Skip to content

Commit

Permalink
Add support for custom prettifiers on the metadata (#283)
Browse files Browse the repository at this point in the history
So folks can prettify the pid, logger name, or hostname as they see fit
  • Loading branch information
airhorns committed Dec 14, 2021
1 parent de1007f commit 96fcc9b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 10 deletions.
8 changes: 7 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ const prettifyQuery = value => {
}
```

Additionally, `customPrettifiers` can be used to format the time and level
Additionally, `customPrettifiers` can be used to format the `time`, `hostname`, `pid`, `name`, `caller` and `level`
outputs:

```js
Expand All @@ -269,6 +269,12 @@ outputs:
// on if the levelKey option is used or not.
// By default this will be the same numerics as the Pino default:
level: logLevel => `LEVEL: ${logLevel}`

// other prettifiers can be used for the other keys if needed, for example
hostname: hostname => colorGreen(hostname)
pid: pid => colorRed(hostname)
name: name => colorBlue(name)
caller: caller => colorCyan(caller)
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function prettyFactory (options) {
}

const prettifiedLevel = prettifyLevel({ log, colorizer, levelKey, prettifier: customPrettifiers.level })
const prettifiedMetadata = prettifyMetadata({ log })
const prettifiedMetadata = prettifyMetadata({ log, prettifiers: customPrettifiers })
const prettifiedTime = prettifyTime({ log, translateFormat: opts.translateTime, timestampKey, prettifier: customPrettifiers.time })

let line = ''
Expand Down
23 changes: 15 additions & 8 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,37 +281,44 @@ function prettifyMessage ({ log, messageFormat, messageKey = MESSAGE_KEY, colori
* @param {object} input
* @param {object} input.log The log that may or may not contain metadata to
* be prettified.
* @param {object} input.prettifiers A set of functions used to prettify each
* key of the input log's metadata. The keys are the keys of the metadata (like
* `hostname`, `pid`, `name`, etc), and the values are functions which take the
* metadata value and return a string. Each key is optional.
*
* @returns {undefined|string} If no metadata is found then `undefined` is
* returned. Otherwise, a string of prettified metadata is returned.
*/
function prettifyMetadata ({ log }) {
function prettifyMetadata ({ log, prettifiers = {} }) {
let line = ''

if (log.name || log.pid || log.hostname) {
line += '('

if (log.name) {
line += log.name
line += prettifiers.name ? prettifiers.name(log.name) : log.name
}

if (log.name && log.pid) {
line += '/' + log.pid
} else if (log.pid) {
line += log.pid
if (log.pid) {
const prettyPid = prettifiers.pid ? prettifiers.pid(log.pid) : log.pid
if (log.name && log.pid) {
line += '/' + prettyPid
} else {
line += prettyPid
}
}

if (log.hostname) {
// If `pid` and `name` were in the ignore keys list then we don't need
// the leading space.
line += `${line === '(' ? 'on' : ' on'} ${log.hostname}`
line += `${line === '(' ? 'on' : ' on'} ${prettifiers.hostname ? prettifiers.hostname(log.hostname) : log.hostname}`
}

line += ')'
}

if (log.caller) {
line += `${line === '' ? '' : ' '}<${log.caller}>`
line += `${line === '' ? '' : ' '}<${prettifiers.caller ? prettifiers.caller(log.caller) : log.caller}>`
}

if (line === '') {
Expand Down
59 changes: 59 additions & 0 deletions test/basic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,46 @@ test('basic prettifier tests', (t) => {
log.info({ msg: 'foo', bar: 'warn' })
})

t.test('can use a customPrettifier on name output', (t) => {
t.plan(1)
const customPrettifiers = {
name: (hostname) => `NAME: ${hostname}`
}
const pretty = prettyFactory({ customPrettifiers })
const log = pino({}, new Writable({
write (chunk, enc, cb) {
const formatted = pretty(chunk.toString())
t.equal(
formatted,
`[${epoch}] INFO (NAME: logger/${pid} on ${hostname}): foo\n`
)
cb()
}
}))
const child = log.child({ name: 'logger' })
child.info({ msg: 'foo' })
})

t.test('can use a customPrettifier on hostname and pid output', (t) => {
t.plan(1)
const customPrettifiers = {
hostname: (hostname) => `HOSTNAME: ${hostname}`,
pid: (pid) => `PID: ${pid}`
}
const pretty = prettyFactory({ customPrettifiers })
const log = pino({}, new Writable({
write (chunk, enc, cb) {
const formatted = pretty(chunk.toString())
t.equal(
formatted,
`[${epoch}] INFO (PID: ${pid} on HOSTNAME: ${hostname}): foo\n`
)
cb()
}
}))
log.info({ msg: 'foo' })
})

t.test('can use a customPrettifier on default time output', (t) => {
t.plan(1)
const customPrettifiers = {
Expand All @@ -189,6 +229,25 @@ test('basic prettifier tests', (t) => {
log.info('foo')
})

t.test('can use a customPrettifier on the caller', (t) => {
t.plan(1)
const customPrettifiers = {
caller: (caller) => `CALLER: ${caller}`
}
const pretty = prettyFactory({ customPrettifiers })
const log = pino({}, new Writable({
write (chunk, enc, cb) {
const formatted = pretty(chunk.toString())
t.equal(
formatted,
`[${epoch}] INFO (${pid} on ${hostname}) <CALLER: test.js:10>: foo\n`
)
cb()
}
}))
log.info({ msg: 'foo', caller: 'test.js:10' })
})

t.test('can use a customPrettifier on translateTime-time output', (t) => {
t.plan(1)
const customPrettifiers = {
Expand Down

0 comments on commit 96fcc9b

Please sign in to comment.