-
Notifications
You must be signed in to change notification settings - Fork 517
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Default logger, or a way to share logger configuration between modules #116
Comments
Create a module named "logger.js" and require it from anywhere you want. |
Thanks! Just to clarify, If creating a I thought Bunyan could have an option to define defaults for all loggers in memory. This might be even more relevant for open-source modules. If we depend on |
A clean solution would be a function to change the default stream. var bunyan = require('bunyan'); |
A way to bypass it is to define new modules on the main file and use it instead.
on the module file use getLogger instead createLogger.
|
I guess this is similar to the idea in log4j (likewise clones like log4js, Python's logging module, etc.) where logger objects are global to the process such that, e.g., There was some bunyan wrapper module on npm that I saw a long while back that allowed for globally shared loggers. I can't recall the name right now. Found it: https://www.npmjs.org/package/bole Personally, I my usage, I get all modules to take a // app.js
var log = bunyan.createLogger(...);
var SomeModuleThing = require('some-module');
var thing = new SomeModuleThing({log: log, ...});
// use thing and each module might use // some-module.js
module.exports = function SomeModuleThing(opts) {
this.log = opts.log.child({someModule: true});
}; IOW, I write modules to say: "Oh, you want me to log somewhere, then pass me the logger on which to do it." I'll grant that this does mean an impact on APIs in that you have to pass this 'log' param around. I've not thought about including a sense of globally shared loggers (by name) in Bunyan core. |
I think that just an option to overwrite the default stream is enough.
|
Each require('Bunyan') will be independent so that doesn't help unless we are proposing this reach into process global state. If that then I'd want to think about an API for each module to use that makes it clear it is process global.
|
Use this in all modules as |
@n4nagappan the good ol' singleton pattern |
The only thing that worked for me, for some reason, is to write the loggers into an object under the global variable;
i use typescript, so i use 'import', not require, and it gave me lots of pain to make it work...reason is unknown, really. |
I solved this problem by writing a custom const addChildLogger = function(parent, child){
child.addStream({
type: 'raw',
stream: { write: function(rec){ parent._emit(rec); } },
level: 'trace',
});
};
addChildLogger(parentLogger, moduleLogger); Here is a version that supports log level, but it's untested so make sure there are no typos or whatnot. const addChildLogger = function(parent, child, level){
child.addStream({
type: 'raw',
stream: {
write: function(rec){
if (this._level <= rec.level) {
parent._emit(rec);
}
}
},
level: level || 'trace',
});
};
addChildLogger(parentLogger, moduleLogger, "trace"); |
@rprieto, I hope I am understanding the question correctly but here's my logger configuration. This setup allows me to import the global settings anywhere AND create child loggers off of it to identify different parts of the application. Note: I am using typescript so ignore if you wish. config.yml logger:
basePath: ./log/
level: info
name: main-api
serviceLog: service.log logUtils.ts import * as path from 'path';
import * as bunyan from 'bunyan';
import { Stream } from 'bunyan';
import conf from '../config';
let mainLoggerStreams: Stream[] = [{
stream: process.stdout
}];
if (conf.env === 'production') {
mainLoggerStreams = [{
path: path.resolve(conf.logger.basePath, 'service.log')
}];
}
// main logger
const logger = bunyan.createLogger({
name: conf.logger.name,
level: conf.logger.level,
serializers: bunyan.stdSerializers,
streams: mainLoggerStreams
});
export default logger; Then in a controller somewhere... import logger from '../utils/logUtils';
const log = logger.child({ feature: 'events' });
// somewhere in the controller
log.info('something happened');
log.error('oh noes!'); All of the logs in the controller will have an extra Hope this helps! |
Context: we split our app into a main process, and several smaller "npm" modules, some of which use
bunyan
.For now, these modules output to the default
stdout
stream, in which case all the logs get aggregated properly. But the main app might configurebunyan
to output to a file instead. How would we share the "main" logger configuration, so that all modules using Bunyan start outputting to the same place?For example:
main-app.js
module-b
A basic way would be to export an
initLogger
function inmodule-b
, and pass down the configuration from our app, but I was hoping for a cleaner way - maybe some global logger config that can be stored and shared?The text was updated successfully, but these errors were encountered: