nodejs-logging-winston: Error: `write after end` when handling SIGINT
Environment details
- OS: MacOS
- Node.js version: 10 LTS
- npm version:
@google-cloud/logging-winston
version: 3.0.6winston
3.2.1
Steps to reproduce
Winston 3 now has a mechanism to wait for logs to flush described here: https://github.com/winstonjs/winston/blob/master/UPGRADE-3.0.md#winstonlogger
winston.Logger.log and level-specific methods (.info, .error, etc) no longer accepts a callback. The vast majority of use cases for this feature was folks awaiting all logging to complete, not just a single logging message.
Since upgrading, I am unable to get the logs to flush before the process exits (via signal or normal termination).
const winston = require("winston")
const { LoggingWinston } = require("@google-cloud/logging-winston")
const logger = winston.createLogger({
exitOnError: false,
level: "info",
transports: [
new winston.transports.Console({
handleExceptions: false
}),
new LoggingWinston({
keyfileName:
"/Users/jamesholcomb/keys/2e645b0b8d27.json",
projectId: "my-proj"
})
]
})
logger.emitErrs = false
logger.info("started")
process.on("SIGINT", () => {
logger.info("Ctrl-C pressed")
logger.on("finish", () => process.exit(0))
logger.end()
})
process.openStdin()
Output error:
{"message":"started","level":"info"}
^C{"message":"Ctrl-C pressed","level":"info"}
events.js:174
throw er; // Unhandled 'error' event
^
Error: write after end
at writeAfterEnd (/Users/jamesholcomb/gcp-test/node_modules/winston/node_modules/readable-stream/lib/_stream_writable.js:261:12)
at DerivedLogger.Writable.write (/Users/jamesholcomb/gcp-test/node_modules/winston/node_modules/readable-stream/lib/_stream_writable.js:305:21)
at DerivedLogger.info (/Users/jamesholcomb/gcp-test/node_modules/winston/lib/winston/create-logger.js:81:14)
at process.on (/Users/jamesholcomb/gcp-test/index.js:42:10)
at process.emit (events.js:198:13)
Emitted 'error' event at:
at errorOrDestroy (/Users/jamesholcomb/gcp-test/node_modules/winston/node_modules/readable-stream/lib/internal/streams/destroy.js:98:101)
at writeAfterEnd (/Users/jamesholcomb/gcp-test/node_modules/winston/node_modules/readable-stream/lib/_stream_writable.js:263:3)
at DerivedLogger.Writable.write (/Users/jamesholcomb/gcp-test/node_modules/winston/node_modules/readable-stream/lib/_stream_writable.js:305:21)
[... lines matching original stack trace ...]
at process.emit (events.js:198:13)
If I comment out the LoggingWinston transport setup, there is no error.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 1
- Comments: 16 (7 by maintainers)
How is this not a bug? The suggested way of flushing logs doesn’t work in this basic reproducible environment
This also happens to us occasionally, and we couldn’t use
setTimeout
on thelogger.end
, since we have no idea how long we’ll have to wait here.Is there any possible solution for this? In v2 I could have flushed the logs without ending by using the callback arg in
logger.info
, but we’re using v3 so that’s not possible anymoreThanks @RLRabinowitz for your response - I agree that the migration was not properly addressed. I am not sure what exactly happened (this migration predates me), but I guess that
winston
change was introduced independently since it is not part ofgoogleapis
project. I believe thewinston
3.0 migration was inevitable in order to be up to date with latestwinston
changes and the issue withwrite after end
was discovered later due toasync
nature of Log. I must admit that such migration inwinston
library supposed to be backward compatible for the sake of clients relying on such functionality - filed the 2095 onwinston
to revive callback functionality. As of now, I do not see how we can solve this issue except of using printing structured logging to STDOUT feature since current default solution isasync
/callback oriented. I am happy that you have a workaround as of now - thanks for sharing it since it could be leveraged by more users! I believe that for now we should add some explanation inREADME
regarding this limitation.@losalex it seems like winston implements its logger as a
Transform
stream and pipes to its transports, delaying the finish event (according to the docs on_final
) until the transports are all finished.It looks like the
nodejs-logging-winston
transport is aTransform
stream as well (viawinston-transform
), so it seems like if your transport can keep track of its own state, then perhaps all it needs to do is implement its own_final
that defers things until it has finished sending the logs and then winston will behave correctly?I understand that updating the README can help explain the context of the bug, but this needs to remain open so that a proper fix can be implemented. @bcoe suggested a path forward by tracking pending requests.
Hey @losalex, gotta say that I’m not sure what other option would be available, other than bringing back callback functionality.
We’ve already solved our issue internally with this workaround mentioned above, which is specific to the transports we use
My main issue with this personally right now is that the “breaking changes” part of the changelog is misleading. The suggested way of migrating to 3.0 is wrong, it should either mention
setTimeout
there, or say that the functionality is no longer available