nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: pinojs/pino
Pull request #1499 (2022-07-19 22:20:19)

Use process.stdout if specified by the developer
Ref: #1497 

Signed-off-by: Matteo Collina <hello@matteocollina.com>

mcollina: @jsumners PTAL

Patch:
diff --git a/lib/tools.js b/lib/tools.js
index 7e37faf..530c5a5 100644
--- a/lib/tools.js
+++ b/lib/tools.js
@@ -303,9 +303,12 @@ function createArgsNormalizer (defaultOptions) {
     }
     const { enabled } = opts
     if (enabled === false) opts.level = 'silent'
-    stream = stream || process.stdout
-    if (stream === process.stdout && stream.fd >= 0 && !hasBeenTampered(stream)) {
-      stream = buildSafeSonicBoom({ fd: stream.fd })
+    if (!stream) {
+      if (!hasBeenTampered(process.stdout)) {
+        stream = buildSafeSonicBoom({ fd: process.stdout.fd })
+      } else {
+        stream = process.stdout
+      }
     }
     return { opts, stream }
   }


Test patch:
diff --git a/test/stdout-protection.test.js b/test/stdout-protection.test.js
index 57a8516..c37e008 100644
--- a/test/stdout-protection.test.js
+++ b/test/stdout-protection.test.js
@@ -5,6 +5,7 @@ const { join } = require('path')
 const { fork } = require('child_process')
 const { once } = require('./helper')
 const writer = require('flush-write-stream')
+const pino = require('..')
 
 test('do not use SonicBoom is someone tampered with process.stdout.write', async ({ not }) => {
   let actual = ''
@@ -17,3 +18,8 @@ test('do not use SonicBoom is someone tampered with process.stdout.write', async
   await once(child, 'close')
   not(actual.match(/^hack/), null)
 })
+
+test('do not use SonicBoom is someone has passed process.stdout to pino', async ({ equal }) => {
+  const logger = pino(process.stdout)
+  equal(logger[pino.symbols.streamSym], process.stdout)
+})
Repository: pinojs/pino
Pull request #1587 (2022-11-09 20:56:42)

Use safe stringify for redaction
My attempt to fixing this issue https://github.com/pinojs/pino/issues/1586#issue-1442733693


Patch:
diff --git a/pino.js b/pino.js
index 934eb74..c16a745 100644
--- a/pino.js
+++ b/pino.js
@@ -117,10 +117,10 @@ function pino (...args) {
     formatters.log
   )
 
-  const stringifiers = redact ? redaction(redact, stringify) : {}
   const stringifyFn = stringify.bind({
     [stringifySafeSym]: stringifySafe
   })
+  const stringifiers = redact ? redaction(redact, stringifyFn) : {}
   const formatOpts = redact
     ? { stringify: stringifiers[redactFmtSym] }
     : { stringify: stringifyFn }


Test patch:
diff --git a/test/redact.test.js b/test/redact.test.js
index d5c0166..8e9eff3 100644
--- a/test/redact.test.js
+++ b/test/redact.test.js
@@ -826,3 +826,22 @@ test('child can remove parent redact by array', async ({ equal }) => {
   equal(req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
   equal(req.method, 'GET')
 })
+
+test('redact safe stringify', async ({ equal }) => {
+  const stream = sink()
+  const instance = pino({ redact: { paths: ['that.secret'] } }, stream)
+
+  instance.info({
+    that: {
+      secret: 'please hide me',
+      myBigInt: 123n
+    },
+    other: {
+      mySecondBigInt: 222n
+    }
+  })
+  const { that, other } = await once(stream, 'data')
+  equal(that.secret, '[Redacted]')
+  equal(that.myBigInt, 123)
+  equal(other.mySecondBigInt, 222)
+})
Repository: pinojs/pino
Pull request #1604 (2022-12-14 07:10:06)

Fix updating errorKey with default error serializer (#1593)
#1593

Hello! Thanks guys for great logger library.
I noticed some bug and try to fix.
Have a nice day


Patch:
diff --git a/lib/tools.js b/lib/tools.js
index b44a961..e16c0c7 100644
--- a/lib/tools.js
+++ b/lib/tools.js
@@ -20,6 +20,7 @@ const {
   nestedKeySym,
   formattersSym,
   messageKeySym,
+  errorKeySym,
   nestedKeyStrSym
 } = require('./symbols')
 const { isMainThread } = require('worker_threads')
@@ -97,6 +98,7 @@ function asJson (obj, msg, num, time) {
   const serializers = this[serializersSym]
   const formatters = this[formattersSym]
   const messageKey = this[messageKeySym]
+  const errorKey = this[errorKeySym]
   let data = this[lsCacheSym][num] + time
 
   // we need the child bindings added to the output first so instance logged
@@ -112,7 +114,11 @@ function asJson (obj, msg, num, time) {
   for (const key in obj) {
     value = obj[key]
     if (Object.prototype.hasOwnProperty.call(obj, key) && value !== undefined) {
-      value = serializers[key] ? serializers[key](value) : value
+      if (serializers[key]) {
+        value = serializers[key](value)
+      } else if (key === errorKey && serializers.err) {
+        value = serializers.err(value)
+      }
 
       const stringifier = stringifiers[key] || wildcardStringifier
 


Test patch:
diff --git a/test/errorKey.test.js b/test/errorKey.test.js
index 5b3d411..9b8e80b 100644
--- a/test/errorKey.test.js
+++ b/test/errorKey.test.js
@@ -18,3 +18,17 @@ test('set the errorKey with error serializer', async ({ equal, same }) => {
   equal(o[errorKey].message, 'test')
   equal(typeof o[errorKey].stack, 'string')
 })
+
+test('set the errorKey without error serializer', async ({ equal, same }) => {
+  const stream = sink()
+  const errorKey = 'error'
+  const instance = pino({
+    errorKey
+  }, stream)
+  instance.error(new ReferenceError('test'))
+  const o = await once(stream, 'data')
+  equal(typeof o[errorKey], 'object')
+  equal(o[errorKey].type, 'ReferenceError')
+  equal(o[errorKey].message, 'test')
+  equal(typeof o[errorKey].stack, 'string')
+})
Repository: pinojs/pino
Pull request #1746 (2023-07-21 15:02:21)

fix: use `messageKey` when giving message precedence over error
Follow-up to https://github.com/pinojs/pino/pull/1654. Ref: https://github.com/pinojs/pino/pull/1654/files#r1270564181.

jsumners: Looks good, but we will need to rebase once https://github.com/pinojs/pino/pull/1747 is merged.
jsumners: Please rebase. That should make CI happy.

Patch:
diff --git a/lib/proto.js b/lib/proto.js
index e9bd4ed..43a3b7b 100644
--- a/lib/proto.js
+++ b/lib/proto.js
@@ -20,6 +20,7 @@ const {
   serializersSym,
   formattersSym,
   errorKeySym,
+  messageKeySym,
   useOnlyCustomLevelsSym,
   needsMetadataGsym,
   redactFmtSym,
@@ -181,6 +182,7 @@ function write (_obj, msg, num) {
   const t = this[timeSym]()
   const mixin = this[mixinSym]
   const errorKey = this[errorKeySym]
+  const messageKey = this[messageKeySym]
   const mixinMergeStrategy = this[mixinMergeStrategySym] || defaultMixinMergeStrategy
   let obj
 
@@ -193,7 +195,7 @@ function write (_obj, msg, num) {
     }
   } else {
     obj = _obj
-    if (msg === undefined && _obj.msg === undefined && _obj[errorKey]) {
+    if (msg === undefined && _obj[messageKey] === undefined && _obj[errorKey]) {
       msg = _obj[errorKey].message
     }
   }


Test patch:
diff --git a/test/error.test.js b/test/error.test.js
index 1869c39..01be0f4 100644
--- a/test/error.test.js
+++ b/test/error.test.js
@@ -376,3 +376,23 @@ test('msg should take precedence over error message on mergingObject', async ({
     msg: 'my message'
   })
 })
+
+test('considers messageKey when giving msg precedence over error', async ({ same }) => {
+  const err = new Error('myerror')
+  const stream = sink()
+  const instance = pino({ messageKey: 'message' }, stream)
+  instance.error({ message: 'my message', err })
+  const result = await once(stream, 'data')
+  delete result.time
+  same(result, {
+    pid,
+    hostname,
+    level: 50,
+    err: {
+      type: 'Error',
+      stack: err.stack,
+      message: err.message
+    },
+    message: 'my message'
+  })
+})
Repository: pinojs/pino
Pull request #1779 (2023-08-08 18:36:42)

adding asString to the key
This fixes issue-1767. It can maybe be added as a feature? not sure, but happy to discuss further


Patch:
diff --git a/browser.js b/browser.js
index f9f8df0..8322842 100644
--- a/browser.js
+++ b/browser.js
@@ -44,7 +44,7 @@ function appendChildLogger (parentLogger, childLogger) {
 function setupBaseLogFunctions (logger, levels, proto) {
   const logFunctions = {}
   levels.forEach(level => {
-    logFunctions[level] = proto[level] ? proto[level] : (_console[level] || _console[logFallbackMap[level] ?? 'log'] || noop)
+    logFunctions[level] = proto[level] ? proto[level] : (_console[level] || _console[logFallbackMap[level] || 'log'] || noop)
   })
   logger[baseLogFunctionSymbol] = logFunctions
 }
diff --git a/lib/tools.js b/lib/tools.js
index 92bd23b..d67b2a4 100644
--- a/lib/tools.js
+++ b/lib/tools.js
@@ -156,7 +156,8 @@ function asJson (obj, msg, num, time) {
           value = (stringifier || stringify)(value, stringifySafe)
       }
       if (value === undefined) continue
-      propStr += ',"' + key + '":' + value
+      const strKey = asString(key)
+      propStr += ',' + strKey + ':' + value
     }
   }
 


Test patch:
diff --git a/test/basic.test.js b/test/basic.test.js
index c8a6962..a7ad5ba 100644
--- a/test/basic.test.js
+++ b/test/basic.test.js
@@ -420,6 +420,23 @@ test('correctly escape msg strings with unclosed double quote', async ({ same })
   })
 })
 
+test('correctly escape quote in a key', async ({ same }) => {
+  const stream = sink()
+  const instance = pino(stream)
+  const obj = { 'some"obj': 'world' }
+  instance.info(obj, 'a string')
+  const result = await once(stream, 'data')
+  delete result.time
+  same(result, {
+    level: 30,
+    pid,
+    hostname,
+    msg: 'a string',
+    'some"obj': 'world'
+  })
+  same(Object.keys(obj), ['some"obj'])
+})
+
 // https://github.com/pinojs/pino/issues/139
 test('object and format string', async ({ same }) => {
   const stream = sink()
Repository: pinojs/pino
Pull request #1980 (2024-05-20 22:00:20)

suppport messageKey in pino/browser
Fixes https://github.com/pinojs/pino/issues/1978


Patch:
diff --git a/browser.js b/browser.js
index a27cd23..8560f1f 100644
--- a/browser.js
+++ b/browser.js
@@ -111,7 +111,8 @@ function pino (opts) {
     asObject: opts.browser.asObject,
     formatters: opts.browser.formatters,
     levels,
-    timestamp: getTimeFunction(opts)
+    timestamp: getTimeFunction(opts),
+    messageKey: opts.messageKey || 'msg'
   }
   logger.levels = getLevels(opts)
   logger.level = level
@@ -308,7 +309,7 @@ function createWrap (self, opts, rootLogger, level) {
         argsIsSerialized = true
       }
       if (opts.asObject || opts.formatters) {
-        write.call(proto, asObject(this, level, args, ts, opts.formatters))
+        write.call(proto, asObject(this, level, args, ts, opts))
       } else write.apply(proto, args)
 
       if (opts.transmit) {
@@ -330,11 +331,11 @@ function createWrap (self, opts, rootLogger, level) {
   })(self[baseLogFunctionSymbol][level])
 }
 
-function asObject (logger, level, args, ts, formatters = {}) {
+function asObject (logger, level, args, ts, opts) {
   const {
     level: levelFormatter,
     log: logObjectFormatter = (obj) => obj
-  } = formatters
+  } = opts.formatters || {}
   const argsCloned = args.slice()
   let msg = argsCloned[0]
   const logObject = {}
@@ -358,7 +359,7 @@ function asObject (logger, level, args, ts, formatters = {}) {
     }
     msg = argsCloned.length ? format(argsCloned.shift(), argsCloned) : undefined
   } else if (typeof msg === 'string') msg = format(argsCloned.shift(), argsCloned)
-  if (msg !== undefined) logObject.msg = msg
+  if (msg !== undefined) logObject[opts.messageKey] = msg
 
   const formattedLogObject = logObjectFormatter(logObject)
   return formattedLogObject


Test patch:
diff --git a/test/browser.test.js b/test/browser.test.js
index f2bb9b3..8684006 100644
--- a/test/browser.test.js
+++ b/test/browser.test.js
@@ -165,6 +165,23 @@ test('opts.browser.asObject logs pino-like object to console', ({ end, ok, is })
   instance.info('test')
   end()
 })
+test('opts.browser.asObject uses opts.messageKey in logs', ({ end, ok, is }) => {
+  const messageKey = 'message'
+  const instance = require('../browser')({
+    messageKey,
+    browser: {
+      asObject: true,
+      write: function (o) {
+        is(o.level, 30)
+        is(o[messageKey], 'test')
+        ok(o.time)
+      }
+    }
+  })
+
+  instance.info('test')
+  end()
+})
 
 test('opts.browser.formatters (level) logs pino-like object to console', ({ end, ok, is }) => {
   const info = console.info
Repository: pinojs/pino
Pull request #1986 (2024-06-09 21:34:52)

Fixing browser side child log issue (#960) child level can now be set at cr…
With this PR, a browser side child logger level can now be set at creation time. More discussions and sample code to demonstrate this problem are in #960.


Patch:
diff --git a/browser.js b/browser.js
index 8560f1f..f65ad76 100644
--- a/browser.js
+++ b/browser.js
@@ -195,7 +195,7 @@ function pino (opts) {
     // must happen before the level is assigned
     appendChildLogger(this, newLogger)
     // required to actually initialize the logger functions for any given child
-    newLogger.level = this.level
+    newLogger.level = childOptions.level || this.level // allow level to be set by childOptions
 
     return newLogger
   }


Test patch:
diff --git a/test/browser-child.test.js b/test/browser-child.test.js
index 0ed1dd5..db80e7e 100644
--- a/test/browser-child.test.js
+++ b/test/browser-child.test.js
@@ -14,6 +14,18 @@ test('child has parent level', ({ end, same, is }) => {
   end()
 })
 
+test('child can set level at creation time', ({ end, same, is }) => {
+  const instance = pino({
+    level: 'error',
+    browser: {}
+  })
+
+  const child = instance.child({}, { level: 'info' }) // first bindings, then options
+
+  same(child.level, 'info')
+  end()
+})
+
 test('changing child level does not affect parent', ({ end, same, is }) => {
   const instance = pino({
     level: 'error',
Repository: pinojs/pino
Pull request #2001 (2024-07-04 15:17:06)

call onChild when instanciating new child browser logger
onChild callback is currently not called when instanciating a child broser logger.
This PR corrects this by passing the callback passed to the parent pino ops into the browser context and calling it on new Child.

Test also included.


Patch:
diff --git a/browser.js b/browser.js
index f65ad76..181eaa7 100644
--- a/browser.js
+++ b/browser.js
@@ -112,7 +112,8 @@ function pino (opts) {
     formatters: opts.browser.formatters,
     levels,
     timestamp: getTimeFunction(opts),
-    messageKey: opts.messageKey || 'msg'
+    messageKey: opts.messageKey || 'msg',
+    onChild: opts.onChild || noop
   }
   logger.levels = getLevels(opts)
   logger.level = level
@@ -127,7 +128,7 @@ function pino (opts) {
   logger.serializers = serializers
   logger._serialize = serialize
   logger._stdErrSerialize = stdErrSerialize
-  logger.child = child
+  logger.child = function (...args) { return child.call(this, setOpts, ...args) }
 
   if (transmit) logger._logEvent = createLogEventShape()
 
@@ -156,7 +157,7 @@ function pino (opts) {
     })
   }
 
-  function child (bindings, childOptions) {
+  function child (setOpts, bindings, childOptions) {
     if (!bindings) {
       throw new Error('missing bindings for child Pino')
     }
@@ -194,8 +195,10 @@ function pino (opts) {
 
     // must happen before the level is assigned
     appendChildLogger(this, newLogger)
+    newLogger.child = function (...args) { return child.call(this, setOpts, ...args) }
     // required to actually initialize the logger functions for any given child
     newLogger.level = childOptions.level || this.level // allow level to be set by childOptions
+    setOpts.onChild(newLogger)
 
     return newLogger
   }


Test patch:
diff --git a/test/browser-child.test.js b/test/browser-child.test.js
index db80e7e..679261a 100644
--- a/test/browser-child.test.js
+++ b/test/browser-child.test.js
@@ -106,6 +106,20 @@ test('changing child log level should not affect parent log behavior', ({ end, s
   end()
 })
 
+test('onChild callback should be called when new child is created', ({ end, pass, plan }) => {
+  plan(1)
+  const instance = pino({
+    level: 'error',
+    browser: {},
+    onChild: (_child) => {
+      pass('onChild callback was called')
+      end()
+    }
+  })
+
+  instance.child({})
+})
+
 function checkLogObjects (is, same, actual, expected) {
   is(actual.time <= Date.now(), true, 'time is greater than Date.now()')
Repository: pinojs/pino
Pull request #2005 (2024-07-12 11:50:31)

fix(browser): should respect log level with transmit
Potential fix for https://github.com/pinojs/pino/issues/1861

Added early return in the case level of the message is below transmit level

Added unit test for the case


Patch:
diff --git a/browser.js b/browser.js
index 181eaa7..522de1a 100644
--- a/browser.js
+++ b/browser.js
@@ -276,8 +276,13 @@ function set (self, opts, rootLogger, level) {
     configurable: true
   })
 
-  if (!opts.transmit && self[level] === noop) {
-    return
+  if (self[level] === noop) {
+    if (!opts.transmit) return
+
+    const transmitLevel = opts.transmit.level || self.level
+    const transmitValue = rootLogger.levels.values[transmitLevel]
+    const methodValue = rootLogger.levels.values[level]
+    if (methodValue < transmitValue) return
   }
 
   // make sure the log format is correct


Test patch:
diff --git a/test/browser-transmit.test.js b/test/browser-transmit.test.js
index fb090c2..860524b 100644
--- a/test/browser-transmit.test.js
+++ b/test/browser-transmit.test.js
@@ -347,3 +347,23 @@ test('extracts correct bindings and raw messages over multiple transmits', ({ en
 
   end()
 })
+
+test('does not log below configured level', ({ end, is }) => {
+  let message = null
+  const logger = pino({
+    level: 'info',
+    browser: {
+      write (o) {
+        message = o.msg
+      },
+      transmit: {
+        send () { }
+      }
+    }
+  })
+
+  logger.debug('this message is silent')
+  is(message, null)
+
+  end()
+})
Repository: pinojs/pino-http
Pull request #15 (2016-11-15 17:39:55)

fix custom instance and custom request id
Fixes https://github.com/pinojs/pino-http/issues/14


Patch:
diff --git a/logger.js b/logger.js
index 97f53b8..63bde40 100644
--- a/logger.js
+++ b/logger.js
@@ -67,12 +67,15 @@ function asReqValue (req) {
 
 function wrapChild (opts, stream) {
   var prevLogger = opts.logger
+  var prevGenReqId = opts.genReqId
   var logger = null
 
   if (prevLogger) {
     opts.logger = undefined
+    opts.genReqId = undefined
     logger = prevLogger.child(opts)
     opts.logger = prevLogger
+    opts.genReqId = prevGenReqId
   } else {
     logger = pino(opts, stream)
   }


Test patch:
diff --git a/test.js b/test.js
index 63a4003..91a2af2 100644
--- a/test.js
+++ b/test.js
@@ -191,3 +191,34 @@ test('support a custom instance', function (t) {
     t.end()
   })
 })
+
+test('support a custom instance with custom genReqId function', function (t) {
+  var dest = split(JSON.parse)
+
+  var idToTest
+  function genReqId (req) {
+    t.ok(req.url, 'The first argument must be the request parameter')
+    idToTest = (Date.now() + Math.random()).toString(32)
+    return idToTest
+  }
+
+  var logger = pinoHttp({
+    logger: pino(dest),
+    genReqId: genReqId
+  })
+
+  setup(t, logger, function (err, server) {
+    t.error(err)
+    doGet(server)
+  })
+
+  dest.on('data', function (line) {
+    t.ok(line.req, 'req is defined')
+    t.ok(line.res, 'res is defined')
+    t.notOk(line.genReqId)
+    t.equal(line.msg, 'request completed', 'message is set')
+    t.equal(line.req.method, 'GET', 'method is get')
+    t.equal(line.res.statusCode, 200, 'statusCode is 200')
+    t.end()
+  })
+})
Repository: pinojs/pino-http
Pull request #16 (2016-11-28 08:40:22)

Stream options
Added the `stream` option to pass the destination stream inside the `options` object instead of the second parameter.
I left the standalone stream parameter for back compatibility.
(cc https://github.com/mcollina/fastify/pull/25)


Patch:
diff --git a/README.md b/README.md
index d49b39f..8439d37 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ connections and 10 pipelined requests.
 * `pino-http` (extreme): 25770.91 req/sec
 * no logger: 46139.64 req/sec
 
-All benchmarks where taken on a Macbook Pro 2013 (2.6GHZ i7, 16GB of RAM). 
+All benchmarks where taken on a Macbook Pro 2013 (2.6GHZ i7, 16GB of RAM).
 
 ## Install
 
@@ -107,6 +107,10 @@ You can pass a `genReqId` function which gets used to generate a request id. The
 
 As fallback `pino-http` is just using an integer. This default might not be the desired behavior if you're running multiple instances of the app.
 
+##### stream
+The destination stream.  
+Could be passed as the second parameter or as an option.
+
 #### Examples
 
 ##### Logger options
diff --git a/logger.js b/logger.js
index 63bde40..1f388a6 100644
--- a/logger.js
+++ b/logger.js
@@ -13,7 +13,10 @@ function pinoLogger (opts, stream) {
   opts.serializers.req = opts.serializers.req || asReqValue
   opts.serializers.res = opts.serializers.res || pino.stdSerializers.res
 
-  var logger = wrapChild(opts, stream)
+  var theStream = opts.stream || stream
+  delete opts.stream
+
+  var logger = wrapChild(opts, theStream)
   var genReqId = reqIdGenFactory(opts.genReqId)
   loggingMiddleware.logger = logger
   return loggingMiddleware


Test patch:
diff --git a/test.js b/test.js
index 91a2af2..190fbcd 100644
--- a/test.js
+++ b/test.js
@@ -51,6 +51,25 @@ test('default settings', function (t) {
   })
 })
 
+test('stream in options', function (t) {
+  var dest = split(JSON.parse)
+  var logger = pinoHttp({ stream: dest })
+
+  setup(t, logger, function (err, server) {
+    t.error(err)
+    doGet(server)
+  })
+
+  dest.on('data', function (line) {
+    t.ok(line.req, 'req is defined')
+    t.ok(line.res, 'res is defined')
+    t.equal(line.msg, 'request completed', 'message is set')
+    t.equal(line.req.method, 'GET', 'method is get')
+    t.equal(line.res.statusCode, 200, 'statusCode is 200')
+    t.end()
+  })
+})
+
 test('exposes the internal pino', function (t) {
   t.plan(1)