Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Recommended setup for production #1491

Open
david-szabo97 opened this issue Jul 10, 2022 · 4 comments
Open

Recommended setup for production #1491

david-szabo97 opened this issue Jul 10, 2022 · 4 comments

Comments

@david-szabo97
Copy link

The documentation contains a mixed use of pino.transport, pino.destination, pino.multistream, and Pino created without arguments. Legacy vs Pino v7+ transports is also confusing.

What's the recommended setup for production? Production = least overhead, best performance, logging to stdout

My first guess would be

const logger = pino(pino.destination());

After reading the documentation, I've found a paragraph:

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.

This makes pino.destination a wrong choice because it runs in the main thread. Therefore to get the best performance out of Pino we must use v7+ transports.

In our case we want to log to stdout, therefore we create a pino/file transport:

const transport = pino.transport({
  target: "pino/file",
});

const logger = pino(transport);

Having a section in the documentation about running Pino in production would be great. Unfortunately, there are too many options at the moment, which can confuse new users of Pino (or even existing users like myself).

@mcollina
Copy link
Member

The default settings are defined to work well in your simple production setup. You don't need to tweak anything.

All the above are required if you have more sophisticated requirements.

Would you like to send a PR to clarify this further in our docs?

@david-szabo97
Copy link
Author

david-szabo97 commented Jul 11, 2022

By default settings you mean this, right?

const logger = pino();

According to the documentation, the default destination is pino.destination(1).
So the above is equivalent to the following:

const logger = pino(pino.destination(1));

As far as I understand, pino.destination runs on the main thread in this case. So the following should perform better because the logging is delegated to a worker thread:

const transport = pino.transport({
  target: "pino/file",
});

const logger = pino(transport);

Benchmark - based on the basic-bench.js - seems to agree with my assumptions:

benchPino*10000: 372.211ms
benchPinoMinLength*10000: 132.718ms
benchPinoNodeStream*10000: 417.469ms
benchPDestinationDevNull*10000: 346.205ms
benchPfile*10000: 77.384ms

benchPDestinationDevNull = pino(pino.destination("/dev/null"))
benchPfile = pino(pino.transport({ target: "pino/file", options: { destination: "/dev/null" } }))
Rest is the same as in basic-bench.js, all goes to /dev/null

/dev/null is messing up the benchmark?

Instead of sending the logs to /dev/null, I sent them to process.stdout. I've also redirected the output to a file.

Command: node bench.js > bench.log

Loggers:
benchPDestination = pino()
benchPfile = pino(pino.transport({ target: "pino/file" }))

Results

benchPDestination*10000: 82.929ms
benchPfile*10000: 79.111ms

Looks like both take the same amount of time when printing to stdout. Ran the benchmark multiple times and it's head-to-head all the time. Sometimes one wins with 10%, sometimes the other win with 10%. Therefore we can take this as a draw.

Question

Are there any benefits of using the pino/file transport over using pino.destination when logging to the stdout stream? (basically worker thread VS main thread?)

Would it make sense to recommend pino/file over pino.destination in production?

IMO, pino/file should be a better choice in production because the logging happens in the worker thread entirely. On the other hand, it might be unnecessary because the destination is stdout.

EDIT: Yes, I'm overthinking this 😄 I'm not worrying about performance, I'm driven by curiosity.

@mcollina
Copy link
Member

Are there any benefits of using the pino/file transport over using pino.destination when logging to the stdout stream? (basically worker thread VS main thread?)

No. This just adds more overhead due to moving the data off the main thread. However this is available for people that want to log to multiple destinations, e.g. to elastic search and to a file. In that case the file transport is useful.

Would it make sense to recommend pino/file over pino.destination in production?

No.

Yes, I'm overthinking this 😄 I'm not worrying about performance, I'm driven by curiosity.

Indeed! But curiosity is great!

@janeklb
Copy link
Contributor

janeklb commented Nov 6, 2022

No. This just adds more overhead due to moving the data off the main thread. However this is available for people that want to log to multiple destinations, e.g. to elastic search and to a file. In that case the file transport is useful.

I was looking for this exact bit of information. From reading the documentation, it was not clear that the default mode (const logger = require('pino')()) yields the best performance for basic / stdout-only logging. I re-read the transports docs a few times thinking that I must have missed something.

Having said all that...

Would you like to send a PR to clarify this further in our docs?

I tried to think about how to fit this into the docs as they stand, and was not able to come up with a good solution. Maybe, simply, an entry to help?

janeklb added a commit to janeklb/pino that referenced this issue Nov 6, 2022
mcollina added a commit that referenced this issue May 8, 2023
* docs: add 'best performance for basic stdout logging' to help.md

My attempt to capture @mcollina's reply: #1491 (comment) in some doc form

* change help section

* Update docs/help.md

Co-authored-by: Matteo Collina <matteo.collina@gmail.com>

* Update docs/help.md

Co-authored-by: Matteo Collina <matteo.collina@gmail.com>

---------

Co-authored-by: Matteo Collina <matteo.collina@gmail.com>
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

3 participants