2.0.5 • Published 5 months ago

@tsjam/logger v2.0.5

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

@tsjam/logger

Vanilla TypeScript Logger

Not opinionated ts Logger with Multiple output channels 🍰
Useful for parallel console output & remote monitoring 👩‍🚀

MIT licensed npm version multichannel hashtags timestamps

Advantages:

  • appId (distinguish log between multiple app instances)
  • timestamps (milliseconds matter)
  • hashtags (tag child loggers, find and filter certain logs super-fast)
  • multiple channels output (add ur own output: e.g. parallel console output & remote monitoring)
  • metadata (for all log entries per appId or per call e.g. { userId: 007 })
  • buffering (useful for crash reporting)
  • fully customizable (use your own log format)
  • fair Errors serialization into string (check JSON.stringify(new Error('Oops')); // {})
  • sanitization of sensitive fields (perf optimized, Logs.sanitize({ password: 'ABC' }))
  • safe stringify payload at any moment (Logs.stringify(data))
  • trim stack to number of lines or fully cut (use config { trimStack: 2 })
  • zero third-party dependencies

Output example:
[app161125][2024-01-21T18:33:02.981Z][info][#user] Logged In: { username: Bob, password: '***' }

Installation

npm install @tsjam/logger

Usage

Out of Box

ConsoleOutput is the default output channel. Specify Ur own ones if needed...

import { jamLogger } from '@tsjam/logger';

jamLogger.info('Hello Logger!');
// [app161125][2024-01-21T18:33:02.981Z][info] Hello Logger!

Tagged Logger

Tag child loggers to easily filter logs by tags.

const logger = jamLogger.tagged('user'); // child logger with added tags

logger.info('Greetings for', { name: 'Bob' });
// [app161125][2024-01-21T18:33:02.981Z][info][#user] Greetings for { name: 'Bob' }

Bake Own Logger

const logger = JamLogger.create({
  appId: `ioApp${Date.now()}`,
  channels: [...defaultOutputChannels /* { out: MyKibanaOutput } */], // default is ConsoleOutput
});
const aiLogger = logger.tagged('ai'); // child logger with #ai tag

Custom Output Channel

const myOutput: LogOutput = {
  write: ({ appId, date, level, message, data, context }: LogEntry) => {
    // Format raw log entry and send it anywhere U wish
  },
};

const logger = JamLogger.create({
  channels: [...defaultOutputChannels, { out: myOutput }, { out: myKibanaOutput }],
});

Buffering

Use simplistic BufferOutput to buffer logs for any crash reporting or remote monitoring. Do not forget to flush after report is sent.

const logBuffer = new BufferOutput(2000);
const logger = JamLogger.create({
  channels: [...defaultOutputChannels, { out: logBuffer }],
});

Metadata

Metadata is especially useful for remote reporting & monitoring.

import { JamLogger } from '@tsjam/logger';

const logger = JamLogger.create({
  metadata: { userId: '007' }, // use it however U wish in ur output channel next to log entry
});
//...
JamLogger.updateMeta(logger.appId, { userId: '456' }); // update metadata
logger.info('Lets Play 🦑');
// [app1737064023840][2025-01-16T21:47:03.840Z][info] Lets Play 🦑
// meta: {"userId":"456"}

Pass additional meta per call.

const logger = JamLogger.create({
  metadata: { userId: '007' }, // use it however U wish in ur output channel next to log entry
});
logger.info('Whats Up?', LogMeta.bake({ drink: 'dry martini 🍸' }));
// [app170723][2025-01-16T23:10:56.102Z][info] Whats Up?
// meta: { "userId": "007", "drink": "dry martini 🍸" }

Cook per single call

Sensitive Fields Sanitization

jamLogger.debug('Logged in', Loges.sanitize({ name: 'Bob', password: 'ABC' }));
// [app170723][2024-02-06T16:47:56.398Z][debug] Logged in  { name: 'Bob', password: '***' }

Note: to always sanitize sensitive fields use sanitizeSensitiveTranslator config option.
Yet it's more perf optimized to sanitize only when needed.

Stack Visibility

Stack is shown on Error payloads (similar to console.log);

jamLogger.warn('Oops!', new Error('Something went wrong'));
// [app170723][2024-02-06T17:02:00.108Z][warn] Oops  Error: Something went wrong
//    at Object.<anonymous> (...tsjam-logger/tests/logging/log.utils.spec.ts:10:49)
//    at Promise.then.completed (...tsjam-logger/node_modules/jest-circus/build/utils.js:298:28)
//    ...

Hide stack on Error payloads for specified levels

const logger = JamLogger.create({ errorStackLevel: LogLevel.Error }); // default WARN

logger.warn('Oops!', new Error('Something went wrong'));
// [app170723][2024-02-06T17:02:00.108Z][warn] Oops  Error: Something went wrong

Trim stack to few lines

const logger = JamLogger.create({ trimStack: 2 });
logger.warn('Oops!', new Error('Spoiled the milk!'));
// [app170723][2024-02-06T17:13:59.496Z][warn] Oops! Spoiled the milk! Stack:
//   at Object.<anonymous> (...tsjam-logger/tests/logging/log.utils.spec.ts:10:15)
//   ...

Note: it's also possible to trim the stack to specified depth via trimStack


Translators

There are some built-in translators for log data u could use while baking ur own logger:

  • jsonStringifyTranslator – safely stringify log data Logs.stringify(data)
  • stringifyErrorStackTranslator – fairly serialize Error correctly Logs.stringifyError(error)
  • sanitizeSensitiveTranslator - sanitize sensitive fields defaults: ['password', 'token', 'secret', 'sessionId']

Note: These translators applied either to a Single log call or to All logs by default, U could add Ur own too.

Note: U could add custom translator if U need one for all channels transformation. Otherwise, it's recommended to process raw logEntry in Ur particular output channel.


License

@tsjam/logger is MIT licensed


TSJam Logger Documentation

NPM package

@seeAlso

TSJam API Documentation

2.0.3

5 months ago

2.0.2

5 months ago

2.0.5

5 months ago

2.0.4

5 months ago

2.0.1

5 months ago

2.0.0

5 months ago

1.0.4

5 months ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago