エクスプレスモーガンミドルウェアロギングをログに記録するWinstonロガーをTypeScriptで作成する正しい方法は何ですか?いくつかのJavaScriptサンプルを見つけましたが、エラー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'.
が発生したため、TypeScriptへの変換に問題がありました。
これが私のコードです:
_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');
を使用するようにコードを調整することでこれを回避できましたが、このタイプを維持する方法を知りたいですか?
最終的に私はこれを解決策として思いついた。 writeという1つのメソッドでクラスを作成しました
export class LoggerStream {
write(message: string) {
logger.info(message.substring(0, message.lastIndexOf('\n')));
}
}
次に、expressに追加するときに、クラスのインスタンスを作成しました。
app.use(morgan('combined', { stream: new LoggerStream() }));
これは私の状況にうまく機能します
stream
は、ストリーム自体ではなく、ストリームを返すファクトリ関数であることが期待されています。
ストリームは、それを模倣するオブジェクトではなく、実際に読み取り可能なストリームであることが期待されます。
書き込みも可能であると想定されているため、デュプレックスである必要があります。
logger.stream = (options?: any) => new stream.Duplex({
write: function (message: string, encoding: any) {
logger.info(message);
}
});
これは、WinstonTSタイプによって提案されたソリューションです。正常に動作するか確認できません。
私が電話を切った場所を通り過ぎてくれた@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/7