diff --git a/docs/transports.md b/docs/transports.md index e9adcc051..1acc5451f 100644 --- a/docs/transports.md +++ b/docs/transports.md @@ -240,6 +240,17 @@ const transport = pino.transport({ pino(transport) ``` +By default, the `pino/file` transport assumes the directory of the destination file exists. If it does not exist, the transport will throw an error when it attempts to open the file for writing. The `mkdir` option may be set to `true` to configure the transport to create the directory, if it does not exist, before opening the file for writing. + +```js +const pino = require('pino') +const transport = pino.transport({ + target: 'pino/file', + options: { destination: '/path/to/file', mkdir: true } +}) +pino(transport) +``` + 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. 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. diff --git a/file.js b/file.js index 7968c1945..a75366164 100644 --- a/file.js +++ b/file.js @@ -4,7 +4,9 @@ const pino = require('./pino') const { once } = require('events') module.exports = async function (opts = {}) { - const destination = pino.destination({ dest: opts.destination || 1, sync: false }) + const destOpts = { dest: opts.destination || 1, sync: false } + if (opts.mkdir) destOpts.mkdir = true + const destination = pino.destination(destOpts) await once(destination, 'ready') return destination } diff --git a/test/transport/core.test.js b/test/transport/core.test.js index c307ed9c4..a08e98e7a 100644 --- a/test/transport/core.test.js +++ b/test/transport/core.test.js @@ -279,6 +279,27 @@ test('pino.transport with target pino/file', async ({ same, teardown }) => { }) }) +test('pino.transport with target pino/file and mkdir option', async ({ same, teardown }) => { + const folder = '_' + Math.random().toString(36).substr(2, 9) + const destination = join(os.tmpdir(), folder, folder) + const transport = pino.transport({ + target: 'pino/file', + options: { destination, mkdir: true } + }) + teardown(transport.end.bind(transport)) + const instance = pino(transport) + instance.info('hello') + await watchFileCreated(destination) + const result = JSON.parse(await readFile(destination)) + delete result.time + same(result, { + pid, + hostname, + level: 30, + msg: 'hello' + }) +}) + test('pino.transport with target pino-pretty', async ({ match, teardown }) => { const destination = join( os.tmpdir(),