pino-elasticsearch

repository·master·Indexed 41 days ago

https://github.com/pinojs/pino-elasticsearch

A transport and CLI tool for loading Pino logs into Elasticsearch. Version 9.0.0 allows users to pipe logs via a CLI or integrate it as a Node.js module using pinoElastic(). It supports authentication via API keys or username/password, custom index naming, and integration with pino.transport for multi-stream logging.

Tokens
4.7K
Snippets
16
Records
19
Agent score
51%

What's inside pino-elasticsearch

  1. Handle stream events for debugging

    master

    The stream handler returned by pinoElastic() is an EventEmitter. You can listen to specific events to debug why logs might not be appearing in Elasticsearch.

    EventCallback SignatureDescription
    unknown(line: string, error: string) => voidReceived event is unparsable (JSON.parse failed). Often happens if using pino-pretty on the stream.
    insertError(error: Error & { document: Record<string, any> }) => voidBulk insert failed (records dropped). Use this to check for schema/mapping mismatches.
    insert(stats: Record<string, any>) => voidSuccessful insert performed.
    error(error: Error) => voidGeneral Elasticsearch client failure.
    const pinoElastic = require('pino-elasticsearch');
    
    const streamToElastic = pinoElastic({
      index: 'an-index',
      node: 'http://localhost:9200',
      esVersion: 7,
      flushBytes: 1000
    })
    
    streamToElastic.on('<event>', (error) => console.log(event));
  2. Set up Elasticsearch and Kibana for testing

    master

    You can use the bundled docker-compose.yml file to quickly spin up a local environment containing both Elasticsearch and Kibana.

    Prerequisites:

    Steps:

    1. Navigate to the project folder.
    2. Run the following command to launch the services:
      docker-compose -f docker-compose-v8.yml up
    docker-compose -f docker-compose-v8.yml up
  3. Send Pino logs to Elasticsearch via CLI

    master

    You can pipe Pino logs directly into the pino-elasticsearch CLI to stream them to an Elasticsearch instance. This is useful for processing log files or piping output from a running process.

    cat log | pino-elasticsearch --node http://localhost:9200
  4. Authenticate with Elasticsearch

    master

    You can authenticate using several methods:

    1. Via CLI (URL, Username/Password, or API Key):

    # Using URL credentials
    cat log | pino-elasticsearch --node https://user:pwd@localhost:9200
    
    # Using username and password flags
    cat log | pino-elasticsearch --node https://localhost:9200 -u user -p pwd
    
    # Using API key flag
    cat log | pino-elasticsearch --node https://localhost:9200 --api-key=base64EncodedKey

    2. Via Module Configuration:

    Use the auth object in the configuration. If both username/password and apiKey are provided, apiKey takes precedence.

    // Basic Auth
    const streamToElastic = pinoElastic({
      index: 'an-index',
      node: 'http://localhost:9200',
      auth: {
        username: 'user',
        password: 'pwd'
      }
    })
    
    // API Key Auth
    const streamToElastic = pinoElastic({
      index: 'an-index',
      node: 'http://localhost:9200',
      auth: {
        apiKey: 'apikey123'
      }
    })
  5. Configure Elastic Common Schema (ECS) support

    master

    To use ECS, do not use the ecs option in pino-elasticsearch (it has been removed). Instead, use the @elastic/ecs-pino-format package to format the logs before they reach the Elasticsearch stream.

    const pino = require('pino')
    const ecsFormat = require('@elastic/ecs-pino-format')()
    const pinoElastic = require('pino-elasticsearch')
    
    const streamToElastic = pinoElastic({
      index: 'an-index',
      node: 'http://localhost:9200',
      esVersion: 7,
      flushBytes: 1000
    })
    
    const logger = pino({ level: 'info', ...ecsFormat() }, streamToElastic)
    
    logger.info('hello world')
  6. Output to multiple streams using pino.transport

    master

    To log to both the console and Elasticsearch simultaneously, use pino.transport. Note that the options object provided to the target must be serializable (e.g., do not pass functions as values).

    const pino = require('pino');
    
    const pinoOptions = {};
    
    return pino(pinoOptions, pino.transport({
      targets: [
        { 
          target: 'pino/file', // This will log to stdout
        }, 
        { 
          target: 'pino-elasticsearch',
          options: {
            index: 'an-index',
            node: 'http://localhost:9200',
            esVersion: 7,
            flushBytes: 1000
          }
        }
      ]
    }));
  7. Use the pino-elasticsearch CLI to pipe logs to Elasticsearch

    master

    The pino-elasticsearch CLI acts as a transport stream that reads JSON logs from stdin and sends them to an Elasticsearch instance. You can pipe logs from pino directly into this CLI.

    Basic Usage

    node path/to/cli.js | pino > logs.json
    pino-elasticsearch < logs.json

    Configuration via File

    You can load configuration settings from a .json or .js file using the --read-config (or -r) flag. This is useful for managing complex connection settings without long command-line strings.

    pino-elasticsearch --read-config config.json
    pino-elasticsearch < logs.json
  8. Test pino-elasticsearch with the provided example

    master

    To verify your installation and ensure the transport is working correctly with a local Elasticsearch instance, you can run the included example script and pipe its output to pino-elasticsearch.

    Prerequisites:

    • pino-elasticsearch must be installed globally.
    • An Elasticsearch instance must be running (e.g., via the docker-compose setup).

    Steps:

    1. Navigate to the project folder.
    2. Run the example script and pipe it to the transport:
      node example | pino-elasticsearch
    node example | pino-elasticsearch
  9. Use pino-elasticsearch as a module

    master

    Integrate pino-elasticsearch directly into your Node.js application by passing the stream returned by pinoElastic() to the pino logger.

    const pino = require('pino')
    const pinoElastic = require('pino-elasticsearch')
    
    const streamToElastic = pinoElastic({
      index: 'an-index',
      node: 'http://localhost:9200',
      esVersion: 7,
      flushBytes: 1000
    })
    
    const logger = pino({ level: 'info' }, streamToElastic)
    
    logger.info('hello world')
  10. Configure a custom Connection class

    master

    When using the module, you can pass a custom Elasticsearch Connection class via the Connection option to customize low-level client behavior.

    const pino = require('pino')
    const pinoElastic = require('pino-elasticsearch')
    
    const Connection = <custom Connection>
    
    const streamToElastic = pinoElastic({
      index: 'an-index',
      node: 'http://localhost:9200',
      esVersion: 7,
      flushBytes: 1000,
      Connection
    })
    
    const logger = pino({ level: 'info' }, streamToElastic)
    
    logger.info('hello world')