Skip to content

Commit

Permalink
feature: allow sync flag to be passed to ThreadStream for synchronous… (
Browse files Browse the repository at this point in the history
#2063)

* feature: allow sync flag to be passed to ThreadStream for synchronous logging

* tests: add unit tests for sync true to ThreadStream

* tests: fix unit test

* tests: fix unit test
  • Loading branch information
karankraina authored Oct 15, 2024
1 parent f220965 commit 5bc0a92
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 5 deletions.
15 changes: 14 additions & 1 deletion docs/transports.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ now referred to as [Legacy Transports](#legacy-transports).

From Pino v7 and upwards transports can also operate inside a [Worker Thread][worker-thread]
and can be used or configured via the options object passed to `pino` on initialization.
In this case the transports would always operate asynchronously, and logs would be
In this case the transports would always operate asynchronously (unless `options.sync` is set to `true` in transport options), and logs would be
flushed as quickly as possible (there is nothing to do).

[worker-thread]: https://nodejs.org/dist/latest-v14.x/docs/api/worker_threads.html
Expand Down Expand Up @@ -124,6 +124,19 @@ const transport = pino.transport({
pino(transport)
```
To make pino log synchronously, pass `sync: true` to transport options.
```js
const pino = require('pino')
const transport = pino.transport({
targets: [
{ target: '/absolute/path/to/my-transport.mjs', level: 'error' },
],
dedupe: true,
sync: true,
});
pino(transport);
```
For more details on `pino.transport` see the [API docs for `pino.transport`][pino-transport].
[pino-transport]: /docs/api.md#pino-transport
Expand Down
9 changes: 5 additions & 4 deletions lib/transport.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ function setupOnExit (stream) {
})
}

function buildStream (filename, workerData, workerOpts) {
function buildStream (filename, workerData, workerOpts, sync) {
const stream = new ThreadStream({
filename,
workerData,
workerOpts
workerOpts,
sync
})

stream.on('ready', onReady)
Expand Down Expand Up @@ -71,7 +72,7 @@ function flush (stream) {
}

function transport (fullOptions) {
const { pipeline, targets, levels, dedupe, worker = {}, caller = getCallers() } = fullOptions
const { pipeline, targets, levels, dedupe, worker = {}, caller = getCallers(), sync = false } = fullOptions

const options = {
...fullOptions.options
Expand Down Expand Up @@ -126,7 +127,7 @@ function transport (fullOptions) {

options.pinoWillSendConfig = true

return buildStream(fixTarget(target), options, worker)
return buildStream(fixTarget(target), options, worker, sync)

function fixTarget (origin) {
origin = bundlerOverrides[origin] || origin
Expand Down
55 changes: 55 additions & 0 deletions test/transport/syncTrue.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict'

const pino = require('../..')
const { join } = require('node:path')
const { readFileSync } = require('node:fs')
const { test } = require('tap')
const { file } = require('../helper')

test('thread-stream sync true should log synchronously', async (t) => {
const outputPath = file()

function getOutputLogLines () {
return (readFileSync(outputPath)).toString().trim().split('\n').map(JSON.parse)
}

const transport = pino.transport({
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
options: { destination: outputPath, flush: true },
sync: true
})
const instance = pino(transport)

var value = { message: 'sync' }
instance.info(value)
instance.info(value)
instance.info(value)
instance.info(value)
instance.info(value)
instance.info(value)
let interrupt = false
let flushData
let loopCounter = 0

// Start a synchronous loop
while (!interrupt && loopCounter < (process.env.MAX_TEST_LOOP_ITERATION || 20000)) {
try {
loopCounter++
const data = getOutputLogLines()
flushData = data
if (data) {
interrupt = true
break
}
} catch (error) {
// File may not exist yet
// Wait till MAX_TEST_LOOP_ITERATION iterations
}
}

if (!interrupt) {
throw new Error('Sync loop did not get interrupt')
}

t.equal(flushData.length, 6)
})

0 comments on commit 5bc0a92

Please sign in to comment.