Feature Request: Support For Automatically Generating Breadcrumbs With Pino
Customer asking - wrote in with the following snippet for @sentry/node:
import { Router } from 'express'
import pino from 'pino'
const logger = pino({level: 'info'});
const object = {
id: '123',
name: 'My Object'
}
export const objectRouter = new Router({ mergeParams: true})
objectRouter.get('/', (req, res) => {
const { id } = req.params
console.log(`Fetching object:${id}`) // <-- this shows up as breadcrumb
logger.info(`Fetching object:${id}`) // <-- this doesn't
Breadcrumbs from logging currently only support the 'console' module.
We probably need to build an integration for pino similar to https://github.com/getsentry/sentry-javascript/blob/master/packages/node/src/integrations/console.ts to make this work.
I'm trying to do some work on this. I've looked at the console.ts file and seen how sentry is integrating to the console object. One thing that I don't fully understand is the import * as util from 'util'; line. What import is this getting?
@Lilja that is importing the util node standard library: https://nodejs.org/api/util.html
This issue has gone three weeks without activity. In another week, I will close it.
But! If you comment or otherwise update it, I will reset the clock, and if you label it Status: Backlog or Status: In Progress, I will leave it alone ... forever!
"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀
Until an official integration exists, here's a simple bridge between pino and the console log methods:
import pino from 'pino'
import { Writable } from 'node:stream'
// By default, pino uses the `process.stdout` stream, which is not instrumented
// by Sentry. Sentry does instrument the methods on the `console` object, so we
// set up these streams to use the `console` object instead of `process.stdout`.
// This way, pino logs will be sent to Sentry.
function createConsoleStream(level: 'info' | 'warn' | 'error') {
return new Writable({
write(chunk: Buffer, _encoding, callback) {
// Both pino and the console methods add a trailing newline, so we slice
// off one character to avoid double newlines in the logs.
const msg = chunk.toString().slice(0, -1)
console[level](msg)
callback()
},
})
}
const consoleInfoStream = createConsoleStream('info')
const consoleWarnStream = createConsoleStream('warn')
const consoleErrorStream = createConsoleStream('error')
export const logger = pino(
{
level: 'info',
},
pino.multistream(
[
{ stream: consoleInfoStream },
{ level: 'warn', stream: consoleWarnStream },
{ level: 'error', stream: consoleErrorStream },
{ level: 'fatal', stream: consoleErrorStream },
],
{ dedupe: true }
)
)
fatalanderror->console.errorwarn->console.warninfo->console.info
Other log levels (if the level option allows) will also go to console.info. If you want to set a different stream for those, the streams array can be expanded. Though be aware that pino.multistream requires that the logger's level option be set to the lowest level used in the streams array.