log-report logo

log-report

Lightweight Node.js logging with ECS-style fields, file rotation, optional HTTP output, and zero-dependency runtime API.

๐Ÿ“š Table of Contents


โœจ Features

Back to top โ†‘


๐Ÿ“ฆ Installation

Available on npm

npm install log-report

Back to top โ†‘


๐Ÿš€ Quick start

  1. Load the module (installs handlers based on settings)
const createLogger = require('log-report');
  1. Create a service logger
const log = createLogger('app');
  1. Emit logs
log.info('Application started', { env: process.env.NODE_ENV });
log.debug('Cache primed', { entries: 42 });
log.warn('Disk space low', { percentFree: 7 });
log.error(new Error('Something went wrong'));
log.trace('db.query', { sql: 'SELECT 1' });        // visible in 'dev' or 'combined'
log.fatal('Cannot continue', { code: 'E_FATAL' }); // also goes to exception log
  1. (Optional) Clear log files on startup
createLogger.clearLogFiles();

Back to top โ†‘


โš™๏ธ Configuration

Possibilitys:

  1. Create a logger instance with options:
const createLogger = require('log-report');
const log = createLogger('payments', {
    logMode: 'dev',                         // includes dev-style logs so trace is visible
    outputJSON: false,                      // human-readable text mode
    baseFields: {
        'ECS.version': '1.12.0',            // ECS version
        service: { name: 'payment-service' }// ECS service.name
    },
    saveOnlyUncaughtException: false,       // enable stdout/stderr hooks
    logDir: './logs/log-report',
    clearOnStartup: true,                   // start clean
    addProcessTag: true,                    // adds process.pid
    addFileTag: true,                       // adds log.origin.file.name
    silent: false                           // also print to console
});
// Example logs
log.info('Payment service started');
log.trace('db.query', { sql: 'SELECT * FROM orders' });
log.error(new Error('Database connection failed'));
log.fatal('Cannot continue', { code: 'E_FATAL' });
log.trace('user.login', { userId: 12345, traceId: 'abcde12345' }); // trace helper
log.trace('cache.miss', 'Cache miss for user 12345', { key: 'user_12345' }); // with value
  1. Use default settings and modify as needed:
const createLogger = require('log-report');
const log = createLogger('app'); // uses default settings
log.info('App started');
  1. Settings are runtime getters/setters on the exported function:
const logReport = require('log-report');
// Modes: 'none' | 'short' | 'dev' | 'combined' 
logReport.logMode = 'dev';
logReport.outputJSON = true;                  // JSON vs text 
logReport.outputUri = 'http://localhost:5985/log-report'; // optional HTTP endpoint 
logReport.logDir = './logs/log-report';
logReport.stdoutFileName = 'stdout.log'; 
logReport.stderrFileName = 'stderr.log'; 
logReport.exceptionFileName = 'exception.log';
logReport.clearOnStartup = true; 
logReport.saveOnlyUncaughtException = false;  // if true, stdout/stderr hooks are not attached 
logReport.addProcessTag = true; 
logReport.addFileTag = true; 
logReport.silent = false;                     // print to console 
logReport.loggingEnabled = true;              // file logging on/off 
logReport.compressEnabled = true;             // gzip rotation over ~1MB
// Utility 
logReport.clearLogFiles();
  1. Loggers can also be created with config sets (config-sets.json):

Install config-sets:

npm install config-sets

Then use in your app:

const configSets = require('config-sets');
const createLogger = require('log-report');
const log = createLogger('orders', configSets('log-report'));
// Example logs
log.info('Order service started');
log.trace('db.query', { sql: 'SELECT * FROM orders' });
log.error(new Error('Database connection failed'));
log.fatal('Cannot continue', { code: 'E_FATAL' });
log.trace('user.login', { userId: 12345, traceId: 'abcde12345' }); // trace helper
log.trace('cache.miss', 'Cache miss for user 12345', { key: 'user_12345' }); // with value

Tip: values also integrate with config-sets (config-sets.json) under the log-report key.

Example config-sets.json:

{
  /* Set to true to use production settings, */
  /* false for development settings. Default is true. */
  "isProduction": true,
  /* Settings used in production mode. */
  /* These settings are saved to "config-sets.json" file. */
  "production": {
    /* 'log-report' settings */
    "log-report": {
      /* Log mode. Default: 'short' */
      /* Example values: 'none', 'short', 'dev', 'combined' */
      /* 'none' = disable all logging except uncaughtException to exception.log */
      /* 'short' = info, warn, error, fatal to respective files (stdout.log, stderr.log, exception.log) */
      /* 'dev' = like 'short' but also includes debug and trace to stdout.log (for development) */
      /* 'combined' = like 'dev' but also includes http info (if provided in log.trace) to stdout (logs all) */
      /* 'dev' and 'combined' are verbose and may include sensitive information, use with caution in production. */
      "logMode": "short",
      /* Output format. Default: true (true = JSON format, false = text format) */
      /* If false, the output format will be a human-readable text format. */
      /* This is useful for development or debugging, but not recommended for production. */
      "outputJSON": true,
      "baseFields": {},
      /* Output URI. Default: '' (e.g. 'http://localhost:3000/logs') */
      /* If set, logs will be sent to the specified URI via HTTP POST in JSON format. */
      /* Ensure that the URI is reachable and can accept POST requests with JSON payloads. */
      /* If empty, logs will only be written to log files. */
      "outputUri": "",
      /* Specifies the directory where logs will be saved. Default: './logs/log-report' */
      /* Ensure that the directory exists or the application has permission to create it. */
      /* Relative paths are resolved against the current working directory. */
      /* Absolute paths are used as-is. (e.g. '/var/log/myapp') */
      "logDir": "./logs/log-report",
      /* Specify appropriate log file names. Default: 'stdout.log' */
      "stdoutFileName": "stdout.log",
      /* Specify appropriate log file names. Default: 'stderr.log' */
      "stderrFileName": "stderr.log",
      /* Specify appropriate log file names. Default: 'exception.log' */
      "exceptionFileName": "exception.log",
      /* This is useful if you want to start with fresh log files, */
      /* especially during development or testing. Default: true */
      "clearOnStartup": true,
      /* This is useful if you only want information about Uncaught Exception. Default: false */
      "saveOnlyUncaughtException": true,
      /* This is useful if you want to get information about the PID of a process, */
      /* especially during development or testing. Default: false */
      /* Note: In clustered environments, multiple processes may write to the same log file. */
      /* Consider using 'addFileTag' for better traceability. */
      "addProcessTag": false,
      /* This is useful if you want to get information about the file that started the process, */
      /* especially during development or testing. Default: false */
      /* Note: In clustered environments, multiple processes may write to the same log file. */
      /* This adds the 'log.origin.file.name' field to each log entry. */
      "addFileTag": false,
      /* Suppresses terminal output when set to true. Default: false */
      /* When false, log messages will be printed to the console in addition to being saved to log files. */
      /* When true, log messages will only be saved to log files. */
      "silent": false,
      /* Enable or disable logging. Default: true */
      /* When false, no logs will be written to files, but uncaught exceptions will still be handled. */
      /* This can be useful for temporarily disabling logging without changing other settings. */
      "loggingEnabled": true,
      /* Enable or disable gzip rotation over 1MB. Default: true */
      /* When true, log files exceeding 1MB will be compressed using gzip to save disk space. */
      /* When false, log files will grow indefinitely unless manually managed. */
      "compressEnabled": true
    }
  },
  /* Settings used in development mode. */
  /* These settings are not saved to file and are created from production settings. */
  /* You can override these settings using command line arguments. */
  /* Set only the settings you want to change. */
  "development": {}
}

Back to top โ†‘


๐Ÿ—บ๏ธOutput formats

Two formats are supported:

Example JSON (abbreviated):

{ "@timestamp": "2025-01-01T12:00:00.000Z", "service.name": "app", "log.logger": "app", "log.level": "info", "message": "Application started", "event.kind": "event", "event.dataset": "app.stdout", "labels": { "env": "production" } }

Example text (abbreviated):

[2025-01-01T12:00:00.000Z] [info] Application started env=production
[2025-01-01T12:00:01.000Z] [debug] Cache primed entries=42
[2025-01-01T12:00:02.000Z] [warn] Disk space low percentFree=7
[2025-01-01T12:00:03.000Z] [error] Something went wrong Error: Something went wrong
    at Object.<anonymous> (/path/to/file.js:10:15)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    ...
[2025-01-01T12:00:04.000Z] [trace] db.query sql=SELECT 1
[2025-01-01T12:00:05.000Z] [fatal] Cannot continue code=E_FATAL
[2025-01-01T12:00:06.000Z] [trace] user.login trace.id=abcde12345 userId=12345
[2025-01-01T12:00:07.000Z] [trace] cache.miss Cache miss for user 12345 key=user_12345

Back to top โ†‘


๐Ÿงฎ Tracing helpers

The trace() promotes common IDs to ECS fields:

Remaining key/values are placed under labels.*. If a value argument is provided, it appears as labels.value. Example:

log.trace('user.login', { userId: 12345, traceId: 'abcde12345' }); // traceId becomes trace.id
log.trace('cache.miss', { key: 'user_12345' }, 'Cache miss for user 12345'); // with value

Back to top โ†‘


๐Ÿ”ƒ HTTP output

If outputUri is set, logs are sent as JSON via HTTP POST. File and console outputs still apply unless disabled.

When outputUri is set, each log is POSTed to the endpoint as JSON. File and console outputs still apply unless disabled.

Example HTTP payload:

{ "@timestamp": "2025-01-01T12:00:00.000Z", "service.name": "app", "log.logger": "app", "log.level": "info", "message": "Application started", "event.kind": "event", "event.dataset": "app.stdout", "labels": { "env": "production" } }

Back to top โ†‘


๐Ÿ—œ๏ธ Log rotation and compression

Logs are buffered and flushed every second or when the buffer exceeds 1KB. When a log file exceeds ~1MB, it is rotated and compressed with gzip (if compressEnabled is true).

Back to top โ†‘


โŒ Exceptions

Uncaught exceptions are logged to exception.log and the process exits. If saveOnlyUncaughtException is true, only uncaught exceptions are recorded (stdout/stderr hooks are not attached).

Back to top โ†‘


๐Ÿ“„ TypeScript

Type definitions are included. If using TypeScript, import as below. Ensure your tsconfig.json has "esModuleInterop": true or use import * as createLogger from 'log-report' if not.

index.d.ts is included.

import createLogger from 'log-report';
const log = createLogger('api');
log.info('ready');

Back to top โ†‘


๐Ÿ“š Examples

See examples/:

Back to top โ†‘


๐Ÿงช Tests

Project includes tests using test-runner-lite. No additional setup is needed. Use test-runner-lite (or Node directly) to run tests.

Run all tests:

npm test

Run the test directly:

node ./index.test.js

Back to top โ†‘


๐Ÿ“œ License

This project is licensed under the MIT License.
Copyright ยฉ Manuel Lรตhmus

Back to top โ†‘