democratic-csi/src/utils/logger.js

120 lines
2.8 KiB
JavaScript

const os = require("os");
/**
* Levels
*
* error: 0
* warn: 1
* info: 2
* verbose: 3
* debug: 4
* silly: 5
*/
const winston = require("winston");
const bunyan = require("bunyan");
const env = process.env.NODE_ENV || "development";
let level = process.env.DEMOCRATIC_CSI_LOG_LEVEL || null;
if (!level) {
if (env == "production") {
level = "info";
} else {
level = "verbose";
}
}
let formatters;
let defaultMeta;
if (env == "production") {
formatters = [winston.format.json()];
defaultMeta = { service: "democratic-csi", host: os.hostname() };
} else {
formatters = [winston.format.colorize(), winston.format.simple()];
defaultMeta = {};
}
const logger = winston.createLogger({
level: level,
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.splat(),
...formatters
),
defaultMeta: defaultMeta,
transports: [
new winston.transports.Console({
handleExceptions: true,
}),
],
});
/**
* A Bunyan raw stream object (i.e. has a `.write(rec)` method that takes a
* Bunyan log record) that shims logging to a given Winston logger.
*
* @param {winston.Logger} wlog is a Winston Logger to which to shim.
*/
function Bunyan2Winston(wlog) {
this.wlog = wlog;
}
Bunyan2Winston.prototype.write = function write(rec) {
// Map to the appropriate Winston log level (by default 'info', 'warn'
// or 'error') and call signature: `wlog.log(level, msg, metadata)`.
var wlevel;
if (rec.level <= bunyan.INFO) {
wlevel = "info";
} else if (rec.level <= bunyan.WARN) {
wlevel = "warn";
} else {
wlevel = "error";
}
// Note: We are *modifying* the log record here. This could be a problem
// if our Bunyan logger had other streams. This one doesn't.
var msg = rec.msg;
delete rec.msg;
// Remove internal bunyan fields that won't mean anything outside of
// a bunyan context.
delete rec.v;
delete rec.level;
// TODO: more?
// Note: Winston doesn't handle *objects* in the 'metadata' field well
// (e.g. the Bunyan record 'time' field is a Date instance, 'req' and
// 'res' are typically objects). With 'json: true' on a Winston transport
// it is a bit better, but still messes up 'date'. What exactly to do
// here is perhaps user-preference.
rec.time = String(rec.time);
//Object.keys(rec).forEach(function (key) {
// if (typeof(rec[key]) === "object") {
// rec[key] = JSON.stringify(rec[key])
// }
//});
this.wlog.log(wlevel, msg, rec);
};
// Pass a Bunyan logger to restify that shims to our winston Logger.
var shim = bunyan.createLogger({
name: "eas",
streams: [
{
type: "raw",
level: "trace",
stream: new Bunyan2Winston(logger),
},
],
});
logger.bunyan = shim;
//global.console = logger;
module.exports = {
logger: logger,
};