winston
バージョン? _3.2.1winston@2
winston@3
node -v
出力:_ v12.8.1Winstonは例外をログに記録していないようで、エラーオブジェクトを適切に解析していないようです。
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
transports: [
new winston.transports.File({
filename: `./logs/error-${momentLogger.unix()}.log`,
level: 'error'
}),
new winston.transports.File({
filename: `./logs/debug-${momentLogger.unix()}.log`,
level: 'debug'
}),
new winston.transports.File({
filename: `./logs/combined-${momentLogger.unix()}.log`
}),
new winston.transports.Console({
format: winston.format.simple()
})
]
});
try {
logger.debug(folderIdRegex.exec(event.link)[1]);
} catch (ex) {
console.log(ex); // Correctly prints
logger.info(ex); // Undefined
logger.debug(ex); // Undefined
logger.error(ex); // Undefined
}
VSCodeデバッガーを使用したさらなるデバッグ
// Output
TypeError: Cannot read property '1' of null
at .....google-sheets-scraping-testing.js:188:51
at processTicksAndRejections (internal/process/task_queues.js:85:5)
info: undefined {"timestamp":"2020-03-04T19:58:36.251Z"}
error: undefined {"timestamp":"2020-03-04T19:58:36.251Z"}
// Here I started using the built-in debug terminal
ex // Input into debug console
> TypeError: Cannot read property '1' of null // Result of ex
logger.log(ex) // Input into debug console
info: undefined {"timestamp":"2020-03-04T20:11:13.924Z"} // Result of logger.log(ex)
> DerivedLogger {_readableState: ReadableState, readable: true, _events: Object, _eventsCount: 3, _maxListeners: undefined, …} // Result of logger.log(ex)
Winstonがtry ... catchブロックからキャッチされたエラーをログに記録することを期待しています。 ex
だけでなくex.message
渡すと、正しく出力されます。 ex
はcatchブロック全体で定義されていますが、Winstonは何らかの理由でそれを解析できないようです。
さらに、catchブロック内からreturn ex
を取得し、すべてを別のcatchブロック内で囲むと、適切に出力されているように見えます。 この異常な動作の詳細については、これがWinstonのバグであることに気付く前に、Discordで作成したサポート投稿の
さらに、このエラーには、別のユーザーが過去1か月間に#1758で発生した問題も含まれていると思います。
これは、フォーマットを適用する際のウィンストンロガーとトランスポート間の動作の一貫性がないことが原因である可能性があります。 winston-transportでは、TransportStream_write関数の一部がこれを行います。
transformed = this.format.transform(Object.assign({}, info), this.format.options);
winston / logger.jsの関連コードは、次のようになります。
this.push(this.format.transform(info, this.format.options));
これが問題の簡略化された再現です。
const winston = require('winston');
// First logger uses a format configured on logger
const logger1 = winston.createLogger({
level: 'info',
transports: new winston.transports.Console(),
format: winston.format.simple()
});
// Second logger uses a format configured on transport
const logger2 = winston.createLogger({
level: 'info',
transports: new winston.transports.Console({
format: winston.format.simple()
})
});
logger1.info(new Error('err message')); // logs expected 'err message'
logger2.info(new Error('err message')); // logs 'undefined'
どの振る舞いを優先すべきかは私にはわかりません。
これは、winstonが一部のオブジェクトを適切にログに記録せず、 [object Object]
として出力し、他のオブジェクトは問題なく印刷される場合にも同じであると思います。
@jleverenz
ありがとう、素晴らしい発見! https://github.com/winstonjs/winston/issues/1758と同じ、私の問題に対する簡単な回避策が得られました
最も参考になるコメント
これは、フォーマットを適用する際のウィンストンロガーとトランスポート間の動作の一貫性がないことが原因である可能性があります。 winston-transportでは、TransportStream_write関数の一部がこれを行います。
transformed = this.format.transform(Object.assign({}, info), this.format.options);
winston / logger.jsの関連コードは、次のようになります。
this.push(this.format.transform(info, this.format.options));
これが問題の簡略化された再現です。
どの振る舞いを優先すべきかは私にはわかりません。