Giter VIP home page Giter VIP logo

lesslog's Introduction

lesslog

Zero-dependency, teeny-tiny and serverless-ready logging utility for Node.js.

In most serverless environments log ingestion comes at a cost. And more often than not, those logs are not even looked at for most of the times. Until something goes bad and crucial debugging information is not available, as it was filtered to save on log ingestions.

Using lesslog, debug information is not logged immediately, but buffered internally. Once an error is logged any buffered logs will be emitted, preserving their original timestamp and context. No debug information is lost, while still maintaining clutter-free logs the rest of the time.

AWS Lambda & CloudWatch

lesslog was created with AWS Lambda in mind and its default logging format is optimized for Amazon CloudWatch. As Lambda functions are reused as much as possible, clear must be called at the end of each Lambda execution to prevent the internal buffers to bloat and carry over log messages from previous executions. To resemble Lambda's default log message format, tag must be used at the very beginning of each execution, to add the awsRequestId to the logs.

Note: If you use Middy, check out middy-lesslog as well!

Installation

$ npm install lesslog

Usage

import log from "lesslog";

log.label = "70e505ba-ad84-4816-82ec-f2a1ed4303ca";

log.debug("Debug message", { with: "additional", information: true });
log.info("Uncritical exceptional information", ["maybe", "an", "array", "?"]);
log.warn("Potentially critical warning", {
  tokenExpired: true,
  user: { id: 42 },
});
log.error("‾\\_(ツ)_/‾", {
  error: { message: error.message },
  user: { id: 42 },
});

log.debug("Yet another debug message");
log.clear();

Running the above code, will result in the following log messages:

2038-01-19T03:14:07.998Z  70e505ba-ad84-4816-82ec-f2a1ed4303ca  INFO  Uncritical exceptional information ["maybe","an","array","?"]
2038-01-19T03:14:07.999Z  70e505ba-ad84-4816-82ec-f2a1ed4303ca  WARN  Potentially critical warning {"tokenExpired":true,"user":{"id":42}}
2038-01-19T03:14:07.997Z  70e505ba-ad84-4816-82ec-f2a1ed4303ca  DEBUG  Debug message {"with":"additional","information":true}
2038-01-19T03:14:08.000Z  70e505ba-ad84-4816-82ec-f2a1ed4303ca  ERROR  ‾\_(ツ)_/‾ {"error":{"message":"Original error message"},"user":{"id":42}}

Note that the last debug log is not emitted, since error is not called afterwards.

API

lesslog exports a default Log instance that exposes the following methods:

.clear() => void

Discards the entire internal buffer.

Must be called whenever error is not invoked and the previous debug messages can be discarded to prevent the internal buffers from bloating.

.flush() => void

Flushes all internally buffered logs to process.env.stdout.

.debug(message: string, context?: LogContext) => void

Stores a log message in the internal buffer with a DEBUG log level.

If the DEBUG environment variable is set to either '1', 'on', 'true', or 'yes', the log message will not be stored and instead written to process.env.stdout directly.

.info(message: string, context?: LogContext) => void

Writes a log message to process.env.stdout with an INFO log level.

warn(message: string, context?: LogContext) => void

Writes a log message to process.env.stderr with a WARN log level.

error(message: string, context?: LogContext) => void

Writes a log message to process.env.stderr with an ERROR log level after flushing all internally buffered logs to process.env.stdout.

.context

Get and set the default context for the Log instance.

The default context will be merged with the context passed to the Log methods above, potentially overriding properties in the default context.

.label

Get and set the log label for the Log instance.

Advanced Usage

import { ILogEntry, Log } from "lesslog";

function format({
  context,
  label,
  level,
  message,
  timestamp,
}: ILogEntry): string {
  const isoString = new Date(timestamp).toISOString();
  const metrics = [
    message,
    context.sumQueryCount,
    context.avgQueryDuration,
    context.dbClusterInstance,
  ];

  return `${isoString}\t${label}\t${level}\t${metrics.join("|")}`;
}

const log = new Log(format);

log.label = "14968fcb-6481-46d8-a068-b97d4be47852";

log.info("DBQueryMetrics", {
  sumQueryCount: 42,
  avgQueryDuration: 0.618,
  dbClusterInstance: "readreplica",
});

Running the above code, will result in the following log messages:

2038-01-19T03:14:08.000Z  14968fcb-6481-46d8-a068-b97d4be47852  INFO  DBQueryMetrics|42|0.618|readreplica

new Log(format?: LogFormatFunction) => Log

Creates and returns a new log instance with a custom log formatting function.

The formatting function is invoked for every log entry with an object containing the following properties and is expected to return a string:

Argument Type Description
context object The log context merged with the default context
label string The log label set on the Log instance
level string The log level of the invoked log function
message string Log message passed to the log function
timestamp number Milliseconds since 1970-01-01T00:00:00.000Z

lesslog's People

Contributors

robdasilva avatar dependabot[bot] avatar

Stargazers

Andrejs Agejevs avatar Cesar Canassa avatar Luky Walker avatar JPL avatar Arshin Albab avatar Grant Jordan avatar Kasey Culmback avatar Sebastian Hesse avatar Jacob B. Sanders avatar Ryan Lewis avatar Livio Bieri avatar Leechael avatar James Anthony Bruno avatar Chris Hoyle avatar Eric Bailey avatar Richard Hurt avatar Viyat Gandhi avatar Jan Hecking avatar Jaypee Ignacio avatar Matt Mοllica avatar Simon Babay avatar Armando Lüscher avatar Emmanuel Salomon avatar Andrew Chou avatar Aral Balkan avatar Tim Redding avatar Kirill Khoroshilov avatar Charles Szilagyi avatar Sanjay Prajapati avatar Luciano Mammino avatar  avatar Oscar Franco avatar

Watchers

 avatar  avatar Kasey Culmback avatar

Forkers

thekarel jbreckel

lesslog's Issues

CloudWatch orders logs by their received time, not the timestamp in the log line

This may be more of a question than an issue with this library. I wasn't able to find any answers elsewhere, so maybe you can help. When buffered debug logs are flushed and sent to CW a timestamp is attached to that event at the time it's pushed to CW, and that is the timestamp CW will show in its "timestamp" column, and what it sorts by.

When using the CW console to view logs, is there a method to create the log events with the timestamp from the message?

Incorrect sequence

Why does the first debug message come out 3rd in the output?
The time sequence is incorrect, which causes confusion as to the order of events.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.