Node.js - 记录 / 使用 morgan 和 winston
Posted
技术标签:
【中文标题】Node.js - 记录 / 使用 morgan 和 winston【英文标题】:Node.js - logging / Use morgan and winston 【发布时间】:2015-03-10 11:43:38 【问题描述】:我们使用morgan
来记录我们的快速转换:
var morgan = require('morgan');
morgan('combined');
// a format string
morgan(':remote-addr :method :url :uuid');
// a custom function
morgan(function (req, res)
return req.method + ' ' + req.url + ' ' + req.uuid;
)
此外,我们使用winston
来记录我们的其他日志记录:
var winston = require('winston');
var logger = new (winston.Logger)(
transports: [
new (winston.transports.Console)( level: 'info' ),
new (winston.transports.File)( filename: '/var/log/log-file.log' )
]
);
有没有办法将两个记录器结合在一起?现在的情况是morgan
写入我的标准输出,而winston
写入/var/log/log-file.log
。
我希望记录器文件将结合快速转换信息和我想要的其他信息 (logger.info()
)..
【问题讨论】:
这样做有什么意义,我的意思是,你为什么一开始就需要摩根,为什么不写一个winston middlewrare for express? 【参考方案1】:受这个问题的启发,这是我易于定制的记录器。
import * as winston from "winston";
import * as morgan from "morgan";
export const logger = winston.createLogger(
transports: [
new winston.transports.Console(
level: 'debug',
handleExceptions: true,
format: winston.format.combine(
winston.format.timestamp( format: 'HH:mm:ss:ms' ),
winston.format.colorize(),
winston.format.printf(
(info) => `$info.timestamp $info.level: $info.message`,
),
// winston.format.simple(),
),
),
],
exitOnError: false,
);
if (process.env.NODE_ENV === "dev")
logger.add(
new winston.transports.File(
level: 'info',
filename: './logs/all-logs.log',
handleExceptions: true,
format: winston.format.combine(
winston.format.timestamp(
format: 'YYYY-MM-DD HH:mm:ss',
),
winston.format.errors( stack: true ),
winston.format.printf(
(info) => `$info.timestamp $info.level: $info.message`,
),
// winston.format.splat(),
// winston.format.json()
),
maxsize: 5242880, //5MB
maxFiles: 5,
));
logger.info("logging started");
app.use(morgan(function (tokens, req, res)
const msg = [
tokens.method(req, res),
tokens.url(req, res),
tokens.status(req, res),
tokens.res(req, res, 'content-length'), '-',
tokens['response-time'](req, res), 'ms',
].join(' ');
logger.http(msg);
return null;
// return msg;
)
);
样本输出
# console
16:32:30:3230 http: GET /users/614daca689f8773a247af93d 200 417 - 1087.858 ms
# file
2021-09-24 16:40:08 http: GET /users/614daca689f8773a247af93d 200 417 - 856.263 ms
【讨论】:
【参考方案2】:最简单将数据记录到nodejs后端文件中的方法 @grdon/logger
这里是例子
const logger = require('@grdon/logger')(
defaultLogDirectory : __dirname + "/myLogDir",
)
// ...
logger(arg1, 'logfile1.log')
logger([arg1, arg2 ,...], 'lofgfile2.log')
【讨论】:
【参考方案3】:Morgan 的坏习惯是用 \n
结束消息,因此为了使事情井井有条,您可能需要在将其写给 winston 之前将其删除。
这可以通过多种不同的方式完成,例如在 winston 中的格式方面,或者通过更新您的流以不写入 \n
class MyStream
write(text: string)
logger.info(text.replace(/\n$/, ''));
let myStream = new MyStream()
app.use(morgan('tiny', stream: myStream ));
【讨论】:
【参考方案4】:这篇文章非常适合您想做的事情。
http://tostring.it/2014/06/23/advanced-logging-with-nodejs/
对于您的特定代码,您可能需要这样的东西:
var logger = new winston.Logger(
transports: [
new winston.transports.File(
level: 'info',
filename: './logs/all-logs.log',
handleExceptions: true,
json: true,
maxsize: 5242880, //5MB
maxFiles: 5,
colorize: false
),
new winston.transports.Console(
level: 'debug',
handleExceptions: true,
json: false,
colorize: true
)
],
exitOnError: false
);
logger.stream =
write: function(message, encoding)
logger.info(message);
;
app.use(require("morgan")("combined", "stream": logger.stream ));
这将设置 Winston 将日志和文件写入控制台。然后,您可以使用最后一个表达式将 morgan 中间件的输出传递给 winston。
【讨论】:
我们可以在这个过程中使用时间戳吗? 似乎没有必要覆盖 logger.stream.. 就我而言,我能够做到app.use(morgan("combined", stream: write: message => logger.info(message) ));
如果您使用@DevonSams 的方法,您将在记录的行之间得到一个空行,因为morgan 和winston 都在记录的消息末尾添加了换行符。您可以使用logger.info(message.trim())
简单地从消息中删除换行符
如果服务器响应为 500,我想使用 logger.error 而不是 logger.info 怎么办?
对于winston: ^3.0.0
使用winston.createLogger
而不是new winston.Logger
【参考方案5】:
对于 Typescript,另一种无需创建类的方法是
let logger = new (winston.Logger)(
exitOnError: false,
level: 'info',
transports: [
new (winston.transports.Console)(),
new (winston.transports.File)( filename: 'app.log')
]
)
const myStream =
write: (text: string) =>
logger.info(text)
app.use(morgan('combined', stream: myStream ));
此解决方案来自此 Github 页面 https://github.com/winstonjs/winston/issues/1385。但是,重要的是要注意我们的代码之间存在细微差别。而不是:
app.use(morgan('combined', myStream ));
我用:
app.use(morgan('combined', stream: myStream ));
这帮助了我,因为我在创建类方面并不太擅长。
【讨论】:
【参考方案6】:在打字稿中:
let logger = new (winston.Logger)(
exitOnError: false,
level: 'info',
transports: [
new (winston.transports.Console)(),
new (winston.transports.File)( filename: 'app.log')
]
)
class MyStream
write(text: string)
logger.info(text)
let myStream = new MyStream()
app.use(morgan('tiny', stream: myStream ));
【讨论】:
为什么很小而不是合并? 我无法再让它工作了。似乎输入不正确。 ***.com/questions/50048193/…【参考方案7】:更新最后一行以删除警告
app.use(require("morgan")("combined", stream: logger.stream ));
【讨论】:
以上是关于Node.js - 记录 / 使用 morgan 和 winston的主要内容,如果未能解决你的问题,请参考以下文章
Morgan(node.js):使用自定义格式时着色状态代码(如“dev”中)