Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2 from BonnierNews/version20
Browse files Browse the repository at this point in the history
Version20
  • Loading branch information
theneubeck authored Jan 21, 2019
2 parents 432e478 + d79ee0e commit d5f1697
Show file tree
Hide file tree
Showing 21 changed files with 2,285 additions and 410 deletions.
23 changes: 15 additions & 8 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"parserOptions": {
"ecmaVersion": 6
"ecmaVersion": 2018
},
"env": {
"node": true,
Expand All @@ -10,18 +10,18 @@
"rules": {
"arrow-parens": 2,
"arrow-spacing": 2,
"brace-style": [2, "1tbs", { "allowSingleLine": false }],
"brace-style": [2, "1tbs", {"allowSingleLine": false}],
"callback-return": 2,
"camelcase": 1,
"comma-spacing": 1,
"curly": [2, "multi-line"],
"dot-notation": [2, { "allowKeywords": true }],
"dot-notation": [2, {"allowKeywords": true}],
"eol-last": 2,
"eqeqeq": 2,
"handle-callback-err": 2,
"key-spacing": [1, { "beforeColon": false, "afterColon": true }],
"key-spacing": [1, {"beforeColon": false, "afterColon": true}],
"keyword-spacing": 1,
"indent": [1, 2, { "SwitchCase": 1, "MemberExpression": 1 }],
"indent": [1, 2, {"SwitchCase": 1, "MemberExpression": 1}],
"new-cap": 2,
"new-parens": 1,
"no-alert": 2,
Expand Down Expand Up @@ -65,17 +65,24 @@
"no-use-before-define": [2, "nofunc"],
"no-var": 2,
"no-with": 2,
"object-curly-spacing": ["error", "never"],
"prefer-arrow-callback": 2,
"prefer-const": ["error", {"destructuring": "all"}],
"prefer-template": 1,
"quotes": [1, "double"],
"quotes": [1, "double", {"avoidEscape": true}],
"semi": [2, "always"],
"semi-spacing": [1, {"before": false, "after": true}],
"space-before-blocks": 1,
"space-before-function-paren": [1, {"anonymous": "always", "named": "never"}],
"space-infix-ops": 1,
"space-unary-ops": [1, { "words": true, "nonwords": false }],
"space-unary-ops": [1, {"words": true, "nonwords": false}],
"space-in-parens": ["error", "never"],
"strict": [2, "global"],
"yoda": [1, "never"]
"template-curly-spacing": ["error", "never"],
"yoda": [1, "never"],
"require-await": ["error"],
"no-restricted-modules": ["warn", {
"patterns": ["test-data/*"]
}]
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ config/_revision

# Atom CTAGS
.tags
logs
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"bracketSpacing": false,
"printWidth": 120,
"arrowParens": "always"
}
33 changes: 33 additions & 0 deletions config/levels.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"use strict";

const levels = {
emergency: 0,
alert: 1,
critical: 2,
error: 3,
warning: 4,
notice: 5,
info: 6,
debug: 7
};
const aliases = {
emergency: "emerg",
critical: "crit"
};

const colors = {
emergency: "blue",
alert: "darkred",
critical: "cyan",
error: "red",
warning: "yellow",
notice: "magenta",
info: "green",
debug: "gray"
};

module.exports = {
levels,
aliases,
colors
};
9 changes: 9 additions & 0 deletions config/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"logging": {
"log": "file",
"logLevel": "debug",
"logJson": true,
"truncateLog": true,
"metricPrefix": "test"
}
}
104 changes: 102 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,105 @@
"use strict";

const logger = require("./lib/logger");
const appConfig = require("exp-config");
const winston = require("winston");
const {format} = winston;
const path = require("path");
const callingAppName = require(`${process.cwd()}/package.json`).name;
const splatEntry = require("./lib/splat-entry");
const logLevels = require("./config/levels");
const {getLoc, caller} = require("./lib/get-loc");

module.exports = logger;
require("winston-syslog").Syslog; // eslint-disable-line no-unused-expressions

const PromTransport = require("./lib/prom-transport");
const config = appConfig.logging;

function logLevel(info) {
info.logLevel = logLevels.aliases[info.level] || info.level;
return info;
}

function location(info, opts) {
if (opts.caller !== __filename) {
info.location = getLoc(11);
} else {
info.location = getLoc();
}
return info;
}

function truncateTooLong(info) {
if (Buffer.byteLength(info.message, "utf8") > 60 * 1024) {
info.message = "too big to log";
}
return info;
}

function metaDataFormat(info) {
const meta = info.metaData && info.metaData.meta;
if (!meta && Object.keys(info.metaData).length > 0) {
info.metaData = {meta: info.metaData};
}
return info;
}

function metaDataFn(info, opts) {
if (opts.metaData) {
info.metaData = opts.metaData;
}
return info;
}

function buildLogger(metaData) {
const transports = [new PromTransport()];

const defaultFormatter = format.printf((info) => `${info.timestamp} - ${info.level}: ${info.message}`);
const formatter = config.logJson ? format.json() : defaultFormatter;

if (config.log === "file") {
const fileName = path.join(process.cwd(), "logs", `${appConfig.envName}.log`);
const options = config.truncateLog ? {flags: "w"} : {flags: "a"};
transports.push(new winston.transports.File({
filename: fileName,
options: options
}));
}

if (config.log === "stdout") {
transports.push(new winston.transports.Console());
}

if (config.sysLogOpts) {
transports.push(new winston.transports.Syslog(Object.assign({
localhost: process.env.HOSTNAME,
app_name: callingAppName, // eslint-disable-line camelcase
eol: "\n"
}, config.sysLogOpts)));
}


const logger = winston.createLogger({
level: config.logLevel || "info",
levels: logLevels.levels,
colors: logLevel.colors,
transports: transports,
format: format.combine(
format.metadata({key: "metaData"}),
format(metaDataFn)({metaData}),
format.timestamp(),
format(logLevel)(),
format(splatEntry)({metaData}),
format(location)({caller: caller()}),
format(truncateTooLong)(),
format(metaDataFormat)(),
formatter
)
});

return logger;
}

module.exports = {
logger: buildLogger(),
buildLogger
};
50 changes: 50 additions & 0 deletions lib/get-loc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use strict";
const path = require("path");

function getLoc(stackLevel = 10) {
const originalPrepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = (_, stack) => stack;
const stack = new Error().stack[stackLevel];
Error.prepareStackTrace = originalPrepareStackTrace;

let calleePath;
if (process.cwd()) {
calleePath = path.relative(process.cwd(), stack.getFileName());
} else {
calleePath = stack.getFileName();
}

return `${calleePath}:${stack.getLineNumber()}`;
}

/**
* Module wrapper of @substack's `caller.js` (stolen from https://github.com/totherik/caller/blob/master/index.js)
* @original: https://github.com/substack/node-resolve/blob/master/lib/caller.js
* @blessings: https://twitter.com/eriktoth/statuses/413719312273125377
* @see https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
*/
function caller(depth) {
let stack, file, frame;

const pst = Error.prepareStackTrace;
Error.prepareStackTrace = function (_, innerStack) {
Error.prepareStackTrace = pst;
return innerStack;
};

stack = new Error().stack;
depth = !depth || isNaN(depth) ? 1 : depth > stack.length - 2 ? stack.length - 2 : depth;
stack = stack.slice(depth + 1);

do {
frame = stack.shift();
file = frame && frame.getFileName();
} while (stack.length && file === "module.js");

return file;
}

module.exports = {
getLoc,
caller
};
Loading

0 comments on commit d5f1697

Please sign in to comment.