-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
multiple transports loosing SPLAT/meta #1430
Comments
I was about to open a new issue regarding this exact same issue, and then I found this one. I'll post my description as well. :) Please tell us about your environment:
What is the problem?The custom data added by the
To replicate the bug, see the code: https://gist.github.com/avaly/527eee1e061accb7e1f446ca105c3094#file-run-with-bug-js Which outputs:
What do you expect to happen instead?Expected output:
Other informationIf we move the custom https://gist.github.com/avaly/527eee1e061accb7e1f446ca105c3094#file-run-without-bug-js But, most of the time, different transports do require different formatting. |
i did some digging and i think i found the cause. The issue is located in the winston stream module: # index.js#L90
TransportStream.prototype._write = function _write(info, enc, callback) {
...
// We trap(and re-throw) any errors generated by the user-provided format, but also
// guarantee that the streams callback is invoked so that we can continue flowing.
try {
transformed = this.format.transform(Object.assign({}, info), this.format.options);
} catch (err) {
errState = err;
}
...
}; They use Proof:
fixes the splat issue in your test. |
i think i figured out a workaround for now. You can try adding this to your scripts to make the transport use a "deepclone" instead of making shallow clone you can try this as a workaround for now: const deepcopy = require('deepcopy');
const TransportStream = require('winston-transport');
const { LEVEL } = require('triple-beam');
TransportStream.prototype._write = function _write(info, enc, callback) {
if (this.silent || (info.exception === true && !this.handleExceptions)) {
return callback(null);
}
// Remark: This has to be handled in the base transport now because we
// cannot conditionally write to our pipe targets as stream. We always
// prefer any explicit level set on the Transport itself falling back to
// any level set on the parent.
const level = this.level || (this.parent && this.parent.level);
if (!level || this.levels[level] >= this.levels[info[LEVEL]]) {
if (info && !this.format) {
return this.log(info, callback);
}
let errState;
let transformed;
// We trap(and re-throw) any errors generated by the user-provided format, but also
// guarantee that the streams callback is invoked so that we can continue flowing.
try {
transformed = this.format.transform(deepcopy(info), this.format.options);
} catch (err) {
errState = err;
}
if (errState || !transformed) {
// eslint-disable-next-line callback-return
callback();
if (errState) throw errState;
return;
}
return this.log(transformed, callback);
}
return callback(null);
}; |
@Fantus nice workaround, thank you! |
I have a PR in for this. Waiting for review from @DABH and @indexzero. winstonjs/logform#85 |
Using this as a workaround
Use |
I came across this, too, in #1933! The solution posed by @Aenima4six2 is what I'm using and it works like a charm! Thanks!! In light of this, I've taken to creating my own formatter classes which ensure that if any property on info is to be "mutated", that a deepclone is taken first so that all transports get the original |
@avaly thanks for including those gists for reproducing this issue. That has made it significantly easier to reproduce the issue described here. I've included this test in a PR of my to verify a lot of the issues we have metadata currently. I find it most likely that this will be resolved as a part of #2072. |
Please tell us about your environment:
winston
version?winston@2
winston@3
node -v
outputs: v8.11.3What is the problem?
Adding multiple transports to a logger causes the info-object to loose meta field on all but one transport.:
Output Console:
Output File:
Sometimes one transport gets the meta and the other doesn't and for the next logentry its the other way around.
What do you expect to happen instead?
Each transport should get a clean "new" info object. At least with a full SPLAT. So {"meta":"metainfo"} is included in File too.
Other information
I tried for a moment to find the issue in debugger, but got lost in the streams. So please excuse me, if this issue belongs more to winston-transports. I try to investigate this further.
It seems the info[SPLAT] is preserved from one Transport to the other, but due to the splat() formatter th metadata is removed. Maybe its more related to the splat() altering the array than i thought...
As a workaround i will push the metadata back to SPLAT after splat():
To get this working i will use this workaround:
The text was updated successfully, but these errors were encountered: