Skip to content

v3: one otel option, transport 0.29+, generic error shaping - #157

Open
cuzzlor wants to merge 7 commits into
mainfrom
feat/v3
Open

cuzzlor wants to merge 7 commits into
mainfrom
feat/v3

Conversation

@cuzzlor

@cuzzlor cuzzlor commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

Closes #156.

v3 puts OpenTelemetry behind one createLogger option, otel, and supports @opentelemetry/winston-transport 0.29 and later only. Merging publishes 3.0.0 as latest. Squash-merge: the intermediate commits do not each pass.

Breaking changes

  • flatten, flattenReplacer and mapAuditLevelForOtel are removed. They are type errors, and createLogger throws if one is passed, so options built from config cannot fall back to nested output without a warning.
  • @opentelemetry/winston-transport is an optional peer dependency at >=0.29. npm 7 and later refuse to install it beside an older transport.
  • With otel, the audit mapping runs last, so a loggerOptions.format sees LEVEL: 'audit'.
  • A Date under otel is written unquoted.

What changed

Area Change
createLogger otel?: boolean | OtelAttributesFormatOptions appends otelAttributesFormat as the last logger-level format.
otelAttributesFormat Maps audit to info severity and writes logLevel (mapAuditLevel, default on). Adds an opt-in maxAttributeLength cap that ends in [Truncated].
createErrorSerializer New. omit(key, error) leaves properties out of every error. dedupe writes a shared object once. serializeError is this factory with no options.
Audit guard Applies only to the logger-level otel placement. On a transport's own format the transport filters by level before the format runs, so level: 'audit' is safe there.
Lint Library source cannot import @opentelemetry/*, so the optional peer cannot become a real dependency.
Real-transport spec Runs on 0.29 and the latest line under npm aliases. Covers 0.34's severityMapping and logSeverity, and pins the transport's SPLAT exception fallback.
README OpenTelemetry section rewritten, "What audit means", an AI SDK example built from generic options, and "Migrating from v2".

The library has no knowledge of any consumer's libraries. The AI SDK setup (redact requestBodyValues, drop responseHeaders and a repeated lastError, cap at the App Insights limit) is a README example built from redactPaths, createErrorSerializer and maxAttributeLength. The real-transport spec runs that example.

Release

  • v2.x is cut from 2.3.0 for fixes only. Its publish workflow runs by hand and publishes under the latest-2 dist-tag, so a 2.x release never moves latest. PR CI now also runs for PRs into v2.x.
  • After release:
    • makerx-reports #225: drop mapAuditLevelForOtel.
    • graphql-template-esm: flatten becomes otel: true.
    • MakerBOS #1612: move the transport to 0.29+ and the SDK to 0.219+ in the same PR, and replace its serializer with createErrorSerializer({ omit }).

Verification

  • npm run build: lint, types, rollup, attw and the CJS smoke test pass.
  • npm test: 232 tests pass.
  • npm run audit passes.
  • npm pack of dist installed in a scratch project: refused beside transport 0.27, installs beside 0.34.

…pacts retries and caps strings

Adds mapAuditLevel, redactKeys, redactedValue, compactErrors and
maxAttributeLength options, all on by default. Adds compactErrorSerializer
and defaultOtelRedactKeys exports.
… otel

createLogger throws when a removed option is passed. The level: 'audit'
guard now applies only to the logger-level otel placement.
…l peer, release 3.0.0

The real-transport spec runs on 0.29 and the latest line under npm aliases.
Lint forbids OpenTelemetry imports in library source. PR CI also runs for
the v2.x branch.
otelAttributesFormat no longer redacts requestBodyValues, compacts retries
or caps strings by default: redactKeys, redactedValue, compactErrors,
defaultOtelRedactKeys and compactErrorSerializer are removed.

- createErrorSerializer({ omit, dedupe }) leaves properties out of every
  error, or writes a shared object once. serializeError is its default.
- maxAttributeLength is off by default.
- The README shows the AI SDK setup as an example built from redactPaths,
  createErrorSerializer and maxAttributeLength, and the transport spec
  runs that example on 0.29 and the latest line.

@cuzzlor cuzzlor left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dual review summary

Findings: 8 (blocker 0, major 1, minor 5, nit 2)

The change is coherent. One otel option replaces three, createErrorSerializer is a small extension of the existing walk, and the real-transport spec runs on both 0.29 and 0.34. The main risk is an audit-severity regression: the audit mapping now runs after loggerOptions.format but compares the mutable info.level, so a format such as format.colorize() stops audit records from being mapped. The upgrade docs also miss that otelAttributesFormat now maps audit by default. The reviewers disagreed on overall quality: Claude found no code defect, and GPT found the audit regression. On omit being called for plain error-shaped objects, they agreed on the diagnosis but disagreed on the fix.

Findings

  • major: Audit mapping fails after a format that changes info.level (gpt-only)
  • minor: omit is called for plain objects that look like errors (disputed)
  • minor: Migration guide does not mention the new audit-mapping default (claude-only)
  • minor: The claim that two api-logs copies drop every line is wrong in most cases (claude-only)
  • minor: Surrogate-pair test does not exercise the surrogate guard (claude-only)
  • minor: A maxAttributeLength below 11 is exceeded (gpt-only)
  • nit: Warning about mapAuditLevel: false applies only when logSeverity is set (claude-only)
  • nit: jsonStringifyValuesFormat JSDoc still recommends it for the OpenTelemetry transport (claude-only)

Findings not anchored to the diff

No line comment could be attached to these findings.

  • nit: jsonStringifyValuesFormat JSDoc still recommends it for the OpenTelemetry transport
    • Impact: The JSDoc at src/json-stringify-values-format.ts:5-7 still names "OTEL + Azure Log Analytics" as the use case, but 3.0 supports only transport 0.29 and later, where this format turns an error into one exception.message string (src/otel-transport.spec.ts:193), and IDE users see this text rather than the updated README row at README.md:376.
    • Recommendation: Match the README: say the format is for sinks other than the OpenTelemetry transport, and that the transport needs otelAttributesFormat.

Generated by dual-review — Claude + litellm/azure/gpt-5.6-sol.

Comment thread src/audit-level.ts Outdated
Comment thread src/serialize-error.ts Outdated
Comment thread README.md
Comment thread README.md Outdated
Comment thread src/otel-attributes-format.spec.ts Outdated
Comment thread src/otel-attributes-format.ts Outdated
Comment thread README.md Outdated
- Read the audit level from LEVEL, so a format such as colorize() before
  otel no longer stops audit records being mapped. Keep an existing logLevel
  so a second pass stays idempotent.
- Cap a string to as much of [Truncated] as fits when maxAttributeLength is
  shorter than the marker, and cut nothing for a negative or NaN limit.
- Make the surrogate-pair test cut inside a pair.
- Document that omit also runs for plain objects with a string name,
  message and stack.
- README: cover the audit-mapping default in Migrating from v2, state when
  two api-logs copies drop lines, and make the severityMapping warning
  unconditional. Point jsonStringifyValuesFormat users at
  otelAttributesFormat for the OpenTelemetry transport.
@cuzzlor

cuzzlor commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

The unanchored nit from the review, the jsonStringifyValuesFormat JSDoc that still recommended it for OpenTelemetry, is fixed in 08cf9f7. The JSDoc now says not to use it for @opentelemetry/winston-transport and points at otelAttributesFormat, matching the README. All eight review findings are addressed.

@cuzzlor
cuzzlor marked this pull request as ready for review October 16, 2026 08:37
@cuzzlor
cuzzlor requested review from mderriey and robdmoore October 16, 2026 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

v3 roadmap

2 participants