Skip to content

Commit 4b0009e

Browse files
authoredNov 22, 2021
Coerce string integer destinations to file descriptors (#1180)
1 parent 29d24b6 commit 4b0009e

File tree

6 files changed

+51
-8
lines changed

6 files changed

+51
-8
lines changed
 

‎docs/api.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ Default: `pino.destination(1)` (STDOUT)
422422
The `destination` parameter, at a minimum must be an object with a `write` method.
423423
An ordinary Node.js `stream` can be passed as the destination (such as the result
424424
of `fs.createWriteStream`) but for peak log writing performance it is strongly
425-
recommended to use `pino.destination` to create the destination stream.
425+
recommended to use `pino.destination` to create the destination stream.
426426
Note that the `destination` parameter can be the result of `pino.transport()`.
427427
428428
```js
@@ -449,6 +449,10 @@ However, there are some special instances where `pino.destination` is not used a
449449
450450
In these cases `process.stdout` is used instead.
451451
452+
Note: If the parameter is a string integer, e.g. `'1'`, it will be coerced to
453+
a number and used as a file descriptor. If this is not desired, provide a full
454+
path, e.g. `/tmp/1`.
455+
452456
* See [`pino.destination`](#pino-destination)
453457
454458
<a id="metadata"></a>
@@ -1010,7 +1014,7 @@ is flushed and all data synced before the process exits.
10101014
Note that calling `process.exit()` on the main thread will stop the event loop on the main thread from turning. As a result,
10111015
using `console.log` and `process.stdout` after the main thread called `process.exit()` will not produce any output.
10121016
1013-
If you are embedding/integrating pino within your framework, you will need to make pino aware of the script that is calling it,
1017+
If you are embedding/integrating pino within your framework, you will need to make pino aware of the script that is calling it,
10141018
like so:
10151019
10161020
```js

‎docs/transports.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ const transport = pino.transport({
262262
pino(transport)
263263
```
264264
265-
The `options.destination` property may also be a number to represent a file descriptor. Typically this would be `1` to write to STDOUT or `2` to write to STDERR. If `options.destination` is not set, it defaults to `1` which means logs will be written to STDOUT.
265+
The `options.destination` property may also be a number to represent a filedescriptor. Typically this would be `1` to write to STDOUT or `2` to write to STDERR. If `options.destination` is not set, it defaults to `1` which means logs will be written to STDOUT. If `options.destination` is a string integer, e.g. `'1'`, it will be coerced to a number and used as a file descriptor. If this is not desired, provide a full path, e.g. `/tmp/1`.
266266
267267
The difference between using the `pino/file` transport builtin and using `pino.destination` is that `pino.destination` runs in the main thread, whereas `pino/file` sets up `pino.destination` in a worker thread.
268268

‎lib/tools.js

+18-1
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,22 @@ function setMetadataProps (dest, that) {
520520
}
521521
}
522522

523+
/**
524+
* Convert a string integer file descriptor to a proper native integer
525+
* file descriptor.
526+
*
527+
* @param {string} destination The file descriptor string to attempt to convert.
528+
*
529+
* @returns {Number}
530+
*/
531+
function normalizeDestFileDescriptor (destination) {
532+
const fd = Number(destination)
533+
if (typeof destination === 'string' && Number.isFinite(fd)) {
534+
return fd
535+
}
536+
return destination
537+
}
538+
523539
module.exports = {
524540
noop,
525541
buildSafeSonicBoom,
@@ -530,5 +546,6 @@ module.exports = {
530546
createArgsNormalizer,
531547
final,
532548
stringify,
533-
buildFormatters
549+
buildFormatters,
550+
normalizeDestFileDescriptor
534551
}

‎pino.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ const {
1515
final,
1616
buildSafeSonicBoom,
1717
buildFormatters,
18-
noop,
19-
stringify
18+
stringify,
19+
normalizeDestFileDescriptor,
20+
noop
2021
} = require('./lib/tools')
2122
const { version } = require('./lib/meta')
2223
const {
@@ -191,10 +192,10 @@ module.exports = pino
191192

192193
module.exports.destination = (dest = process.stdout.fd) => {
193194
if (typeof dest === 'object') {
194-
dest.dest = dest.dest || process.stdout.fd
195+
dest.dest = normalizeDestFileDescriptor(dest.dest || process.stdout.fd)
195196
return buildSafeSonicBoom(dest)
196197
} else {
197-
return buildSafeSonicBoom({ dest, minLength: 0, sync: true })
198+
return buildSafeSonicBoom({ dest: normalizeDestFileDescriptor(dest), minLength: 0, sync: true })
198199
}
199200
}
200201

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict'
2+
3+
const pino = require('../..')
4+
const transport = pino.transport({
5+
target: 'pino/file',
6+
options: { destination: '1' }
7+
})
8+
const logger = pino(transport)
9+
logger.info('Hello')

‎test/transport/core.test.js

+12
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,18 @@ test('log and exit before ready', async ({ not }) => {
377377
not(strip(actual).match(/Hello/), null)
378378
})
379379

380+
test('string integer destination', async ({ not }) => {
381+
let actual = ''
382+
const child = execa(process.argv[0], [join(__dirname, '..', 'fixtures', 'transport-string-stdout.js')])
383+
384+
child.stdout.pipe(writer((s, enc, cb) => {
385+
actual += s
386+
cb()
387+
}))
388+
await once(child, 'close')
389+
not(strip(actual).match(/Hello/), null)
390+
})
391+
380392
test('pino transport options with target', async ({ teardown, same }) => {
381393
const destination = join(
382394
os.tmpdir(),

0 commit comments

Comments
 (0)
Please sign in to comment.