@warlock.js/logger 5.32.0 → 5.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/llms-full.txt CHANGED
@@ -861,7 +861,7 @@ If two channels share a `name`, only one is reachable this way — the search re
861
861
 
862
862
  ---
863
863
  name: redact-sensitive-log-fields
864
- description: 'Strip secrets from log output — a built-in secret-key denylist on by default (DEFAULT_REDACT_KEYS), plus two-layer additive redaction via log.configure({redact: {paths, keys}}) (logger floor) + per-channel redact (more on top). Dotted glob paths (*, **). Triggers: `redact`, `paths`, `keys`, `defaultKeys`, `censor`, `log.setRedact`, `applyRedact`, `maskEmail`, `maskEmailsInText`; "redact passwords in logs", "strip tokens from log output", "hide authorization headers", "scrub PII before logging", "turn off default redaction"; typical import `import { log } from "@warlock.js/logger"`. Skip: filtering — the `filter-log-entries` topic; custom sinks — the `write-custom-log-channel` topic; competing libs `pino.redact`, `fast-redact`.'
864
+ description: 'Strip secrets from log output — a built-in secret-key denylist on by default (DEFAULT_REDACT_KEYS), plus two-layer additive redaction via log.configure({redact: {paths, keys}}) (logger floor) + per-channel redact (more on top). Dotted glob paths (*, **). Triggers: `redact`, `paths`, `keys`, `defaultKeys`, `censor`, `log.setRedact`, `applyRedact`, `maskEmail`, `maskEmailsInText`, `registerLogSecret`, `maskRegisteredLogSecrets`; "redact passwords in logs", "strip tokens from log output", "hide authorization headers", "scrub PII before logging", "turn off default redaction"; typical import `import { log } from "@warlock.js/logger"`. Skip: filtering — the `filter-log-entries` topic; custom sinks — the `write-custom-log-channel` topic; competing libs `pino.redact`, `fast-redact`.'
865
865
  ---
866
866
 
867
867
  # Redaction — keeping secrets out of logs
@@ -896,7 +896,7 @@ log.configure({
896
896
 
897
897
  **A channel cannot turn the default set off** (it can only add keys, or turn it back _on_ if the logger-wide config disabled it) — same additive-only contract as paths, below. And `log.setRedact(undefined)` clears _your_ paths, not the default denylist.
898
898
 
899
- Not reachable by any layer: secrets interpolated into a `message` string (`` `token=${t}` ``), `Map`/`Set`/`Buffer` contents, and getter-backed or non-enumerable properties.
899
+ Key/path redaction cannot reach secrets interpolated into strings, opaque container contents, or non-enumerable properties. Register known credentials with `registerLogSecret()` (below) for an additional safety floor.
900
900
 
901
901
  ## Layers 1 & 2 — path globs, opt-in
902
902
 
@@ -1046,6 +1046,21 @@ sequences are removed; `maxLength` cuts and marks `…[truncated]`. `warlock
1046
1046
  check` (from `@warlock.js/core`) reports raw emails, credentials and request
1047
1047
  bodies in log calls as `WL9008` and accepts these helpers.
1048
1048
 
1049
+ ## Registered credentials (since 5.33)
1050
+
1051
+ ```ts
1052
+ import { registerLogSecret, maskRegisteredLogSecrets, log } from "@warlock.js/logger";
1053
+
1054
+ registerLogSecret("provider-credential", ["vendorPrivateRef"]);
1055
+ log.info("sample", "request", "using provider-credential", { vendorPrivateRef: "hidden" });
1056
+ // "using [REDACTED]", { vendorPrivateRef: "[REDACTED]" }
1057
+ const safeText = maskRegisteredLogSecrets("using provider-credential");
1058
+ ```
1059
+
1060
+ Keys are normalized; values are exact literal substrings (punctuation is literal, longer matches win). Empty values are ignored. This adds a final safety floor after censors in every Logger instance: `defaultKeys: false` and permissive censors cannot disable it. Error messages/stacks/causes, property names, Maps/Sets and channel diagnostics are protected. The safety pass clones without invoking getters/serializers; opaque objects (including Buffers) and functions become `[REDACTED]` while any registration is active.
1061
+
1062
+ Registration retains keys/values in memory for the process lifetime. Removed/rotated values stay protected. It does not protect prior logs, transformed/encoded credentials, direct console calls, third-party loggers or credentials never registered. Core's `secrets` store registers its encountered keys/values automatically. Keep credentials out of logs even with this protection enabled.
1063
+
1049
1064
 
1050
1065
  ## ship-logs-to-sentry `@warlock.js/logger/ship-logs-to-sentry/SKILL.md`
1051
1066
 
package/llms.txt CHANGED
@@ -13,7 +13,7 @@
13
13
  - [logger-basics](@warlock.js/logger/logger-basics/SKILL.md): Start here for @warlock.js/logger channels, structured entries, transports, and application logging setup.
14
14
  - [overview](@warlock.js/logger/overview/SKILL.md): @warlock.js/logger overview for orientation and choosing the focused skill for the task.
15
15
  - [pick-log-channel](@warlock.js/logger/pick-log-channel/SKILL.md): Pick one of the four built-in channels — ConsoleLog (terminal), FileLog (plain text on disk), JSONFileLog (structured JSON for aggregators like Loki / Datadog / Elastic), SentryLog (forwards errors + breadcrumbs to Sentry). Triggers: `ConsoleLog`, `FileLog`, `JSONFileLog`, `SentryLog`, `chunk`, `rotate`, `groupBy`, `maxFileSize`, `showContext`, `log.channel`; "log to a file", "rotate log files", "daily log chunks", "json logs for datadog / loki / elastic", "send logs to Sentry"; typical import `import { ConsoleLog, FileLog, JSONFileLog, SentryLog } from "@warlock.js/logger"`. Skip: Sentry-specific setup — the `ship-logs-to-sentry` topic; custom sinks — the `write-custom-log-channel` topic; registration — the `configure-logger` topic; competing libs `winston-daily-rotate-file`, `pino-pretty`.
16
- - [redact-sensitive-log-fields](@warlock.js/logger/redact-sensitive-log-fields/SKILL.md): Strip secrets from log output — a built-in secret-key denylist on by default (DEFAULT_REDACT_KEYS), plus two-layer additive redaction via log.configure({redact: {paths, keys}}) (logger floor) + per-channel redact (more on top). Dotted glob paths (*, **). Triggers: `redact`, `paths`, `keys`, `defaultKeys`, `censor`, `log.setRedact`, `applyRedact`, `maskEmail`, `maskEmailsInText`; "redact passwords in logs", "strip tokens from log output", "hide authorization headers", "scrub PII before logging", "turn off default redaction"; typical import `import { log } from "@warlock.js/logger"`. Skip: filtering — the `filter-log-entries` topic; custom sinks — the `write-custom-log-channel` topic; competing libs `pino.redact`, `fast-redact`.
16
+ - [redact-sensitive-log-fields](@warlock.js/logger/redact-sensitive-log-fields/SKILL.md): Strip secrets from log output — a built-in secret-key denylist on by default (DEFAULT_REDACT_KEYS), plus two-layer additive redaction via log.configure({redact: {paths, keys}}) (logger floor) + per-channel redact (more on top). Dotted glob paths (*, **). Triggers: `redact`, `paths`, `keys`, `defaultKeys`, `censor`, `log.setRedact`, `applyRedact`, `maskEmail`, `maskEmailsInText`, `registerLogSecret`, `maskRegisteredLogSecrets`; "redact passwords in logs", "strip tokens from log output", "hide authorization headers", "scrub PII before logging", "turn off default redaction"; typical import `import { log } from "@warlock.js/logger"`. Skip: filtering — the `filter-log-entries` topic; custom sinks — the `write-custom-log-channel` topic; competing libs `pino.redact`, `fast-redact`.
17
17
  - [ship-logs-to-sentry](@warlock.js/logger/ship-logs-to-sentry/SKILL.md): Forward log entries to Sentry with the SentryLog channel — error/warn become events (captureException/captureMessage), every other level a breadcrumb (no quota). @sentry/node is an OPTIONAL peer, lazily imported. Triggers: `SentryLog`, `@sentry/node`, `eventLevels`, `flushTimeout`, `Sentry.flush`, `captureException`, `addBreadcrumb`, `withScope`; "send logs to Sentry", "report errors to Sentry", "Sentry log channel", "Sentry breadcrumbs from logs", "log channel for Sentry"; typical import `import { SentryLog } from "@warlock.js/logger"`. Skip: file/console channels — the `pick-log-channel` topic; custom sinks — the `write-custom-log-channel` topic; graceful-shutdown flushing — the `flush-logs-on-shutdown` topic; Slack alerting recipe.
18
18
  - [test-logging-code](@warlock.js/logger/test-logging-code/SKILL.md): Test code that touches the logger — silence globally via log.setChannels([]) in setupFiles, assert specific log lines via a capturing LogChannel subclass (prefer it over vi.spyOn — it asserts on delivered entries, not just method calls, and isolates the shared singleton cleanly). Triggers: `log.setChannels`, `LogChannel`, `LoggingData`, `Logger`, `log.channels`; "silence logger in vitest", "assert a log line was emitted", "capture log output in tests", "test code that logs"; typical import `import { log, Logger, LogChannel, type LoggingData } from "@warlock.js/logger"`. Skip: custom sinks — the `write-custom-log-channel` topic; filtering — the `filter-log-entries` topic; competing `vi.spyOn(console)`, `jest.spyOn`.
19
19
  - [use-log-helpers](@warlock.js/logger/use-log-helpers/SKILL.md): Two DX shortcuts on every Logger — log.assert(condition, module, action, message, context?) logs an error when condition is falsy (free on the happy path), log.timer(module, action) returns an end-function emitting an info entry with measured duration. Triggers: `log.assert`, `log.timer`, `durationMs`; "assert an invariant via logger", "measure how long an operation took", "time a request", "log operation duration"; typical import `import { log } from "@warlock.js/logger"`. Skip: basics — the `logger-basics` topic; filtering — the `filter-log-entries` topic; competing `console.assert`, `console.time`, `console.timeEnd`, `perf_hooks.performance.now`.
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "dependencies": {
5
5
  "@mongez/copper": "^2.1.3",
6
6
  "@mongez/reinforcements": "^4.0.2",
7
- "@warlock.js/fs": "5.32.0",
7
+ "@warlock.js/fs": "5.34.0",
8
8
  "dayjs": "^1.11.9",
9
9
  "safe-stable-stringify": "^2.5.0"
10
10
  },
@@ -33,7 +33,7 @@
33
33
  "warlock": {
34
34
  "environment": "server"
35
35
  },
36
- "version": "5.32.0",
36
+ "version": "5.34.0",
37
37
  "main": "./cjs/index.cjs",
38
38
  "module": "./esm/index.mjs",
39
39
  "types": "./esm/index.d.mts",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: redact-sensitive-log-fields
3
- description: 'Strip secrets from log output — a built-in secret-key denylist on by default (DEFAULT_REDACT_KEYS), plus two-layer additive redaction via log.configure({redact: {paths, keys}}) (logger floor) + per-channel redact (more on top). Dotted glob paths (*, **). Triggers: `redact`, `paths`, `keys`, `defaultKeys`, `censor`, `log.setRedact`, `applyRedact`, `maskEmail`, `maskEmailsInText`; "redact passwords in logs", "strip tokens from log output", "hide authorization headers", "scrub PII before logging", "turn off default redaction"; typical import `import { log } from "@warlock.js/logger"`. Skip: filtering — the `filter-log-entries` topic; custom sinks — the `write-custom-log-channel` topic; competing libs `pino.redact`, `fast-redact`.'
3
+ description: 'Strip secrets from log output — a built-in secret-key denylist on by default (DEFAULT_REDACT_KEYS), plus two-layer additive redaction via log.configure({redact: {paths, keys}}) (logger floor) + per-channel redact (more on top). Dotted glob paths (*, **). Triggers: `redact`, `paths`, `keys`, `defaultKeys`, `censor`, `log.setRedact`, `applyRedact`, `maskEmail`, `maskEmailsInText`, `registerLogSecret`, `maskRegisteredLogSecrets`; "redact passwords in logs", "strip tokens from log output", "hide authorization headers", "scrub PII before logging", "turn off default redaction"; typical import `import { log } from "@warlock.js/logger"`. Skip: filtering — the `filter-log-entries` topic; custom sinks — the `write-custom-log-channel` topic; competing libs `pino.redact`, `fast-redact`.'
4
4
  ---
5
5
 
6
6
  # Redaction — keeping secrets out of logs
@@ -35,7 +35,7 @@ log.configure({
35
35
 
36
36
  **A channel cannot turn the default set off** (it can only add keys, or turn it back _on_ if the logger-wide config disabled it) — same additive-only contract as paths, below. And `log.setRedact(undefined)` clears _your_ paths, not the default denylist.
37
37
 
38
- Not reachable by any layer: secrets interpolated into a `message` string (`` `token=${t}` ``), `Map`/`Set`/`Buffer` contents, and getter-backed or non-enumerable properties.
38
+ Key/path redaction cannot reach secrets interpolated into strings, opaque container contents, or non-enumerable properties. Register known credentials with `registerLogSecret()` (below) for an additional safety floor.
39
39
 
40
40
  ## Layers 1 & 2 — path globs, opt-in
41
41
 
@@ -184,3 +184,18 @@ CR/LF/tab become `\r`/`\n`/`\t`, other control characters `\uXXXX`, ANSI
184
184
  sequences are removed; `maxLength` cuts and marks `…[truncated]`. `warlock
185
185
  check` (from `@warlock.js/core`) reports raw emails, credentials and request
186
186
  bodies in log calls as `WL9008` and accepts these helpers.
187
+
188
+ ## Registered credentials (since 5.33)
189
+
190
+ ```ts
191
+ import { registerLogSecret, maskRegisteredLogSecrets, log } from "@warlock.js/logger";
192
+
193
+ registerLogSecret("provider-credential", ["vendorPrivateRef"]);
194
+ log.info("sample", "request", "using provider-credential", { vendorPrivateRef: "hidden" });
195
+ // "using [REDACTED]", { vendorPrivateRef: "[REDACTED]" }
196
+ const safeText = maskRegisteredLogSecrets("using provider-credential");
197
+ ```
198
+
199
+ Keys are normalized; values are exact literal substrings (punctuation is literal, longer matches win). Empty values are ignored. This adds a final safety floor after censors in every Logger instance: `defaultKeys: false` and permissive censors cannot disable it. Error messages/stacks/causes, property names, Maps/Sets and channel diagnostics are protected. The safety pass clones without invoking getters/serializers; opaque objects (including Buffers) and functions become `[REDACTED]` while any registration is active.
200
+
201
+ Registration retains keys/values in memory for the process lifetime. Removed/rotated values stay protected. It does not protect prior logs, transformed/encoded credentials, direct console calls, third-party loggers or credentials never registered. Core's `secrets` store registers its encountered keys/values automatically. Keep credentials out of logs even with this protection enabled.