Hi 👋!
With the 3.0 release coming, I am trying to get a sense for what the expectation is for Transport authors to deal with the new release. We are getting feature requests for winston@3 support already on our transport.
Looking at the upgrade guide it seems like there are significant enough API changes that I don't see an easy way to support both winston@2 and winston@3 out of the same transport package. Is the expectation that Transport authors would be releasing a new set of packages for winston@3 (e.g. winston-funky-transport vs. winston3-funky-transport). Alternatively do we need to maintain two semver major branches concurrently on for winston@2 and one for winston@3? Both of those options sound unappetizing to me.
I can imagine some shenanigans where we try to require winston dynamically to see what the user actually has available and then expose a different version depending of the precise version? That is way too hacky, and something we can't to do in our Transport – as we are a TypeScript project and want the users to have predictable usable types.
It is possible I am either overthinking it, or perhaps I am missing something. If the project authors here have thoughts on this, it would be great to have some feedback on what the vision about the Transport migration path is.
Thanks a lot!
/cc @MylesBorins @DominicKramer
That's a great question. There is no silver bullet here, sorry. A TL;DR for a possible approach goes something like:
winston@3 API. winston@3 transport that exposes a winston@2 API, e.g.:// winston@3 symbols
// https://github.com/winstonjs/winston#streams-objectmode-and-info-objects
const { MESSAGE, LEVEL } = require('triple-beam');
// The `winston@3` transport you wrote in (1) above.
const winston3Transport = require('./your-winston3-transport');
module.exports = class YourLegacyTransport {
constructor(opts) {
this.transport = new winston3Transport(opts);
}
log(level, msg, meta, callback) {
this.transport.log(Object.assign({}, meta, {
level,
message,
MESSAGE: message,
LEVEL: level
}, callback);
}
}
require('your-transport/legacy');Of course this would not work seamlessly, but it would easy enough to document this generically or throw in some console warnings if they are using winston@2 with your winston@3 transport, e.g.:
const Transport = require('winston-transport');
module.exports = class YourWinston3Transport extends Transport {
log(info, callback) {
if (arguments.length > 2) throw new Error(```
You appear to be using [email protected]
Please use require('winston-your-transport/legacy');
```);
}
/* your transport code continues below */
}
Regardless of the approach it's not a silver bullet is that in winston@2 every Transport had to implement their own formatting options, nothing was shareable between them. Most transport just called common.log (which is still available in winston-compat for exactly this kind of interop) from winston, so _for the 80%+_ they can just invoke that and pass the resultant object to the winston@3 transport for serialization. If you defined your own formatting options however, you'll have to reimplement those as formats.
_Would love a PR to the upgrade guide to explain this in detail to transport authors!_ 😸
In winston-daily-rotate-file, I used a check using semver to determine which version was in use and then defined the appropriate methods depending on the result.
Base class decision: https://github.com/winstonjs/winston-daily-rotate-file/blob/293d7fe6b79408b0f10b129a1726e375e6f39821/daily-rotate-file.js#L13
Log method declaration: https://github.com/winstonjs/winston-daily-rotate-file/blob/293d7fe6b79408b0f10b129a1726e375e6f39821/daily-rotate-file.js#L114-L136
My thinking on this is that, while it somewhat complicates the transport code, it allows callers to use either winston@2 or winston@3 without any changes.
That's a very interesting technique @mattberther! Thanks for sharing.
Is this going anywhere, particularly in regards to https://github.com/googleapis/nodejs-logging-winston/issues/84
@vongohren, see this PR, explicitly for Winston@3. Could use help on the two failing test cases.