ctx-log v0.0.7
Context Logger for TypeScript
A context logger written in TypeScript.
Motivation
ctx-log is motivated by tagging loggers with a particular context to identify logs.
It aims to be provide a fast and simple logger with JSON output with zero dependency. The idea of a context logger is that
each logger is attached with a particular context, in which can be used for better search and identification (see: Contextual Logging).
ctx-log logger can be easily configured to write to multiple Writers at multiple levels, which can be
implemented by developers using provided interfaces (see: Writers & Leveled Logging).
ctx-log chaining API & design is inspired by GoLang logging library zerolog.
Features
Installation
NPM:
npm install ctx-logYarn:
yarn add ctx-logPNPM:
pnpm add ctx-logGetting Started
Simple Logging Example
The simplest way to get started with ctx-log is to use the default export global logger.
import log from "ctx-log";
log().Info().Msg("hello world");
// Output: {"level":"info","time":"2024-02-25T16:49:57.564Z","caller":"./src/index.ts:3","message":"Hello World!"}The default logger will initialize a
Writerbased on the environment variableNODE_ENV, if theNODE_ENVvariable is set todevelopment, it'll utilize the builtinConsoleWriterfor pretty logging.
However, to use the logger more efficiently and in a customized fashion, it is recommend to create your own logger and replace the existing global logger.
import log, { NewLogger, ConsoleWriter, Logger } from "ctx-log";
log().Info().Msg("Hello World!");
// Output: {"level":"info","time":"2024-02-25T17:12:58.199Z","caller":"./src/index.ts:3","message":"Hello World!"}
const newLogger = NewLogger(new ConsoleWriter());
Logger.GlobalLogger = newLogger;
log().Info().Msg("Hello World!");
// Output: INF Hello World!Leveled Logging
Log Levels
Logging levels in ctx-log is configured to have the following log levels (from the highest to lowest):
- fatal (Level.FatalLevel, 4)
- error (Level.ErrorLevel, 3)
- warn (Level.WarnLevel, 2)
- info (Level.InfoLevel, 1)
- debug (Level.DebugLevel, 0)
- trace (Level.TraceLevel, -1)
Simple Leveled Logging Example
log().Trace().Msg("Hello World!");
log().Debug().Msg("Hello World!");
log().Info().Msg("Hello World!");
log().Warn().Msg("Hello World!");
log().Error().Msg("Hello World!");
log().Fatal().Msg("Hello World!");
// Output:
// {"level":"trace","time":"2024-02-25T17:35:07.068Z","caller":"./src/index.ts:3","message":"Hello World!"}
// {"level":"debug","time":"2024-02-25T17:35:07.078Z","caller":"./src/index.ts:4","message":"Hello World!"}
// {"level":"info","time":"2024-02-25T17:35:07.078Z","caller":"./src/index.ts:5","message":"Hello World!"}
// {"level":"warn","time":"2024-02-25T17:35:07.078Z","caller":"./src/index.ts:6","message":"Hello World!"}
// {"level":"error","time":"2024-02-25T17:35:07.079Z","caller":"./src/index.ts:7","message":"Hello World!"}
// {"level":"fatal","time":"2024-02-25T17:35:07.079Z","caller":"./src/index.ts:8","message":"Hello World!"}Since
ctx-loguses chaining methods, the chain must end withMsg,MsgFuncorSendmethod. If the log doesn't end with either of these 3 methods, the log will not be written.
Global Levels
You can set the global log level of the logger, which disables all level below the set level.
import log, { Level, SetGlobalLevel } from "ctx-log";
SetGlobalLevel(Level.WarnLevel);
log().Trace().msg("Hello World!");
log().Debug().Msg("Hello World!");
log().Info().Msg("Hello World!");
log().Warn().Msg("Hello World!");
log().Error().Msg("Hello World!");
// Output:
// {"level":"warn","time":"2024-02-25T17:45:32.297Z","caller":"./src/index.ts:8","message":"Hello World!"}
// {"level":"error","time":"2024-02-25T17:45:32.307Z","caller":"./src/index.ts:9","message":"Hello World!"}Logging without Level
You may send a log without using a "level" field, this can be done by using the Log() method.
log().Log().Msg("Hello World!");
// Output:
// {time":"2024-02-25T17:45:32.297Z","caller":"./src/index.ts:3","message":"Hello World!"}Logging without Message
You may send a log without using a "message" field, this can be done by ending the log with the Send() method or
using an empty string ("") in the Msg() method.
log().Info().Msg("");
log().Info().Send();
// Output:
// {"level":"warn","time":"2024-02-25T17:45:32.297Z","caller":"./src/index.ts:3"}
// {"level":"error","time":"2024-02-25T17:45:32.307Z","caller":"./src/index.ts:4"}Writers
WIP.
Hooks
WIP.
Contextual Fields
WIP.
Pretty Logging for Development
WIP.
Error Logging
You can log in "error" level using the Error() method as shown in Leveled Logging. You can also
attach an error object to the error log.
log().Error(new Error("some error")).Msg("An error occurred");
// Output:
// {"level":"error","error":"Error: some error","time":"2024-02-25T18:12:58.746Z","caller":"./src/index.ts:3","message":"An error occurred"}The error is formatted as such:
${err.name}: ${err.message}
Error Logging with Stacktrace
Using the Stack() method, the logger will use the builtin stacktrace in the Error object,
and format into an array for the stack.
function someFunction() {
throw new Error("This is an error");
}
const loggerWithStack = log().With().Stack().Logger();
try {
someFunction();
} catch (error) {
loggerWithStack.Error(error as Error).Msg("An error occurred");
}
// Output (formatted):
// {
// "level": "error",
// "error": "Error: This is an error",
// "stack": [
// "Error: This is an error",
// "at someFunction (./src/index.ts:4:9)",
// "at Object.<anonymous> (./src/index.ts:10:3)",
// "at Module._compile (node:internal/modules/cjs/loader:1376:14)",
// ...
// ],
// "time": "2024-02-25T18:18:57.903Z",
// "caller": "./src/index.ts:12",
// "message": "An error occurred"
// }Logging Fatal Level
When the Fatal level is used, the program will exit with process.exit(1)
log().Fatal().Error(new Error("some error")).Msg("Hello World!");
// Output:
// {"level":"fatal","error":"Error: some error","time":"2024-02-25T18:25:49.352Z","caller":"./src/index.ts:3","message":"Hello World!"}Caller
WIP.
