-
Notifications
You must be signed in to change notification settings - Fork 886
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
setBindings() does not overwrite existing bindings #1418
Comments
This was a design choice for performance reasons . I don't see us changing this, would you like to send a PR to the did to clarify? |
@mcollina Sure I can. Question though about the performance. I'm not trying to challenge that there are performance issues, but jw what constitutes as not performant enough at least for pino. TLDR: the fix I had in mind uses
So given that, even though I believe the fix is just using const chindings = asChindings(this, newBindings)
//this[chindingsSym] = chindings // old code
const dedupedChindings = JSON.stringify(JSON.parse(`{${chindings.substring(1)}}`));
this[chindingsSym] = ',' + dedupedChindings.substring(1, dedupedChindings.length-1) Testing those lines, it takes about 3ms if the string has >1000 fields. 5ms if >10,000. 30 ms if >100,000. And that's including some string concatenation that wouldn't normally be done in const start = performance.now();
let chindings = ',"foo":"bar","name":"basicTest","0":"bar0"';
for (let i = 0; i < 10000; i++) {
chindings += `,"${i}":"test"`
}
const dedupedChindings = JSON.stringify(JSON.parse(`{${chindings.substring(1)}}`));
const chindingsSym = ',' + dedupedChindings.substring(1, dedupedChindings.length-1)
const end = performance.now(); Testing the reproduction steps I wrote in the issue description, the new code was taking about 8ms longer when running 10 iterations of logging 1000 times, with each log getting progressively bigger. But when we start putting in duplicate fields of course, the newer code is much faster because the actual string it streams is a lot smaller of course: const logger = pino({ name: 'basicTest', level: 'info', base: { foo: 'bar' } })
// old code 1393.1250248998404ms
// new code 1401.6106416999362ms
let total = 0;
for (let j = 0; j < 10; j++) {
const childLogger = logger.child({})
const start = performance.now();
for (let i = 0; i < 10000; i++) {
childLogger.info('Hello World')
childLogger.setBindings({ [i]: `bar${i}` })
childLogger.info('Hello World')
}
const end = performance.now();
total += (end - start)
}
console.log(`Took average of ${total / 10} milliseconds`) |
Resolved by #1419. |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Hello!
While using
setBindings()
and referring to the docs comment in the types, I expected it to at least overwrite existing fields. However, it ends up duplicating the field in the log.Is this the intended behavior? Based on this unit test, I didn't think it was the desired behavior. But since
bindings()
usesJSON.parse()
, the unit test doesn't catch thatpino.chindings
includes duplicate keys.Steps to reproduce
Running this outputs:
Notice the duplicate
foo
field.The text was updated successfully, but these errors were encountered: