在TypeScript中创建winston记录器的正确方法是什么,它将记录快速Morgan中间件记录?我找到了许多JavaScript示例,但在将它们转换为TypeScript时遇到了问题,因为我收到错误Type '{ write: (message: string, encoding: any) => {}; logger: any; }' is not assignable to type '(options?: any) => ReadableStream'. Object literal may only specify known properties, and 'write' does not exist in type '(options?: any) => ReadableStream'.
这是我的代码:
import { Logger, transports } from 'winston';
// http://tostring.it/2014/06/23/advanced-logging-with-nodejs/
// https://www.loggly.com/ultimate-guide/node-logging-basics/
const logger = new Logger({
transports: [
new (transports.Console)({
level: process.env.NODE_ENV === 'production' ? 'error' : 'debug',
handleExceptions: true,
json: false,
colorize: true
}),
new (transports.File)({
filename: 'debug.log', level: 'info',
handleExceptions: true,
json: true,
colorize: false
})
],
exitOnError: false,
});
if (process.env.NODE_ENV !== 'production') {
logger.debug('Logging initialized at debug level');
}
// [ts]
// Type '{ write: (message: string, encoding: any) => {}; logger: any; }' is not assignable to type '(options?: any) => ReadableStream'.
// Object literal may only specify known properties, and 'write' does not exist in type '(options?: any) => ReadableStream'.
logger.stream = {
write: function (message: string, encoding: any) {
logger.info(message);
};
}
export default logger;
我已经能够通过调整我的代码来使用const winston = require('winston');
来解决这个问题,但是想知道你应该如何做这个维护类型?
答案 0 :(得分:4)
stream
应该是返回流的工厂函数,而不是流本身。
预计流是真正可读的流,而不是模仿它的对象。
因为它应该是可写的,所以它应该是双工的:
logger.stream = (options?: any) => new stream.Duplex({
write: function (message: string, encoding: any) {
logger.info(message);
}
});
这是Winston TS类型建议的解决方案。我无法确认它是否正常工作。
答案 1 :(得分:3)
感谢@estus让我过去了我被挂断的地方。这是我最终使用的解决方案:
import { Logger, transports } from 'winston';
import stream from 'stream';
import split from 'split';
// http://tostring.it/2014/06/23/advanced-logging-with-nodejs/
// https://www.loggly.com/ultimate-guide/node-logging-basics/
const logger = new Logger({
transports: [
new (transports.Console)({
level: process.env.NODE_ENV === 'production' ? 'error' : 'debug',
handleExceptions: true,
json: false,
colorize: true
}),
new (transports.File)({
filename: 'debug.log', level: 'info',
handleExceptions: true,
json: true,
colorize: false
})
],
exitOnError: false,
});
if (process.env.NODE_ENV !== 'production') {
logger.debug('Logging initialized at debug level');
}
logger.stream = split().on('data', function (message: string) {
logger.info(message);
});
export default logger;
最终这个问题让我找到了最终解决方案 - https://github.com/expressjs/morgan/issues/70
答案 2 :(得分:1)
最终,我最终以此作为解决方案。我用一个叫做write的方法创建了一个类
export class LoggerStream {
write(message: string) {
logger.info(message.substring(0, message.lastIndexOf('\n')));
}
}
然后在添加表达时,我创建了该类的实例:
app.use(morgan('combined', { stream: new LoggerStream() }));
这很适合我的情况
答案 3 :(得分:1)
如果您使用 TypeScript 类作为记录器,您可以声明一个 stream() 函数,该函数从摩根返回一个 StreamOptions 类型:
import { StreamOptions } from 'morgan';
//...rest of the class code
public stream(): StreamOptions {
return {
write: (message: string): void => {
this.info(message.trim());
}
};
然后你可以在 express 中间件中使用这个流函数:
app.use('combined', { stream: this.logger.stream()})