semantic-release-bot 19de8db119 chore(release): 1.0.0 [skip ci]
# [1.0.0](https://git.mifi.dev/mifi/logger/compare/v0.10.0...v1.0.0) (2026-08-07)

### Features

* API options object support to control sentry handling; removal of `logger.sentry.` ([234226e](234226e2bb))
* API options object support to control sentry handling; removal of `logger.sentry.` ([6bee3a8](6bee3a801d))

### BREAKING CHANGES

* API options object support to control sentry handling; removal of `logger.sentry.`
* API options object support to control sentry handling; removal of `logger.sentry.`
2026-08-07 15:22:51 +00:00
2026-08-05 01:09:30 -03:00
2026-08-05 01:09:30 -03:00
2026-08-07 15:22:51 +00:00
2026-08-07 15:22:51 +00:00
2026-08-07 12:20:52 -03:00
2026-08-07 12:20:52 -03:00
2026-08-05 01:09:30 -03:00
2026-08-05 01:09:30 -03:00

@mifi/logger

Intentional, namespaced logging for TypeScript browser and Node.js applications.

import { createLogger } from "@mifi/logger";

const logger = createLogger({ environment: "production", namespace: "WIDGET" });
logger.child("Button").debug("Rendered", () => ({ expensive: "only evaluated when shown" }));

Install

pnpm add @mifi/logger

Requires Node.js >=24. Published to the private @mifi registry.

Quick start

import { createLogger } from "@mifi/logger";

const logger = createLogger({
    environment: "development", // "development" | "staging" | "production"
    namespace: "API", // optional; string or string[] joined with ":"
});

logger.trace("very detailed");
logger.debug("diagnostic", () => ({ snapshot: heavyWork() }));
logger.info("ready");
logger.warn("slow response", { ms: 1200 });
logger.error("request failed", error);
logger.assert(userId, "missing user id");

const auth = logger.child("auth"); // namespace → "API:auth"
auth.info("token refreshed");

Console utility methods (group, groupCollapsed, table, time, count, dir, …) are available and gated by the same level policy as info.

Runtime policy

Default levels by environment:

Environment Default level Console shows
development trace all levels
staging warn warn, error
production error error only

Levels in order (most → least verbose): tracedebuginfowarnerrorsilent.

Override precedence

Highest wins:

  1. Explicit level option on createLogger
  2. Browser sessionStorage.showLoggingFor
  3. Env vars MIFI_LOG_LEVEL / MIFI_LOG_NAMESPACES
  4. Environment default (table above)

Browser session override

sessionStorage.setItem("showLoggingFor", "debug");
// or restrict to namespaces (exact or descendants):
sessionStorage.setItem("showLoggingFor", "debug:WIDGET,API");

WIDGET matches WIDGET and WIDGET:Button.

Container / Node env overrides

See Environment variables and env.example.

MIFI_LOG_LEVEL=debug
MIFI_LOG_NAMESPACES=WIDGET,API

Environment variables

These are read from process.env (or from options.env when testing/injecting):

Variable Description
MIFI_LOG_LEVEL Override level: trace, debug, info, warn, error, or silent.
MIFI_LOG_NAMESPACES Optional comma-separated namespace filters applied with the level override.

When only MIFI_LOG_LEVEL is set, all namespaces are enabled at that level. When MIFI_LOG_NAMESPACES is also set, only matching namespaces (and their children) emit at that level.

Copy env.example as a starting point for local or container config.

Sentry

The Sentry adapter has no SDK dependency. Provide the SDK your application already uses via @mifi/logger/sentry.

Development never sends to Sentry. Staging and production attach the sink when sentry is configured.

Destination policy when sentry is configured and sinks is not:

Runtime + environment Console Sentry
Production browser Off Issues for errors; optional Logs
Production Node On (stderr for errors) Issues for errors; optional Logs
Staging On (default warn+) Issues for errors; optional Logs
Development On Nothing

Issues vs Logs

  • Errors → Sentry Issues (captureException / captureMessage). Not also written to Logs.
  • Warnings and lower → Sentry Logs (sentry.logger.*) only when { logs: true } on the sink (or forced per call).

Default Sentry Logs thresholds when logs is enabled:

Environment Logs threshold
Staging info
Production warn

Override with logLevel on createSentrySink. Console policy stays independent — production browsers can stay quiet while warnings still appear in Sentry Logs.

Per-call options

trace / debug / log / info / warn / error (and assert) accept a trailing options object. Console utilities (group, time, …) do not.

import * as Sentry from "@sentry/nextjs";
import { createLogger } from "@mifi/logger";
import { createSentrySink } from "@mifi/logger/sentry";

const logger = createLogger({
    environment: "production",
    namespace: "API",
    sentry: createSentrySink(Sentry, { logs: true }),
});

logger.error("Request failed", error, { requestId: "req_1" });
logger.warn("slow", { ms: 1200 }); // → Sentry Logs in production
logger.info("investigating", { orderId }, { sentry: true }); // force Logs
logger.error("expected", err, { suppressSentry: true }); // console only (when enabled)
Option Effect
sentry: true Force this event to Sentry Logs (ignores Logs threshold; not for errors)
suppressSentry: true Skip creating a Sentry Issue for an error

A last argument is treated as options only when every key is sentry or suppressSentry. Prefer the third-argument form when you also pass data.

Logs payload: string message + flat primitive attributes (including logger.namespace). Nested objects are not unfurled.

Custom sinks

Replace the default destinations entirely with sinks:

import { createLogger, createConsoleSink, type LogSink } from "@mifi/logger";

const analyticsSink: LogSink = {
    emit(event) {
        if (event.sendToConsole) analytics.track("log", event);
    },
};

const logger = createLogger({
    environment: "production",
    sinks: [createConsoleSink(), analyticsSink],
});

When sinks is provided, the sentry option is not used for default sink selection.

API overview

Export From Purpose
createLogger @mifi/logger Build a namespaced, Console-shaped logger
createConsoleSink @mifi/logger Default styled console destination
parseLoggingOverride @mifi/logger Parse debug / debug:NS1,NS2 override strings
createSentrySink @mifi/logger/sentry Adapter for any Sentry-like SDK

Types: Logger, LoggerOptions, LogLevel, LoggerEnvironment, LogEvent, LogSink, LogData, LogCallOptions, and (from /sentry) SentryLike, SentryScopeLike, SentrySink, SentrySinkOptions.

Optional destinations live under src/sinks/ (console, Sentry today; New Relic / Datadog-style adapters can land beside them later). Public import paths stay @mifi/logger and @mifi/logger/sentry.

All public APIs include JSDoc with parameter and example documentation in the TypeScript sources.

Lazy arguments

Any function passed after the first argument is invoked only if the event is emitted:

logger.debug("state", () => buildHugeSnapshot()); // skipped when debug is suppressed

Releases

Woodpecker verifies pull requests and main, reports CI to Mattermost, then automatically releases from Conventional Commits merged to main. It updates package.json and CHANGELOG.md, creates a vX.Y.Z tag, and publishes to the private @mifi registry.

Use fix: for a patch, feat: for a minor release, and feat! / fix! (or a BREAKING CHANGE: footer) for a major release. Commits such as docs:, test:, and chore: do not release a package.

The release workflow uses the existing global gitea_package_token, gitea_registry_username, gitea_release_token, mattermost_bot_access_token, mattermost_tests_channel_id, mattermost_pushes_channel_id, and mattermost_post_api_url secrets.

S
Description
Why keep recreating the same wheel? Just use the wheel I like (and have made 67,000 times already)
Readme
166 KiB
v1.0.1
Latest
2026-08-07 19:08:20 +00:00
Languages
TypeScript 97.8%
JavaScript 2.2%