Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: pinojs/pino-pretty
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 92b68f4b14da7553361170f42de5932fc7bf837f
Choose a base ref
...
head repository: pinojs/pino-pretty
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 7693cd4810ab7b9589f33364148d0cd33119dd42
Choose a head ref
  • 8 commits
  • 10 files changed
  • 5 contributors

Commits on Apr 13, 2021

  1. Bump actions/cache from v2.1.4 to v2.1.5 (#176)

    Bumps [actions/cache](https://github.com/actions/cache) from v2.1.4 to v2.1.5.
    - [Release notes](https://github.com/actions/cache/releases)
    - [Commits](actions/cache@v2.1.4...1a9e213)
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Apr 13, 2021
    Copy the full SHA
    edfcbce View commit details

Commits on Apr 14, 2021

  1. Added missing comma (#177)

    Jackson Melcher authored Apr 14, 2021
    Copy the full SHA
    141ca39 View commit details

Commits on Apr 29, 2021

  1. Copy the full SHA
    5227c2e View commit details
  2. Bump fastify/github-action-merge-dependabot from v1.2.1 to v2.0.0 (#167)

    Bumps [fastify/github-action-merge-dependabot](https://github.com/fastify/github-action-merge-dependabot) from v1.2.1 to v2.0.0.
    - [Release notes](https://github.com/fastify/github-action-merge-dependabot/releases)
    - [Commits](fastify/github-action-merge-dependabot@v1.2.1...a8beb6a)
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Apr 29, 2021
    Copy the full SHA
    d9fc678 View commit details

Commits on May 9, 2021

  1. Copy the full SHA
    24e8ff0 View commit details
  2. Add support to ignore nested properties (#180)

    * Add support to ignore nested properties
    
    * Delete from deep clone of log object
    
    * Update README
    
    * Update function description and add utils tests
    TzeWey authored May 9, 2021
    Copy the full SHA
    3477063 View commit details
  3. Revert quotes (#184)

    jsumners authored May 9, 2021
    Copy the full SHA
    7a217e8 View commit details
  4. v4.8.0

    jsumners committed May 9, 2021
    Copy the full SHA
    7693cd4 View commit details
Showing with 160 additions and 39 deletions.
  1. +2 −2 .github/dependabot.yml
  2. +16 −10 .github/workflows/ci.yml
  3. +13 −13 Readme.md
  4. +4 −4 docs/help.md
  5. +3 −7 index.js
  6. +44 −2 lib/utils.js
  7. +2 −1 package.json
  8. +23 −0 test/cli.test.js
  9. +30 −0 test/lib/utils.internals.test.js
  10. +23 −0 test/lib/utils.public.test.js
4 changes: 2 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
directory: '/'
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: npm
directory: "/"
directory: '/'
schedule:
interval: daily
open-pull-requests-limit: 10
26 changes: 16 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,46 @@
name: CI

on:
push:
paths-ignore:
- "docs/**"
- "*.md"
- 'docs/**'
- '*.md'
pull_request:
paths-ignore:
- "docs/**"
- "*.md"
- 'docs/**'
- '*.md'

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x, 12.x, 13.x, 14.x]
node-version: [10, 12, 13, 14, 16]
steps:
- name: Checkout
uses: actions/checkout@v2.3.4

- name: Use Node.js
uses: actions/setup-node@v2.1.5
with:
node-version: ${{ matrix.node-version }}

- name: Restore cached dependencies
uses: actions/cache@v2.1.4
uses: actions/cache@v2.1.5
with:
path: node_modules
key: node-modules-${{ hashFiles('package.json') }}

- name: Install dependencies
run: npm install

- name: Run Tests
run: npm run ci

- name: Coveralls Parallel
uses: coverallsapp/github-action@v1.1.2
with:
github-token: ${{ secrets.github_token }}
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel: true
flag-name: run-${{ matrix.node-version }}-${{ matrix.os }}

@@ -51,7 +58,6 @@ jobs:
needs: build
runs-on: ubuntu-latest
steps:
- uses: fastify/github-action-merge-dependabot@v1.2.1
if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request' }}
- uses: fastify/github-action-merge-dependabot@v2.0.0
with:
github-token: ${{secrets.github_token}}
github-token: ${{ secrets.GITHUB_TOKEN }}
26 changes: 13 additions & 13 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ $ npm install -g pino-pretty
<a id="usage"></a>
## Usage

It's recommended to use `pino-pretty` with `pino`
It is recommended to use `pino-pretty` with `pino`
by piping output to the CLI tool:

```sh
@@ -59,7 +59,7 @@ node app.js | pino-pretty
- `--crlf` (`-f`): Appends carriage return and line feed, instead of just a line
feed, to the formatted log line.
- `--errorProps` (`-e`): When formatting an error object, display this list
of properties. The list should be a comma separated list of properties Default: `''`.
of properties. The list should be a comma-separated list of properties Default: `''`.
- `--levelFirst` (`-l`): Display the log level name before the logged date and time.
- `--errorLikeObjectKeys` (`-k`): Define the log keys that are associated with
error like objects. Default: `err,error`.
@@ -73,25 +73,25 @@ node app.js | pino-pretty
Default: `false`
- `--timestampKey` (`-a`): Define the key that contains the log timestamp.
Default: `time`.
- `--translateTime` (`-t`): Translate the epoch time value into a human readable
- `--translateTime` (`-t`): Translate the epoch time value into a human-readable
date and time string. This flag also can set the format string to apply when
translating the date to human readable format. For a list of available pattern
letters see the [`dateformat` documentation](https://www.npmjs.com/package/dateformat).
translating the date to a human-readable format. For a list of available pattern
letters, see the [`dateformat` documentation](https://www.npmjs.com/package/dateformat).
- The default format is `yyyy-mm-dd HH:MM:ss.l o` in UTC.
- Require a `SYS:` prefix to translate time to the local system's timezone. A
- Require a `SYS:` prefix to translate time to the local system's time zone. A
shortcut `SYS:standard` to translate time to `yyyy-mm-dd HH:MM:ss.l o` in
system timezone.
system time zone.
- `--search` (`-s`): Specify a search pattern according to
[jmespath](http://jmespath.org/).
- `--ignore` (`-i`): Ignore one or several keys: (`-i time,hostname`)
- `--ignore` (`-i`): Ignore one or several keys, nested keys are supported: (`-i time,hostname,req.headers`)
- `--hideObject` (`-H`): Hide objects from output (but not error object)
- `--singleLine` (`-S`): Print each log message on a single line (errors will still be multi-line)
- `--config`: Specify a path to a config file containing the pino-pretty options. pino-pretty will attempt to read from a `.pino-prettyrc` in your current directory (`process.cwd`) if not specified

<a id="integration"></a>
## Programmatic Integration

We recommend against using `pino-pretty` in production, and highly
We recommend against using `pino-pretty` in production and highly
recommend installing `pino-pretty` as a development dependency.

When installed, `pino-pretty` will be used by `pino` as the default
@@ -139,7 +139,7 @@ with keys corresponding to the options described in [CLI Arguments](#cliargs):
levelFirst: false, // --levelFirst
messageKey: 'msg', // --messageKey
levelKey: 'level', // --levelKey
messageFormat: false // --messageFormat
messageFormat: false, // --messageFormat
timestampKey: 'time', // --timestampKey
translateTime: false, // --translateTime
search: 'foo == `bar`', // --search
@@ -155,7 +155,7 @@ The `colorize` default follows

`customPrettifiers` option provides the ability to add a custom prettify function
for specific log properties. `customPrettifiers` is an object, where keys are
log properties which will be prettified and value is the prettify function itself.
log properties that will be prettified and value is the prettify function itself.
For example, if a log line contains a `query` property,
you can specify a prettifier for it:
```js
@@ -170,13 +170,13 @@ const prettifyQuery = value => {
}
```

`messageFormat` option allows you to customize the message output. The format can be defined by a template `string` like this:
`messageFormat` option allows you to customize the message output. A template `string` like this can define the format:
```js
{
messageFormat: '{levelLabel} - {pid} - url:{request.url}'
}
```
But this option can also be defined as a `function` with this prototype:
This option can also be defined as a `function` with this prototype:
```js
{
messageFormat: (log, messageKey, levelLabel) => {
8 changes: 4 additions & 4 deletions docs/help.md
Original file line number Diff line number Diff line change
@@ -3,22 +3,22 @@

If you run your Node.js process via [Systemd](https://www.freedesktop.org/wiki/Software/systemd/) and you examine your logs with [journalctl](https://www.freedesktop.org/software/systemd/man/journalctl.html) some data will be duplicated. You can use a combination of `journalctl` options and `pino-pretty` options to shape the output.

For example viewing the pretified logs of a process named `monitor` with `journalctl -u monitor -f | pino-pretty`, might output something like this:
For example viewing the prettified logs of a process named `monitor` with `journalctl -u monitor -f | pino-pretty`, might output something like this:

```
Apr 24 07:40:01 nanopi node[6080]: {"level":30,"time":1587706801902,"pid":6080,"hostname":"nanopi","msg":"TT
21","v":1}
```
As you can see, the timestamp, hostname and pid are duplicated.
If you just want the bare pretified Pino logs you can strip out the duplicate items from the `journalctl` output with the `-o cat` option of `journalctl`:
As you can see, the timestamp, hostname, and pid are duplicated.
If you just want the bare prettified Pino logs you can strip out the duplicate items from the `journalctl` output with the `-o cat` option of `journalctl`:
```
journalctl -u monitor -f -o cat | pino-pretty
```
the output now looks something like this:
```
[1587706801902] INFO (6080 on nanopi): TT 21
```
Making the output even more human readble by using the pino-pretty options `-t` to format the timestamp and `-i pid, hostname` to filter out hostname and pid:
Make the output even more human readable by using the pino-pretty options `-t` to format the timestamp and `-i pid, hostname` to filter out hostname and pid:
```
[2020-04-24 05:42:24.836 +0000] INFO : TT 21
```
10 changes: 3 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
@@ -11,7 +11,8 @@ const {
prettifyMessage,
prettifyMetadata,
prettifyObject,
prettifyTime
prettifyTime,
filterLog
} = require('./lib/utils')

const bourne = require('@hapi/bourne')
@@ -81,12 +82,7 @@ module.exports = function prettyFactory (options) {
const prettifiedMessage = prettifyMessage({ log, messageKey, colorizer, messageFormat, levelLabel })

if (ignoreKeys) {
log = Object.keys(log)
.filter(key => !ignoreKeys.has(key))
.reduce((res, key) => {
res[key] = log[key]
return res
}, {})
log = filterLog(log, ignoreKeys)
}

const prettifiedLevel = prettifyLevel({ log, colorizer, levelKey })
46 changes: 44 additions & 2 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'

const clone = require('rfdc')()
const dateformat = require('dateformat')
const stringifySafe = require('fast-safe-stringify')
const defaultColorizer = require('./colors')()
@@ -21,13 +22,15 @@ module.exports = {
prettifyMessage,
prettifyMetadata,
prettifyObject,
prettifyTime
prettifyTime,
filterLog
}

module.exports.internals = {
formatTime,
joinLinesWithIndentation,
prettifyError
prettifyError,
deleteLogProperty
}

/**
@@ -435,3 +438,42 @@ function prettifyError ({ keyName, lines, eol, ident }) {

return result
}

/**
* Deletes a specified property from a log object if it exists.
* This function mutates the passed in `log` object.
*
* @param {object} log The log object to be modified.
* @param {string} property A string identifying the property to be deleted from
* the log object. Accepts nested properties delimited by a `.`
* e.g. `'prop1.prop2'`.
*/
function deleteLogProperty (log, property) {
const props = property.split('.')
const propToDelete = props.pop()

props.forEach((prop) => {
if (!Object.prototype.hasOwnProperty.call(log, prop)) {
return
}
log = log[prop]
})

delete log[propToDelete]
}

/**
* Filter a log object by removing any ignored keys.
*
* @param {object} log The log object to be modified.
* @param {string} ignoreKeys An array of strings identifying the properties to be removed.
*
* @returns {object} A new `log` object instance that does not include the ignored keys.
*/
function filterLog (log, ignoreKeys) {
const logCopy = clone(log)
ignoreKeys.forEach((ignoreKey) => {
deleteLogProperty(logCopy, ignoreKey)
})
return logCopy
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pino-pretty",
"version": "4.7.1",
"version": "4.8.0",
"description": "Prettifier for Pino log lines",
"main": "index.js",
"bin": {
@@ -38,6 +38,7 @@
"joycon": "^2.2.5",
"pump": "^3.0.0",
"readable-stream": "^3.6.0",
"rfdc": "^1.3.0",
"split2": "^3.1.1",
"strip-json-comments": "^3.1.1"
},
23 changes: 23 additions & 0 deletions test/cli.test.js
Original file line number Diff line number Diff line change
@@ -133,5 +133,28 @@ test('cli', (t) => {
t.tearDown(() => child.kill())
})

t.test('does ignore nested keys', (t) => {
t.plan(1)

const logLineNested = JSON.stringify(Object.assign(JSON.parse(logLine), {
extra: {
foo: 'bar',
number: 42,
nested: {
foo2: 'bar2'
}
}
})) + '\n'

const env = { TERM: 'dumb' }
const child = spawn(process.argv[0], [bin, '-S', '-i', 'extra.foo,extra.nested,extra.nested.miss'], { env })
child.on('error', t.threw)
child.stdout.on('data', (data) => {
t.is(data.toString(), `[${epoch}] INFO (42 on foo): hello world {"extra":{"number":42}}\n`)
})
child.stdin.write(logLineNested)
t.tearDown(() => child.kill())
})

t.end()
})
30 changes: 30 additions & 0 deletions test/lib/utils.internals.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const tap = require('tap')
const clone = require('rfdc')()
const stringifySafe = require('fast-safe-stringify')
const { internals } = require('../../lib/utils')

@@ -95,3 +96,32 @@ tap.test('#prettifyError', t => {

t.end()
})

tap.test('#deleteLogProperty', t => {
const logData = {
level: 30,
data1: {
data2: { 'data-3': 'bar' }
}
}

t.test('deleteLogProperty deletes property of depth 1', async t => {
const log = clone(logData)
internals.deleteLogProperty(log, 'data1')
t.same(log, { level: 30 })
})

t.test('deleteLogProperty deletes property of depth 2', async t => {
const log = clone(logData)
internals.deleteLogProperty(log, 'data1.data2')
t.same(log, { level: 30, data1: { } })
})

t.test('deleteLogProperty deletes property of depth 3', async t => {
const log = clone(logData)
internals.deleteLogProperty(log, 'data1.data2.data-3')
t.same(log, { level: 30, data1: { data2: { } } })
})

t.end()
})
23 changes: 23 additions & 0 deletions test/lib/utils.public.test.js
Original file line number Diff line number Diff line change
@@ -341,3 +341,26 @@ tap.test('prettifyTime', t => {

t.end()
})

tap.test('#filterLog', t => {
const { filterLog } = utils
const logData = {
level: 30,
time: 1522431328992,
data1: {
data2: { 'data-3': 'bar' }
}
}

t.test('filterLog removes single entry', async t => {
const result = filterLog(logData, ['data1.data2.data-3'])
t.same(result, { level: 30, time: 1522431328992, data1: { data2: { } } })
})

t.test('filterLog removes multiple entries', async t => {
const result = filterLog(logData, ['time', 'data1'])
t.same(result, { level: 30 })
})

t.end()
})