Repository navigation
feat: add flatten: 'otel' and otelAttributesFormat for winston-transport 0.29+ (2.3.0) - #154
Merged
Merged
Conversation
…ort 0.29+
From 0.29, @opentelemetry/winston-transport lifts an `err`/`error` value off
the record and hands it to the logs SDK as the exception, which keeps only
name, message, stack and a cause's message. So:
- `flatten: true` stringifies the error first, and the SDK records the whole
JSON as one `exception.message`, with no type or stack trace.
- No flattening records the exception but drops the rest of the error
(status, provider data, cause chain), and 0.32+ sends other objects as
nested maps that Log Analytics does not index.
`otelAttributesFormat` keeps the error an object with only the fields the
SDK reads, moves the rest to `<key>Detail` as JSON (code too, since the SDK
prefers a truthy code over name for exception.type), and stringifies every
other object value; a Date becomes its unquoted ISO string. It can sit on
the transport, keeping other transports nested, or be applied for every
transport with `createLogger({ flatten: 'otel' })` — the only option with
WinstonInstrumentation, which constructs its transport without a format.
`flatten: true` is unchanged and documented as the mode for transports
before 0.29. The README gains a transport-line matrix. A new spec drives
the real transport at 0.27, 0.31 and 0.34 (npm aliases) into the logs SDK
and asserts the exported attributes, including the two failure modes above.
2 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #153 (2.2.1). Merge that first; GitHub then retargets this PR to
main. Merging this one alone would ship both changes as 2.3.0.Why
flatten: truewas written for a transport that copied attributes through as they were.@opentelemetry/winston-transporthas changed twice since:err/erroroff the record and gives it to the logs SDK as the exception (contrib#3441). The SDK keeps onlyname,message,stack(asexception.type/message/stacktrace) and a cause's message (error.cause.*).Errors into maps (contrib#3672). It does not stringify them.On 0.29 and later neither existing option is right, and the new spec proves both against the real transport:
flatten: truestringifies the error before the transport sees it, so the SDK records the whole JSON as oneexception.message, with noexception.typeor stack. This is the[object Object]-era shape seen in production on makerx-reports (MakerXStudio/makerx-reports#225).What
otelAttributesFormat()shapes a record for 0.29 and later:error(orerr, matching the transport's precedence) stays an object with onlyname,message,stack, and a cause the transport can describe. Everything else, including the full cause chain, goes toerrorDetailas JSON.codegoes toerrorDetailtoo, because the SDK takes a truthycodeovernameasexception.type. It stays when the error has noname.Datebecomes its ISO string, unquoted. Errors nested elsewhere are serialised, BigInts are written as<n>n, and nothing throws out of the log call.Two ways to apply it, one implementation:
The README's OpenTelemetry section is rewritten around a transport-line matrix:
flatten: true/jsonStringifyValuesFormatbefore 0.29,flatten: 'otel'/otelAttributesFormatfrom 0.29.Compatibility
2.3.0 — minor.
flatten?: booleanwidens toboolean | 'otel';flatten: trueand every other default are unchanged, so no existing consumer's output moves until it opts in.flattenReplacerapplies in both modes.No peer dependency on the transport is added: consumers on a transport before 0.29 legitimately keep
flatten: true, and a peer range would warn them for it.Next (not in this PR)
A 3.0.0 could make the OTel shape the default for
flattenand dropflatten: truefromcreateLogger(keepingjsonStringifyValuesFormatexported), with transport 0.29 as the supported minimum. That is a deliberate output change for a major.Consumers
flattenForOtelwithotelAttributesFormat()on the transport.jsonStringifyValuesFormat()on the transport until its OTel SDK moves past 0.218.WinstonInstrumentation): moves fromflatten: truetoflatten: 'otel'.Test plan
npm run build— lint,tsc, rollup,attw --pack, CJS smoke testnpm run auditclean (the audit fix is in fix: keep a Date in log metadata instead of writing {} (2.2.1) #153)npm test— 185 tests. New:otel-attributes-format.spec.ts(16, the format on its own) andotel-transport.spec.ts(15), which drives the real transport at 0.27, 0.31 and 0.34, installed under npm aliases, into an in-memory logs SDK and asserts the exported attributes — including both failure modes above, so a future transport change shows up here first