Skip to content

Instantly share code, notes, and snippets.

@vitalipe
Created January 4, 2018 20:31
Show Gist options
  • Select an option

  • Save vitalipe/fdc6ed9c187bb1964d0840037217eb84 to your computer and use it in GitHub Desktop.

Select an option

Save vitalipe/fdc6ed9c187bb1964d0840037217eb84 to your computer and use it in GitHub Desktop.
CoolAutomation logger setup
/**
* Built-in Log Configuration
* (sails.config.log)
*
* Configure the log level for your app, as well as the transport
* (Underneath the covers, Sails uses Winston for logging, which
* allows for some pretty neat custom transports/adapters for log messages)
*
* For more information on the Sails logger, check out:
* http://sailsjs.org/#/documentation/concepts/Logging
*/
// change log level in local.js!!! this file is version contolled!
// if you flood my console I know where you live!
var logging = require("../core/logging");
var Transport = logging.Transports;
module.exports.log = logging.setupAndGenerateSailsConfig({
app : {
level: "debug",
ignorePrefix : true, // don't show [app] in logs
transports: [
Transport.Console,
Transport.File({filename : "logs/app.log"})
]
},
sails : {
level : "debug",
ignorePrefix : true, // don't show [sails] in logs
transports: [
Transport.Console({showLevel : true}),
Transport.File({ filename : "logs/sails.log"})
]
},
"CoolNestService" : {
ignorePrefix : true
},
"CoolBackEndService" : {
level : "silly",
transports: [
Transport.Console({level : "debug"}),
Transport.File({ filename : "logs/CoolBackEndService.log", level : "silly", handleExceptions : false})
]
},
"CoolSchedulerService" : {
transports: [
Transport.Console({showLevel : true, level : "warn"}),
Transport.File({ filename : "logs/CoolSchedulerService.log", handleExceptions : false})
]
},
_exceptionHandler : {
transports: [
Transport.Console({handleExceptions : true}),
Transport.File({filename : "logs/exceptions.log", handleExceptions : true})
]
},
});
/**
* Created by vitali on 21/06/14.
*/
var winston = require('winston');
var _ = require("lodash");
require('winston-mongodb');
require('winston-nodemail');
var Levels = {silent : -Infinity, error: 0, warn: 1, info: 2, verbose: 3, debug: 4, silly: 5};
var MEGABYTE = 1048576;
var Transports = {
Console : function (spec) {
return new (winston.transports.Console)(_.extend({
level : "silly",
timestamp : true,
datePattern : 'YYYY-MM-DD HH:mm:ss.SS',
prettyPrint : true,
colorize : false,
showLevel : false,
handleExceptions : false
}, spec));
},
File : function (spec) {
return new (winston.transports.File)(_.extend({
level : "silly",
timestamp: true,
filename: 'logs/default.log',
json: false,
maxsize: (MEGABYTE * 10),
maxFiles: 30,
tailable: true,
colorize: true,
showLevel: false,
prettyPrint: false,
zippedArchive: true,
handleExceptions: true
}, spec));
},
MongoDB : function (spec) {
return new (winston.transports.MongoDB)(_.extend({
level : "info",
db: 'mongodb://localhost:27017/cooldb-logs',
collection: 'log-error',
storeHost: true,
capped: true,
cappedSize: (MEGABYTE * 50)
}, spec));
},
Mail : function (spec) {
return new (winston.transports.Mail)(_.extend({
level: 'error',
to: '[email protected]',
from: '[email protected]',
username: '[email protected]',
host: 'smtp.coolautomation.com',
port: '465',
ssl: true,
subject: "[CoolRemote Logger] [{{level}}] [{{msg}}]",
html: true,
unique: true,
silent: true
}, spec));
}
};
// config singleton
var config = {
_config : null,
_root : "app",
_sailsRoot : "sails",
generatePrefixString : function(prefix) {
if (_(prefix).isEmpty())
prefix = [config._root];
var path = _(prefix)
.map(config.get)
.where({ignorePrefix : false})
.pluck("name")
.map(function (m) { return "[" + m +"]"})
.value().join("");
return (path.length > 0) ? path + ": " : "";
},
findConfig : function (prefix, key) {
if (_(prefix).isEmpty())
return config.get(config._root)[key];
prefix = _.clone(prefix);
return (config.get(prefix.pop())[key] || config.findConfig(prefix, key));
},
get : function (name) {
if (config._config === null)
throw new Error("Dude why the fuck are you trying to use the logger before it was initialized!?");
return (_.has(config._config, name)) ? config._config[name] : { name : name, ignorePrefix : false};
},
setup : function (settings , root, sailsRoot) {
var cfg = {};
var result = function (val) {return _.isFunction(val)? val() : val};
config._root = (root || config._root);
config._sailsRoot = (sailsRoot || config._sailsRoot);
_.each(settings, function (val, name) {
var setting ={
name : name,
ignorePrefix : (val.ignorePrefix === true),
level : val.level
};
// create new engine ?
if (!_(val.transports).isEmpty())
setting.engine = new (winston.Logger)({
exitOnError: false,
transports : val.transports.map(result)
});
// default engine & level for root
if (name === config._root)
_.defaults(setting, {
engine : new (winston.Logger)({exitOnError: false, transports : [Transports.Console()]}),
level : "info"
});
if (setting.level && _(Levels[setting.level]).isUndefined())
throw new Error("Unknown logging level: " + setting.level);
cfg[name] = setting;
});
if (!_(cfg).has(config._root))
throw new Error("Missing logger root config!");
if (!_(cfg).has(config._sailsRoot))
throw new Error("Missing logger sails config!");
if (!cfg[config._sailsRoot].engine)
throw new Error("Missing transports in sails config!");
if (!cfg[config._sailsRoot].level)
throw new Error("Missing logging level in sails config!");
config._config = cfg;
return config;
},
generateSailsLoggerConfig : function () {
var sailsConfig = config.get(config._sailsRoot);
return {
colors: false,
json: false,
custom: createLogger([config._sailsRoot]),
level: sailsConfig.level
}
}
};
var createLogger = function (prefix) {
prefix = (prefix || []);
var _factory = function(name) { return createLogger((prefix || []).concat(name))};
var _handle = function(target) {
var message = _.toArray(arguments);
var engine = config.findConfig(prefix, "engine");
var level = config.findConfig(prefix, "level");
if (Levels[target] > Levels[level])
return;
message[0] = config.generatePrefixString(prefix);
return engine[target].apply(engine, message);
};
// add public methods
["silly", "verbose", "debug", "info", "warn", "error"]
.forEach(function (name) { _factory[name] = _handle.bind(null, name)});
// log works like we want, except for the shorthand version :(
_factory.log = function (target) {
if (_(Levels).has(target))
return _handle.apply(null, arguments);
var args = _.toArray(arguments);
args.unshift("info");
return _handle.apply(null, args);
};
return _factory;
};
module.exports = {
logger : createLogger(),
Transports : Transports,
setupAndGenerateSailsConfig : function (cfg) { return config.setup(cfg).generateSailsLoggerConfig()}
};
/**
* logger
*
* Example usage:
*
* var config = {
* "parent" : {
* ignorePrefix : true,
* transports : [Transports.Console, Transports.File]
* },
* "child" : { level : "silent"}
* }
*
* // call setup before you can use the logger
* logging.setup(config, {root : "parent"})
*
* topLevel = logging.logger;
* child = topLevel("child");
* grandchild = child("grand"); // if no config is passed, it will use parent's transports
*
* topLevel.info("hey!"); // "hey!" - if ignorePrefix is false -> "[app]: hey!"
* child.info("hey!"); // nothing... because level is silent in config...
* grandchild.info("hey!"); // "[child][grand]: hey!"
*
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment