winston-elasticsearch

repository·master·Indexed 43 days ago

https://github.com/vanthome/winston-elasticsearch

An Elasticsearch transport for winston (v0.19.0) that sends logs to Elasticsearch. It supports Logstash-compatible message structures, date-based indexing, automatic buffering, and Elasticsearch datastreams. Features include the ElasticsearchTransport class for log routing and the ElasticsearchTransformer for reshaping log data into formats optimized for Kibana, as well as integration with elastic-apm-node for correlating logs with APM traces.

Tokens
2.3K
Snippets
7
Records
12
Agent score
4%

What's inside winston-elasticsearch

  1. Use Elasticsearch Datastreams

    master

    For Elasticsearch 7.9 and higher, you can use Datastreams by setting the dataStream option to true.

    When enabled:

    • Bulk indexing uses the create operation instead of index.
    • The default naming convention is logs-*-*, which automatically matches built-in Elasticsearch Index templates and ILM (Index Lifecycle Management) policies.
    • The default datastream name is logs-app-default.

    To use a custom name with the built-in template and ILM policy, set the index option to a value that matches the logs-*-* pattern.

    Note on Fallbacks: If dataStream: true is enabled, but you are using Elasticsearch < 7.9, OR you have provided a custom index name that does not match logs-*-* (and no custom matching template exists in Elasticsearch), the library will fall back to creating a normal index instead of a datastream.

    // Example configuration for Datastreams
    {
      dataStream: true,
      index: 'logs-my-app-production' // Must match logs-*-* to use built-in templates
    }
  2. How the transformer works

    master

    The transformer converts Winston's log data into a shape optimized for Elasticsearch/Kibana.

    Default Behavior: It generates a @timestamp and moves meta properties into a fields object.

    Input Shape (logdata):

    • timestamp (ISO string)
    • level (string)
    • message (string)
    • meta (object)

    Output Shape:

    • @timestamp (ISO string)
    • severity (string, from level)
    • message (string)
    • fields (object, from meta)
  3. Correlate logs with Elastic APM

    master

    To link logs with APM traces, pass the APM client to the apm option in ElasticsearchTransport.

    If you use a custom transformer, you must manually map the APM IDs to ensure Kibana can link them. Add this logic to your transformer:

    if (logData.meta['transaction.id']) transformed.transaction = { id: logData.meta['transaction.id'] };
    if (logData.meta['trace.id']) transformed.trace = { id: logData.meta['trace.id'] };
    if (logData.meta['span.id']) transformed.span = { id: logData.meta['span.id'] };
  4. Configure ElasticsearchTransport options

    master

    The ElasticsearchTransport constructor accepts an options object. Key configuration properties include:

    • level [info]: Minimum severity level for logging.
    • index [none | logs-app-default if dataStream is true]: The target index. Mutually exclusive with indexPrefix.
    • indexPrefix [logs]: Prefix for index names (e.g., <indexPrefix>-<indexSuffixPattern>). Can be a string or a function.
    • indexSuffixPattern [YYYY.MM.DD]: Day.js compatible date/time pattern for index names.
    • transformer: Function to mutate log data before indexing.
    • useTransformer [true]: Enables the transformer (default or custom).
    • ensureIndexTemplate [true]: If true, uploads the indexTemplate to ES on the first log message.
    • indexTemplate: JSON mapping template to be ensured.
    • flushInterval [2000]: Milliseconds between bulk writes.
    • retryLimit [400]: Connection retries before giving up.
    • client: An existing @elastic/elasticsearch client instance. If provided, clientOpts are ignored.
    • clientOpts: Options passed directly to the ES client.
    • buffering [true]: Enables/disables message buffering.
    • bufferLimit [null]: Max number of messages in the buffer.
    • dataStream [false]: Enables Elasticsearch datastreams.
    • apm: An elastic-apm-node client to link logs with APM traces.
    • source: String identifying the origin service.
    • internalLogger [console.error]: Logger used for internal errors.
  5. Integrate APM trace IDs into logs

    master

    If you provide an apm object in the transport options, the transport will automatically extract and attach APM trace information to every log entry.

    It looks for currentTraceIds and maps them to the following fields in the log document:

    • transaction.id $\rightarrow$ transaction.id
    • trace.id $\rightarrow$ trace.id
    • span.id $\rightarrow$ span.id
  6. Customize log indexing with indexInterfix

    master

    You can dynamically route logs to different indices by including an indexInterfix property in your log metadata.

    If dataStream is false, the transport will use the pattern: {indexPrefix}-{indexInterfix}-{dateString}. If dataStream is true, it will use: {dataStreamName}-{indexInterfix}.

    Note: The indexInterfix property is automatically deleted from the log entry before being sent to Elasticsearch to avoid polluting the document.

  7. Extend the default transformer

    master

    You can import ElasticsearchTransformer to extend the default transformation logic within your options.

    const { ElasticsearchTransformer } = require('winston-elasticsearch');
    const esTransportOpts = {
     transformer: (logData) => {
       const transformed = ElasticsearchTransformer(logData);
       transformed.fields.customField = 'customValue';
       return transformed;
     }
    };
    const esTransport = new ElasticsearchTransport(esTransportOpts);
  8. Basic usage of ElasticsearchTransport

    master

    Initialize ElasticsearchTransport with an options object and add it to a Winston logger.

    Important: You must implement error handling for both the logger and the esTransport instance to catch and handle errors effectively.

    const winston = require('winston');
    const { ElasticsearchTransport } = require('winston-elasticsearch');
    
    const esTransportOpts = {
      level: 'info'
    };
    const esTransport = new ElasticsearchTransport(esTransportOpts);
    const logger = winston.createLogger({
      transports: [
        esTransport
      ]
    });
    
    // Compulsory error handling
    logger.on('error', (error) => {
      console.error('Error in logger caught', error);
    });
    esTransport.on('error', (error) => {
      console.error('Error in logger caught', error);
    });
  9. Use ElasticsearchTransport for Winston logging

    master

    The ElasticsearchTransport class is a Winston transport that sends log entries to Elasticsearch. It supports buffering for performance, automatic index template management, and data stream support. You can provide your own @elastic/elasticsearch client or let the transport create one using clientOpts.

    const winston = require('winston');
    const { ElasticsearchTransport } = require('winston-elasticsearch');
    
    const logger = winston.createLogger({
      transports: [
        new ElasticsearchTransport({
        // configuration options
        })
      ]
    });
  10. Use ElasticsearchTransformer to format logs

    master

    The ElasticsearchTransformer (exported as ElasticsearchTransformer) is the default function used to reshape log data. It extracts message, level, and timestamp from the Winston info object and moves all other properties into a meta object.

    If useTransformer is set to true, the log entry sent to Elasticsearch will follow this structure:

    {
      "message": "...",
      "level": "...",
      "timestamp": "...",
      "meta": { "key": "value" }
    }
    const { ElasticsearchTransformer } = require('winston-elasticsearch');
    
    // Example of a custom transformer
    const myTransformer = (logData) => {
      return {
        ...logData,
        custom_field: 'added_value'
      };
    };
    
    // Usage in transport
    new ElasticsearchTransport({
      transformer: myTransformer,
      useTransformer: true
    });