Skip to content

Commit

Permalink
Added documentation for MultiStreamRes, StreamEntry, DestinationStrea…
Browse files Browse the repository at this point in the history
…m and Level (#1342)

* Added documentation about MultiStreamRes, StreamEntry, DestinationStream and Level

* fix branching in multistream#add
  • Loading branch information
dbacarel authored Feb 17, 2022
1 parent c3cd594 commit 5d8eb71
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 17 deletions.
64 changes: 62 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
* [pino.stdTimeFunctions](#pino-stdtimefunctions)
* [pino.symbols](#pino-symbols)
* [pino.version](#pino-version)
* [Interfaces](#interfaces)
* [MultiStreamRes](#multistreamres)
* [StreamEntry](#streamentry)
* [DestinationStream](#destinationstream)
* [Types](#types)
* [Level](#level-1)

<a id="export"></a>
## `pino([options], [destination]) => logger`
Expand Down Expand Up @@ -1164,9 +1170,10 @@ finalLogger.info('exiting...')
<a id="pino-multistream"></a>
### `pino.multistream(options) => Stream`
### `pino.multistream(streamsArray, opts) => MultiStreamRes`
Create a stream composed by multiple destination streams:
Create a stream composed by multiple destination streams and returns an
object implementing the [MultiStreamRes](#multistreamres) interface.
```js
var fs = require('fs')
Expand Down Expand Up @@ -1272,3 +1279,56 @@ for general use.
Exposes the Pino package version. Also available on the logger instance.
* See [`logger.version`](#version)
## Interfaces
<a id="pino-multistreamres"></a>
### `MultiStreamRes`
Properties:
* `write(data)`
- `data` Object | string
- Returns: void
Write `data` onto the streams held by the current instance.
* `add(dest)`
- `dest` [StreamEntry](#streamentry) | [DestinationStream](#destinationstream)
- Returns: [MultiStreamRes](#multistreamres)
Add `dest` stream to the array of streams of the current instance.
* `flushSync()`
- Returns: `undefined`
Call `flushSync` on each stream held by the current instance.
* `minLevel`
- number
The minimum level amongst all the streams held by the current instance.
* `streams`
- Returns: [StreamEntry[]](#streamentry)
The array of streams currently held by the current instance.
* `clone(level)`
- `level` [Level](#level-1)
- Returns: [MultiStreamRes](#multistreamres)
Returns a cloned object of the current instance but with the the provided `level`.
### `StreamEntry`
Properties:
* `stream`
- DestinationStream
* `level`
- Optional: [Level](#level-1)
### `DestinationStream`
Properties:
* `write(msg)`
- `msg` string
## Types
### `Level`
* Values: `"fatal"` | `"error"` | `"warn"` | `"info"` | `"debug"` | `"trace"`
42 changes: 30 additions & 12 deletions lib/multistream.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ const { levels } = require('./levels')
const defaultLevels = Object.create(levels)
defaultLevels.silent = Infinity

const DEFAULT_INFO_LEVEL = levels.info

function multistream (streamsArray, opts) {
let counter = 0

streamsArray = streamsArray || []
opts = opts || { dedupe: false }

Expand Down Expand Up @@ -77,22 +78,39 @@ function multistream (streamsArray, opts) {
}

function add (dest) {
if (!dest) {
return res
}

// Check that dest implements either StreamEntry or DestinationStream
const isStream = typeof dest.write === 'function' || dest.stream
const stream_ = dest.write ? dest : dest.stream
// This is necessary to provide a meaningful error message, otherwise it throws somewhere inside write()
if (!isStream) {
throw Error('stream object needs to implement either StreamEntry or DestinationStream interface')
}

const { streams } = this
if (typeof dest.write === 'function') {
return add.call(this, { stream: dest })
} else if (typeof dest.levelVal === 'number') {
return add.call(this, Object.assign({}, dest, { level: dest.levelVal, levelVal: undefined }))

let level
if (typeof dest.levelVal === 'number') {
level = dest.levelVal
} else if (typeof dest.level === 'string') {
return add.call(this, Object.assign({}, dest, { level: levels[dest.level] }))
} else if (typeof dest.level !== 'number') {
// we default level to 'info'
dest = Object.assign({}, dest, { level: 30 })
level = levels[dest.level]
} else if (typeof dest.level === 'number') {
level = dest.level
} else {
dest = Object.assign({}, dest)
level = DEFAULT_INFO_LEVEL
}

const dest_ = {
stream: stream_,
level,
levelVal: undefined,
id: counter++
}
dest.id = counter++

streams.unshift(dest)
streams.unshift(dest_)
streams.sort(compareByLevel)

this.minLevel = streams[0].level
Expand Down
4 changes: 2 additions & 2 deletions pino.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,10 @@ declare namespace pino {

interface MultiStreamRes {
write: (data: any) => void,
add: (dest: Record<string, any>) => MultiStreamRes,
add: (dest: StreamEntry | DestinationStream) => MultiStreamRes,
flushSync: () => void,
minLevel: number,
streams: ({ stream: DestinationStream, level: number, id: number })[],
streams: StreamEntry[],
clone(level: Level): MultiStreamRes,
}

Expand Down
39 changes: 38 additions & 1 deletion test/multistream.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ test('no stream', function (t) {
t.end()
})

test('add a stream', function (t) {
test('one stream', function (t) {
let messageCount = 0
const stream = writeStream(function (data, enc, cb) {
messageCount += 1
Expand All @@ -497,6 +497,43 @@ test('add a stream', function (t) {
t.end()
})

test('add a stream', function (t) {
let messageCount = 0
const stream = writeStream(function (data, enc, cb) {
messageCount += 1
cb()
})

const log = pino({
level: 'trace'
}, multistream().add(stream))
log.info('info stream')
log.debug('debug stream')
log.fatal('fatal stream')
t.equal(messageCount, 2)
t.end()
})

test('multistream.add throws if not a stream', function (t) {
try {
pino({
level: 'trace'
}, multistream().add({}))
} catch (_) {
t.end()
}
})

test('multistream throws if not a stream', function (t) {
try {
pino({
level: 'trace'
}, multistream({}))
} catch (_) {
t.end()
}
})

test('flushSync', function (t) {
const tmp = join(
os.tmpdir(),
Expand Down
1 change: 1 addition & 0 deletions test/types/pino-multistream.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ expectType<pino.MultiStreamRes>(pino.multistream(streams))
expectType<pino.MultiStreamRes>(pino.multistream(streams, {}))
expectType<pino.MultiStreamRes>(pino.multistream(streams, { levels: { 'info': 30 } }))
expectType<pino.MultiStreamRes>(pino.multistream(streams, { dedupe: true }))
expectType<pino.MultiStreamRes>(pino.multistream(streams[0]).add(streams[1]))

expectType<pino.MultiStreamRes>(multistream(process.stdout));

0 comments on commit 5d8eb71

Please sign in to comment.