Skip to content

Releases: fullstack-build/tslog

v5.1.0

Choose a tag to compare

@terehov terehov released this 16 Jul 22:15

Added

  • Named sub-loggers on tslog/liteLiteLogger gains name/nameSeparator options and getSubLogger()/child(). The label is partially applied with Function.prototype.bind, so a sub-logger's level methods are still the bound native console.* functions and the devtools file:line badge keeps pointing at the caller. Every % in a label is escaped so a (possibly runtime-derived) name can never act as a console format specifier and consume a logged value. Sub-loggers nest to any depth, join names with the parent's nameSeparator (default ":"), and inherit minLevel and the sink unless overridden; an unresolvable minLevel override inherits the parent's level, matching the full Logger. Known trade-off (documented): on a named lite logger the label occupies the console's format-string slot, so printf-style specifiers in messages print literally.
  • Bundle-size budget for tslog/litecheck-bundle-size now probes the lite subpath (~0.8 KB gzip measured, 1 KB budget).

v5.0.2...v5.1.0

v5.0.2

Choose a tag to compare

@terehov terehov released this 16 Jul 20:07
  • Readable default styling on light devtools themes — the default pretty styles color timestamps, log positions, and logger names white, which the browser CSS path rendered as a near-white hex: invisible on light consoles (the Safari/Chrome default theme). Foreground white/whiteBright now contribute no color: declaration, so that text keeps the console's own default color and is readable in both light and dark themes. Terminal ANSI output is unchanged; background tokens keep their palette hex.

v5.0.1...v5.0.2

v5.0.1

Choose a tag to compare

@terehov terehov released this 16 Jul 10:41

A patch release that makes source-mapped error positions work out of the box with modern bundler output (Turbopack/Next.js dev, Rollup, Webpack) — verified end-to-end against live Next.js 16 (next dev --turbopack) and TanStack Start (Vite) dev servers — and fixes the default browser console output (error styling, stack parsing, log positions), verified in real Chromium, Firefox, and WebKit. No API or settings changes.


v5.0.0...v5.0.1

v5.0.0

Choose a tag to compare

@terehov terehov released this 14 Jul 13:18

[5.0.0] - 2026-07-14

A ground-up rewrite. tslog is now ESM-only, zero-dependency, Node >=20, and built with TypeScript 7 / ES2022. Settings are grouped, JSON output is fields-first, and the logger gains a middleware pipeline, async transports, JSONPath masking, OpenTelemetry/pino/GenAI presets, ready-made file/http/ringbuffer/worker transports, and tree-shakeable subpath modules. v5 also adds first-class support for agents and LLMs — fields-first calls, agent/session correlation, and OTel-GenAI attributes; OpenClaw uses tslog for its agent logging. This is a breaking release — see MIGRATION_v4_to_v5.md for the upgrade path.

Added

  • Grouped settings — related options now live under pretty, json, mask, stack, and meta groups instead of a flat list of prettyLog*/maskValues* keys. Sub-loggers merge groups rather than overwrite them.
  • Fields-first JSON output — every level method is overloaded pino-style: info(fields, message?, ...args) as well as info(message, ...args). A single object spreads its fields to the top level, a leading object plus string spreads fields and sets message, and positional args land under message/"1"/… Runtime metadata moves under _logMeta carrying a v: 5 schema marker. All JSON keys are configurable via the json group.
  • Middleware pipelinelogger.use(middleware) runs functions over each log context to mutate logObj/meta or drop the log entirely (return null/false).
  • Async transports with attachTransport() returning a detach function, logger.flush(), and Symbol.asyncDispose/Symbol.dispose support (await using). Each transport may declare its own minLevel and format ("pretty", "json", or a custom formatter).
  • Advanced maskingmask.paths (JSONPath-ish patterns such as user.password or *.token), mask.regex, and a mask.censor of "remove", "hash", a string, or a function (with mask.hashLabel).
  • Presetstslog/presets/pino (pinoFormat, pinoTransport, toPinoLevel), tslog/otel (otelFormat, toOtelRecord, levelToSeverityNumber, OtelSeverityNumber, otelTraceContext, stringifyOtelRecord), and tslog/presets/genai (genai, genaiAttributes, genaiSummary emitting OTel gen_ai.* fields).
  • Built-in transportstslog/transports/file (fileTransport, non-blocking, flush/dispose), tslog/transports/http (httpTransport, batched), tslog/transports/ringbuffer (ringBufferTransport with .dump()/.clear()), and tslog/transports/worker (workerTransport, Node-only off-thread sink I/O).
  • Standard serializerstslog/serializers exports stdSerializers (err, req, res, user), the individual serializers, and a serialize(map) middleware helper.
  • Context propagationrunInContext(ctx, fn) uses AsyncLocalStorage to attach context fields to _logMeta when meta.attachContext is enabled. Auto-resolves on Node/Deno/Bun; on Cloudflare Workers inject one via the contextStorage setting (graceful no-op in browsers, with a one-time development warning).
  • Custom levels via the customLevels setting and log(levelId, levelName, ...args).
  • New API surfacechild() (alias of getSubLogger()), isLevelEnabled(), getContext(), addLevel(), logger.if(condition), Logger.fromEnv(), defineConfig(), and TslogConfigError (thrown when strictConfig is on).
  • Subpath modules (all tree-shakeable) — tslog/lite (minimal console wrappers preserving native line numbers), tslog/cli (also the tslog bin, an NDJSON pretty-printer for stdin), tslog/testing (createTestLogger, mockLogger), tslog/throttle (rate-limit middleware), tslog/pretty/box (box, tree), and tslog/console (wrapConsole, restoreConsole, isConsoleWrapped).
  • Env-aware colorization — when type is omitted, output is pretty everywhere (server, CI, browser, React Native); only the coloring adapts to the environment: colored on an interactive TTY (CSS in the browser) and uncolored when stdout is piped/redirected/CI, so no ANSI escapes leak into files or log collectors. Structured JSON is opt-in via type: "json", TSLOG_TYPE=json, or a JSON transport. NO_COLOR strips colors without switching the format; FORCE_COLOR forces styled pretty. Applies to both new Logger() and the ready-made log.
  • React Native support — detected via navigator.product (_logMeta.runtime: "react-native", Hermes engine version when available), Hermes/JSC stack frames parsed with a hybrid parser, pretty output by default.
  • Real hostname in server JSON logs_logMeta.hostname resolves from HOSTNAME/HOST/COMPUTERNAME, then the OS hostname (Deno.hostname() / node:os via process.getBuiltinModule), instead of defaulting to "unknown".
  • Tree-shakeable exportssideEffects: false (audited) with per-runtime conditional exports.
  • tslog/slim — the smallest structured-JSON build (~9KB gzip vs ~19KB for the full browser entry, budget-checked in CI): the same pipeline minus masking, pretty output, and stack capture; mask settings and type: "pretty" throw instead of silently degrading.
  • Buffered stdout sink (Node) — the Node entry writes type: "json" lines through a batched process.stdout.write (one write per event-loop turn, early flush past ~8KB) instead of per-line console.log; drained by logger.flush(), await using, and guarded beforeExit/exit hooks (a bare process.exit() loses nothing). Browser/universal entries keep console.log.
  • Time seam — an injectable top-level clock: () => Date (deterministic tests, offset/monotonic stamping; inherited by sub-loggers, hostile clocks ignored) and json.time: "iso" | "epoch" | false | fn controlling the top-level timestamp representation (_logMeta.date stays UTC ISO).
  • Deterministic test outputcreateTestLogger(settings, { now, normalize }): now freezes only that logger's clock (no fake-timer sledgehammer), normalize: true yields snapshot-stable records/lines; plus a standalone normalizeMeta(recordOrLine) scrubber (all in tslog/testing).
  • Real OTLP/JSON in tslog/otelotlpFormat/toOtlpJson/toOtlpLogRecord/toOtlpAnyValue/stringifyOtlpRequest emit the collector wire format (camelCase proto3 fields, typed attributes, resourceLogs[].scopeLogs[].logRecords[] envelope, exception.* semconv mapping for logged errors), and otlpBatchBody pairs with the http transport's new encodeBody option to POST merged batches straight to /v1/logs.
  • httpTransport({ encodeBody }) — custom body encoder for endpoints whose payload is neither NDJSON nor a JSON array (used by the OTLP pairing above).
  • Conditional logginglogger.if(condition) returns the logger when the condition is truthy and a no-op stand-in when falsy, so a per-call guard reads as a fluent chain (log.if(!ok).warn("failed", { id })). Use isLevelEnabled() to skip expensive payload construction.
  • Browser-native pretty objectspretty.passObjectsNatively hands non-Error arguments to the console by reference (on by default in real browsers), so DevTools renders collapsible, interactive trees; pair with pretty.levelMethod for native warn/error stack groups. Set false for log-time snapshots or text-matchable console output.
  • Source-mapped error positions — on Node, Bun, and Deno, logged Error stack frames resolve through discoverable source maps back to original .ts file/line/column (automatic outside production; override with TSLOG_SOURCE_MAPS=on/off).

Changed

  • ESM-only and Node >=20; the project now targets TypeScript 7 / ES2022.
  • JSON output on Node no longer goes through console.log (see the buffered stdout sink above) — code intercepting console.log must spy on process.stdout.write or use type: "hidden" plus a transport.
  • tslog/otel resource precedence — in toOtelRecord, resource attributes now win over colliding per-record fields (resource identity semantics); in the OTLP shape they live in the envelope, separate from record attributes.
  • The default JSON shape is fields-first with _logMeta.v: 5; name/parentNames appear only when set (no "[undefined]" noise).
  • Masking is off by defaultmask.keys starts empty; enable it explicitly.

Removed

  • The CommonJS build and require("tslog") — the package is ESM-only.
  • The overwrite.* hooks (mask, toLogObj, addMeta, formatMeta, formatLogObj, transportFormatted, transportJSON, addPlaceholders) — use middleware and per-transport format instead.
  • Flat settings keysprettyLogTemplate/prettyError*/prettyLog*, stylePrettyLogs, maskValuesOfKeys/maskValuesRegEx/maskPlaceholder, metaProperty, and stackDepthLevel (now the callerFrame constructor parameter).
  • hideLogPositionForProduction — superseded by the stack group and env-aware defaults.
  • The loggerEnvironment/createLoggerEnvironment singleton — each entry point exports its own environment factory (createNodeEnvironment, createBrowserEnvironment, createUniversalEnvironment/selectEnvironment).
  • The nested {"0": message} JSON shape.

v5 RC

v5 RC Pre-release
Pre-release

Choose a tag to compare

@terehov terehov released this 14 Jul 12:45
  • fix(tests): switch worker.runner until() to time-based 10s timeout for CI stability 51cc454
  • ci: expand Node test matrix to 20/22/24/26/latest; bump harnesses to 22 e367fb9
  • Merge branch 'development' into v5 24a9988
  • fix(tests): clear NO_COLOR in vitest setup and explicitly enable pretty.style for CSS tests bc17e21
  • fix(tests): restore CI on Node 20 for lifecycle and worker.runner suites fd1ccc3
  • Document v5 late features across CHANGELOG, migration guide, and release notes f761374
  • Update README and release notes for v5.0.0: add TypeScript types and enhance logging features e45130b
  • Enable pretty.passObjectsNatively by default in browsers fbf4af3
  • Fix doc inaccuracies found by the pre-release audit e6a7f99
  • Fix the Deno test runner so its tests actually run e71bcd9
  • Add logger.if() conditional logging gate ebcaf3c
  • Add pretty.passObjectsNatively to pass raw objects to the console 8234681
  • Bump docs deps: astro 7, starlight 0.41, vite 8 6e262a5
  • Keep fullFilePath absolute after a source-map remap d496454
  • Improve source-map resolution: binary search, fullFilePath consistency, per-call enablement a2304ec
  • Resolve error stack positions through source maps on Node, Bun, and Deno 1c10154
  • Remove global Window.chrome type declaration cd077d0
  • Redesign the docs site with a dark theme e39c30d
  • Reflow README and migration guide for narrower content columns 8323373
  • Remove the stale examples/ tree fac0648
  • Rename _meta to _logMeta 352d03f
  • Fix browser stack parser for Windows Vite /@fs/ drive-letter paths 3ac1900
  • Default to pretty output everywhere and make JSON opt-in 49e9588
  • Publish the v4-to-v5 migration guide as a docs site page 5b88479
  • Highlight first-class agent and LLM support and OpenClaw usage ac89125
  • Set 4.11.0 changelog release date 1b0ebf6
  • Fix stale doc claims and expand llms.txt API coverage b244db9
  • Report a structured droppedCount on http transport buffer drops 52163ba
  • Fix doubled host in browser stack fullFilePath ef25020
  • Extract the shared provider implementation into env/providerBase a3eaf14
  • Trim padding tests, convert testable coverage ignores into real tests, and drop dead branches 8cacdfb
  • Fix polyfill %i/%f parsing, flushSync double-write, and inert coverage tests 7c6ebb4
  • Cover Sentry Logs in the Sentry integration docs 0003b76
  • Add migration guides and Sentry/Better Stack integration docs c8c1da1
  • Reach 100% test coverage across the source tree d19d43b
  • Fix worker transport dispose after a failed spawn 02558e4
  • Wire the Node environment provider onto core/meta.ts af3c293
  • Remove dead v4 modules and reconcile coverage config 5159f5c
  • Document the buffered sink, time seam, and preset output changes 2c2cdc8
  • Isolate the transport format step and default hidden transports to JSON 844462a
  • Serialize errors in pino's wire shape in the pino preset 501f3ed
  • Emit real OTLP/JSON from the otel preset 6dfa49c
  • Add an injectable clock and configurable JSON time output 665fece
  • Batch Node JSON output through a buffered stdout sink 744633f
  • Add a build-picker guide to the README fee348a
  • Enforce gzip budgets for the slim and full browser bundles d996dae
  • Add tslog/slim, a structured JSON logger at half the size 1de26d9
  • Inject masking, JSON rendering and validation through the entries 6039f91
  • Sync the browser spec with the (string, object) spread shape 9aa649b
  • Point the legacy module field at the universal entry e4f7d51
  • Treat NO_COLOR as a color switch, not a format switch 97661b7
  • Let apps inject AsyncLocalStorage for context propagation cdf2bd4
  • Resolve the real OS hostname for server JSON logs 90f1431
  • Detect React Native and parse Hermes and JSC stack frames 3391032
  • Add bindings and typed custom level methods 99993e6
  • Stop the worker transport from pinning or starving the process 383a422
  • Bound and retry HTTP log delivery f8176bc
  • Contain file-transport failures and drain on process exit c06d798
  • Make flush() cover async transport writes and scope disposal 8e1801a
  • Point npm run bench at the actual benchmark script 2c8cec8
  • Trim per-log overhead and use native inspect in ESM 1af363e
  • Precompile the JSON line and spread message-first fields 5ac53df
  • Validate settings keys against the grouped shape 9e1c01c
  • Document v5 and add a migration guide f6b06e3
  • Rewrite the test suite for the v5 API 564be4a
  • Drop the CJS build and publish ESM only 76f4538
  • Add tree-shakeable subpath modules d6ab74f
  • Restructure the logger into core, env and render modules 647c704
  • Sync AGENTS.md version from package.json on release 5479add
  • Share agent guidance and keep personal overrides local 8ec821a
  • Document new 4.11.0 settings and tidy release notes 0e43385
  • Pin graphql and bson dev deps to versions that support Node 20 e2916f9
  • Bump codecov-action to v5 and pass upload token a68a229
  • Add regression tests for logging GraphQLError and BSON ObjectId c2b56b3
  • Update changelog for 4.10.1, 4.10.2, and 4.11.0 6e953aa
  • Add AI/agentic docs and ship them with the package 2ea3598
  • Add runtime features: unified stack detection, named log levels, config validation fd6a0e4
  • Fix bigint, invalid date, local timezone, worker styling and meta types 4733bdd
  • Rename CI build job to test-node and bump actions to Node 24 f0e3b76
  • Run browser tests as a per-engine CI matrix and gate development PRs 4ced09d
  • Run browser tests on Firefox and WebKit and port core suites to the browser 725dfdd
  • Optionally pass default meta to custom addMeta handler c373203
  • Expose DefaultLogLevels enum for default log levels e899630
  • Merge PR #330: add prettyLogLevelMethod for routing log levels 32a9a0a
  • Merge PR #310: add missing fileNameWithLine style and dedup type 4c3b66a
  • Add regression tests for inspect option handling 77eb8ad
  • Merge PR #331: make _extend mutate the context in place 9f267c2
  • Merge PR #335: fix cannot convert object to primitive value 619d6d7
  • Harden transport and masking, reach full test coverage 643844b
  • fix cannot convert object to primitive value 1457c86
  • Refine docs styling and page title 20c00cd
  • Replace docsify with Starlight for docs site 2b49f8f
  • Replace eslint and prettier with biome b5369aa
  • update dependencies and fix vulnerabilities f8940e6
  • merge remote master 5ecd602
  • Fix stale references and typos in readme b9dadb7
  • fix deno regex masking test bypassing mask pipeline f98c1ea
  • Run CI on development branch 9f30c84
  • Add cross-runtime test suite for node, browser, deno, bun, and workers 3e49aea
  • replace simple-git-hooks with husky v9 24f755a
  • Replace Jest and Puppeteer with Vitest and Playwright f0a3d17
  • fix: make _extend method use shallow copy 31b518e
  • prettyLogLevelMethod bba5ad3
  • 4.10.0 (#320) (#321) 6b98e17
  • Add CI-specific launch arguments for Puppeteer cc6cc05
  • Add missing fileNameWithLine 9aab33b

v4.10.2...v5.0.0-rc.0

v4.11.0

Choose a tag to compare

@terehov terehov released this 07 Jul 18:16
  • Set 4.11.0 changelog release date 1b0ebf6
  • Sync AGENTS.md version from package.json on release 5479add
  • Share agent guidance and keep personal overrides local 8ec821a
  • Document new 4.11.0 settings and tidy release notes 0e43385
  • Pin graphql and bson dev deps to versions that support Node 20 e2916f9
  • Bump codecov-action to v5 and pass upload token a68a229
  • Add regression tests for logging GraphQLError and BSON ObjectId c2b56b3
  • Update changelog for 4.10.1, 4.10.2, and 4.11.0 6e953aa
  • Add AI/agentic docs and ship them with the package 2ea3598
  • Add runtime features: unified stack detection, named log levels, config validation fd6a0e4
  • Fix bigint, invalid date, local timezone, worker styling and meta types 4733bdd
  • Rename CI build job to test-node and bump actions to Node 24 f0e3b76
  • Run browser tests as a per-engine CI matrix and gate development PRs 4ced09d
  • Run browser tests on Firefox and WebKit and port core suites to the browser 725dfdd
  • Optionally pass default meta to custom addMeta handler c373203
  • Expose DefaultLogLevels enum for default log levels e899630
  • Merge PR #330: add prettyLogLevelMethod for routing log levels 32a9a0a
  • Merge PR #310: add missing fileNameWithLine style and dedup type 4c3b66a
  • Add regression tests for inspect option handling 77eb8ad
  • Merge PR #331: make _extend mutate the context in place 9f267c2
  • Merge PR #335: fix cannot convert object to primitive value 619d6d7
  • Harden transport and masking, reach full test coverage 643844b
  • fix cannot convert object to primitive value 1457c86
  • Refine docs styling and page title 20c00cd
  • Replace docsify with Starlight for docs site 2b49f8f
  • Replace eslint and prettier with biome b5369aa
  • update dependencies and fix vulnerabilities f8940e6
  • merge remote master 5ecd602
  • Fix stale references and typos in readme b9dadb7
  • fix deno regex masking test bypassing mask pipeline f98c1ea
  • Run CI on development branch 9f30c84
  • Add cross-runtime test suite for node, browser, deno, bun, and workers 3e49aea
  • replace simple-git-hooks with husky v9 24f755a
  • Replace Jest and Puppeteer with Vitest and Playwright f0a3d17
  • fix: make _extend method use shallow copy 31b518e
  • prettyLogLevelMethod bba5ad3
  • 4.10.0 (#320) (#321) 6b98e17
  • Add CI-specific launch arguments for Puppeteer cc6cc05
  • Add missing fileNameWithLine 9aab33b

v4.10.2...v4.11.0

v4.10.2

Choose a tag to compare

@terehov terehov released this 30 Sep 13:52
  • Fix CJS build, add README to dist folder e1bdfd7

v4.10.1...v4.10.2

v4.10.0

Choose a tag to compare

@terehov terehov released this 28 Sep 14:49

Changelog

[4.10.0] - 2025-09-25

Breaking

  • Custom transportFormatted overrides now receive logMeta as the fourth argument; pass five parameters to also receive settings, otherwise adjust implementations that previously read settings from the fourth position.
  • Deprecated runtime entry points under src/runtime/** and related browser mappings have been removed; use the primary Logger export instead of importing runtime-specific helpers.
  • Logger metadata now exposes lowercase runtime identifiers (for example node, browser, deno, bun, worker) and normalized versions without the leading v; adjust consumers that compared against Nodejs or relied on the old format.

Added

  • Introduced universal runtime detection that recognises Node.js, browsers, web workers, Deno, and Bun, enriching metadata with runtime versions and hostnames when available.
  • Documented first-class Deno and Bun usage, refreshed examples under examples/server, and aligned development scripts (npm run dev-ts*).
  • Pretty transports now detect when the browser console supports CSS, rendering styled output with %c tokens and gracefully falling back when styling is unavailable.
  • Error formatting captures chained Error.cause entries (up to depth five) and includes them in both pretty error blocks and JSON error objects.

Changed

  • The core logger automatically locates the first user stack frame instead of relying on hard-coded depths, producing stable file and line metadata across bundlers; manual stackDepthLevel overrides continue to work.
  • Placeholder formatting now routes through a shared buildPrettyMeta utility, improving consistency for custom templates and nested style tokens.
  • Masking internals normalise and cache case-insensitive keys, reducing repeated allocations and keeping behaviour consistent when toggling mask options.
  • Browser styling defaults keep ANSI colouring enabled unless explicitly disabled, letting CSS-capable consoles honour stylePrettyLogs without runtime-specific tweaks.

Fixed

  • Runtime error detection now treats objects with an Error-suffixed name as errors, ensuring they are formatted via the error transport.
  • Browser stack parsing guards against malformed frames, avoiding crashes when devtools emit unexpected stack entries.
  • Logging no longer fails when process.cwd() throws (for example under restricted permissions); environment helpers fall back to cached working directories and hostname detection across Node, Deno, and Bun.

v4.9.3

Choose a tag to compare

@terehov terehov released this 08 Jun 12:14
  • Fix _extend fn - alter provided object 135ee61

v4.9.2...v4.9.3

v4.9.2

Choose a tag to compare

@terehov terehov released this 23 Aug 13:43

v4.9.1...v4.9.2