An unopinionated JS/TS logging framework.
-
Provides a
console.log
equivalent that can be used in the middle of expressions, likef(log(arg))
. -
Has a minimal core and a simple plugins system.
bun add @1log/console @1log/core
pnpm add @1log/console @1log/core
yarn add @1log/console @1log/core
npm install @1log/console @1log/core
Create a log
function, probably in a separate module:
// log.ts
import { consolePlugin } from "@1log/console";
import { noopLog } from "@1log/core";
export const log = noopLog.add(consolePlugin());
This function can be used just like console.log
, but has two additional features. First, it returns the last argument passed to it instead of void
, so as mentioned above, can be inserted in an expression. Second, calling log.add(...plugins)
returns a new log function with more plugins added to it. For example, to prefix all log messages from some module with a label, you would do
import { label } from "@1log/core";
import { log as baseLog } from "./log";
const log = baseLog.add(label("your module"));
log("will have prefix");
Another example: use console.error
instead of console.log
:
import { severity } from "@1log/console";
import { log } from "./log";
log.add(severity("error"))("oops");
- core:
noopLog
, the notion of labels, color palette, and a mechanism to reset stateful plugins. - console: a plugin that logs messages using console.* methods (supports colored labels, time deltas and severity levels).
- jest: a plugin that buffers log messages and lets you snapshot them in Jest tests (supports labels and time deltas).
- promise: log fulfillment/rejection of a promise.
- function: log arguments, returned value and errors for a regular or async function.
- rxjs: log everything that happens to an RxJS observable.
A plugin is a function that takes and returns a "data" object of shape {args, meta}
where args
is the arguments passed to the log function, and meta
is an object of type Meta
that has metadata on the log message. The data object is passed through all the plugins in the following order:
log.add(called3rd).add(called2nd, called1rst);
For example, severity
plugin from the code sample above adds a property [severitySymbol]: "error"
to meta
, which consolePlugin
then sees and uses console.error
to log the message. If we wanted to only log errors, we could create a plugin inline in log.ts
as follows:
// log.ts
import { consolePlugin, severitySymbol } from "@1log/console";
import { noopLog } from "@1log/core";
export const log = noopLog.add((data) =>
data.meta[severitySymbol] === "error" ? consolePlugin()(data) : data
);
If you're adding your own props to meta
, it's recommended to use a Symbol
as key and augment the Meta
interface like this:
export const yourSymbol = Symbol("yourSymbol");
declare module "@1log/core" {
interface Meta {
[yourSymbol]?: YourPropertyValueType;
}
}