Skip to content

Instantly share code, notes, and snippets.

@miguelmota
Created November 26, 2019 02:05
Show Gist options
  • Save miguelmota/4df504cff4bfebcff982dd06bde7a34a to your computer and use it in GitHub Desktop.
Save miguelmota/4df504cff4bfebcff982dd06bde7a34a to your computer and use it in GitHub Desktop.
Node.js pino logger show caller filename and line number
import path from 'path'
import pino from 'pino'
const STACKTRACE_OFFSET = 2
const LINE_OFFSET = 7
const { symbols : { asJsonSym} } = pino
function traceCaller (pinoInstance) {
const get = (target, name) => name === asJsonSym ? asJson : target[name]
function asJson (...args) {
args[0] = args[0] || Object.create(null)
args[0].caller = Error().stack.split('\n').filter(s => !s.includes('node_modules/pino') && !s.includes('node_modules\\pino'))[STACKTRACE_OFFSET].substr(LINE_OFFSET).replace(path.resolve(__dirname, '..'), '')
return pinoInstance[asJsonSym].apply(this, args)
}
return new Proxy(pinoInstance, { get })
}
const logger = traceCaller(pino({
level: 'debug',
prettyPrint: {
colorize: true,
}
}))
@fleveillee
Copy link

fleveillee commented Jul 20, 2022

Love this! Thanks - thanks - thanks! 👍
As a node ESM version, I had issues with __dirname, also substr() should be replaced by substring()

I'm using dirname(import.meta.url) as a workaround, if in a subfolder, you can call dirname twice
Here's my take on traceCaller, I also modernized the pino instance creation since "prettyPrint" is deprecated.

import { pino } from 'pino'
import { dirname } from 'path'

const STACKTRACE_OFFSET = 2
const LINE_OFFSET = 7
const { symbols: { asJsonSym } } = pino

function traceCaller (pinoInstance) {
  const get = (target, name) => name === asJsonSym ? asJson : target[name]

  function asJson (...args) {
    args[0] = args[0] || Object.create(null)
    args[0].caller = Error().stack.split('\n')
      .filter(s => !s.includes('node_modules/pino') && !s.includes('node_modules\\pino'))[STACKTRACE_OFFSET]
      .substring(LINE_OFFSET).replace(dirname(import.meta.url) + '/', '')

    return pinoInstance[asJsonSym].apply(this, args)
  }

  return new Proxy(pinoInstance, { get })
}

const logger = traceCaller(pino({
  level: 'debug',
  transport: {
    target: 'pino-pretty',
    options: {
      ignore: 'time,pid,hostname'
    }
  }
}))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment