Skip to content

Robust and simple Winston transport for AWS CloudWatch Logs

License

Notifications You must be signed in to change notification settings

mifi/cloudwatch-winston

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cloudwatch-winston

Robust and simple Winston transport for AWS CloudWatch Logs

Features

  • Tries very hard to deliver messages, even in case of errors
  • Does not fail or break when losing internet connection
  • Does not implement the complex and error-prone sequence token logic (no longer needed)
  • Follows AWS strict logging rules
  • Truncates long messages (handling UTF-8 characters correctly)
  • Customisable memory buffer size, prevents memory overrun by dropping logs when queue is full
  • Logs to CloudWatch when messages have been truncated or dropped due to full queue
  • Passes actual log timestamps to CloudWatch
  • Cleans up resources when Winston closes the Transport
  • Auto-creates log group and stream (optional)
  • AWS SDK v3

Usage

import CloudWatchTransport from 'cloudwatch-winston';
import { format } from 'node:util';

const cloudWatchTransport = new CloudWatchTransport({
  logGroupName: 'my-log-group',
  logStreamName: new Date().toISOString().replace(/[-:]/g, '/'),
  shouldCreateLogGroup: false,
  shouldCreateLogStream: true,
  aws: {
    credentials: {
      accessKeyId: '',
      secretAccessKey: '',
    },
    region: 'us-east-1',
  },
  formatLog: (item) => `${item.level}: ${item.message}`,
});


// https://github.com/winstonjs/winston/issues/1427
const combineMessageAndSplat = () => ({
  transform(info) {
    const { [Symbol.for('splat')]: args = [], message } = info;
    info.message = format(message, ...args);
    return info;
  },
});

const logger = winston.createLogger({
  format: winston.format.combine(
    winston.format.timestamp(),
    combineMessageAndSplat(),
    winston.format.simple(),
  ),
});

logger.add(cloudWatchTransport);

// When you call close on the logger, it will automatically close the transport and clean up
// logger.close()

Options

{
  aws: {
    credentials: { // required
      accessKeyId: '',
      secretAccessKey: '',
    },
    region: '',
  },
  logGroupName: '', // required
  logStreamName: '', // required

  // whether to auto create the log group
  shouldCreateLogGroup: false,

  // whether to auto create the log stream
  shouldCreateLogStream: true,

  // handle non-fatal errors
  onError: (err) => console.error(err),

  // customise how to format log messages
  formatLog: ({ level, message }) => `${level}: ${message}`,

  // a function that allows to you provide custom timestamp for log entries sent to CloudWatch. Must return number of milliseconds since epoch. Default: use `timestamp` metadata provided by `winston.format.timestamp()`
  getTimestamp: ({ timestamp }) => +new Date(),

  // minimum interval between batch requests sent to AWS (don't set too low!)
  minInterval: 2000,

  // max number of pending batches - once this limit is exceeded, log calls will be dropped. Note that each batch can have up to 10k messages and a total of about 1MB.
  maxQueuedBatches: 100,

  // Text to append to truncated message. Set to empty string to disable.
  truncatedMessageSuffix: ' TRUNCATED',

  // If maxQueuedBatches is exceeded, we will send queueOverrunMessage to CloudWatch Logs *once*, until queue has returned to normal again. Set to empty string to disable this behavior.
  queueOverrunMessage: 'Log queue overrun',

  // Whether to abandon any remaining queued batches when the transport closes, or retry them until delivered
  abandonQueueOnClose: true,
}

Example

test.mjs

DEBUG=CloudWatchTransport,CloudWatchTransport:* node test.mjs

TODO

  • Max retries option?
  • Types

Alternatives

  • Seems to work ok, however simply stops working when there's a loss of internet connection
  • Unmaintained
  • AWS SDK v2
  • Doesn't adhere to AWS strict logging rules
  • Most popular
  • Unmaintained
  • Haven't tested
  • Many issues
  • Many dependencies
  • Code is a bit hard to follow

Release

np

About

Robust and simple Winston transport for AWS CloudWatch Logs

Resources

License

Stars

Watchers

Forks

Packages

No packages published