-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Winston logs to all files. (or: Restrict transport to only 1 level) #614
Comments
This is how I'm logging the requests // Log all requests
app.use(function(req, res, next) {
var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
logger.log('request', req.method, req.url, ip);
next();
}); But see the output in the all 3 files: All I want is that "request" custom level will output only to its own dedicated file. |
@t0lkman I believe that you need to call |
Ideally, what I want to accomplish is, to have different log files for different stuff.. e.g. all http requests goes to one place, all mongo errors to another etc... Currently there is some hierarchy logging system... where depends on the order things being logged.. |
I'm actually having a very similar issue, using the built in levels. My Winston config: logger = new winston.Logger({
emitErrs: true,
transports: [
new winston.transports.Console({
level:'debug',
name: 'console',
handleExceptions: true,
prettyPrint: true,
silent:false,
timestamp: true,
colorize: true,
json: false
}),
new winston.transports.DailyRotateFile({
level:'info',
name: 'info',
filename: accessLogsPath,
handleExceptions: true,
prettyPrint: true,
silent:false,
timestamp: true,
json: true,
colorize: true,
maxsize: 20000,
tailable: true
}),
new winston.transports.DailyRotateFile({
level:'error',
name: 'error',
filename: errorLogsPath,
handleExceptions: true,
prettyPrint: true,
silent: false,
timestamp: true,
json: true,
colorize: false,
maxsize: 20000,
tailable: true
})
],
exitOnError: false
}); Then when I run |
@NukaPunk Isn't this the expected behaviour of a logger? Usually a logger instance will log to all transports that match the minimum level of the message. Ex: debug -> info -> warning -> error. A transport that handles info will not log debug messages but will log info, warning and error. This is usually solved by creating multiple logger instances, each handling a specific case. |
Thanks for the reply @masom. I guess it's counter intuitive to have your errors logged in your info log to me, but now that I better understand the way the levels work I'll take your advice and create different instances. Thanks again. |
@NukaPunk yeah it is really counter-intuitive at first. Same happened with other language loggers and some of them let you specify an exclusive log level for a specific transport. |
@masom so not a bug, but a feature ;-) The readme file doesn't really explain the concept of lower level logging, so I assumed levels were exclusive. I'd recommend adding some information about that to the readme to avoid confusion, if possible. Thank again, great work on the logging transport! |
Is there any example, how I do multiple logger instances? All I need is to have totally separated log files. |
@t0lkman My guess would be something like this: module.exports = {
errorLog: new winston.Logger({
levels: levels,
colors: colors,
exceptionHandlers: [
new winston.transports.File({filename: 'logs/exceptions.log'})
],
transports: [
new winston.transports.File({
name: 'error-file',
level: 'error',
filename: 'logs/error-logs.log',
json: true,
maxsize: 5242880, //5MB
maxFiles: 5,
colorize: false
})
],
exitOnError: false
}),
requestLog: new winston.Logger({
levels: levels,
colors: colors,
exceptionHandlers: [
new winston.transports.File({filename: 'logs/exceptions.log'})
],
transports: [
new winston.transports.File({
name: 'request-file',
level: 'request',
filename: 'logs/requests.log',
json: true,
maxsize: 5242880, //5MB
maxFiles: 5,
colorize: false
})
],
exitOnError: false
}
),
infoLog: new winston.Logger({
levels: levels,
colors: colors,
exceptionHandlers: [
new winston.transports.File({filename: 'logs/exceptions.log'})
],
transports: [
new winston.transports.File({
name: 'info-file',
level: 'info',
filename: 'logs/all-logs.log',
json: true,
maxsize: 5242880, //5MB
maxFiles: 5,
colorize: false
})
],
exitOnError: false
})
}; And then you could use it like this: var logger = require(/path/to/file);
logger.errorLog('This is an error!');
logger.infoLog('This is info!');
logger.request('request', req.method, req.url, ip); Alternatively you can use Morgan for request logging pretty easily: infoLogger.stream = {
write: function(message, encoding){
logger.info(message);
}
};
app.use(require("morgan")("combined", { "stream": infoLogger.stream })); I hope that helps! |
Tried, didn't work :(
|
@t0lkman You're right. I tried it out and it doesn't work (that's what I get for writing it in my browser). Try this instead: var errorLog = require('./models/winston').errorLog;
errorLog.error('test'); |
any updates on this one? |
@davidfeldi Maybe this may help, I've encountered this issue before and manage to create my own wrapper. This separates error logs for each levels. https://github.com/odegraciajr/winston-logger |
This issue has now been around for two years. I myself thought it was kinda a pity that I can't make an error-only log file along with an info-log with one instance. |
Hey guys, here is my solution for the problem (also in gist: winston-logger.js) const winston = require('winston');
const path = require('path');
const getLogger = (module, type) => {
const modulePath = module.filename.split('/').slice(-2).join('/');
const logger = new winston.Logger({
transports: [
new (winston.transports.Console)({
colorize: true,
level: (process.env.NODE_ENV === 'development') ? 'debug' : 'error',
label: modulePath
})
]
});
switch (type) {
case 'error':
logger.add(winston.transports.File, {
name: 'error-file',
filename: path.join(__dirname, '../../logs/error_default.log'),
level: 'error'
});
return logger;
case 'info':
logger.add(winston.transports.File, {
name: 'info-file',
filename: path.join(__dirname, '../../logs/info_default.log'),
level: 'info'
});
return logger;
default:
return logger;
}
};
module.exports = module => ({
error(err) {
getLogger(module, 'error').error(err);
},
info(err) {
getLogger(module, 'info').info(err);
},
debug(err) {
getLogger(module, 'default').debug(err);
}
}); Usage: const logger = require('path/to/logger')(module);
logger.info('Logging with winston'); |
It works! only if the minimum log level should be the same in all defined transports, Personally, I think that each transport should log according it its defined level |
Any update on this, the latest rc3 doesn't work |
You could achieve this with a custom format that checks for the desired level:
|
+1 |
@madal3x That will still log empty lines to the file whenever the level doesn't match. I've tried returning null or even returning nothing at all and it still logs null/undefined. Unless something has changed in the 3.x release of which I'm not aware. It's a pity there doesn't seem to be a way to abort a particular line from being logged or your custom format example might be a viable workaround. Seems like it would be a simply fix to not log the undefined value at all, so returning undefined from the format/formatter function would not log an empty line. Note that this should not affect the ability to log undefined variables as long as the total message being logged is more than just a single A more robust solution might be to add some type of intercept function to a transport that would allow returning true to log a message or false to ignore it. |
I'm using the 3.x winston, after trials and errors I find out that we can filter log by level to log them to separate files. Here is the code I used:
|
@ngthienlinh You're right, that does work, and this is even detailed in the I think this issue can be closed now given that it has been clearly indicated that there is no more work being done on the winston 2.x codebase. |
Hello everyone, this worked for me.
|
Thanks! |
This is my winston config:
I'm trying to log, errors, http-requests, and exceptions to their own files.
However, I see, for example, in error-logs.log (http)requests logs.
Can anybody explain to me what I'm doing wrong?
The text was updated successfully, but these errors were encountered: