2.0.5 • Published 12 months ago

@tsjam/logger v2.0.5

Weekly downloads
-
License
MIT
Repository
github
Last release
12 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

12 months ago

2.0.2

12 months ago

2.0.5

12 months ago

2.0.4

12 months ago

2.0.1

12 months ago

2.0.0

12 months ago

1.0.4

12 months ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago