evlog@2.30.0
Minor Changes
-
#743
9000215Thanks @evlogai! - Add a default export soimport logger from 'evlog'works like pino and consola: every call prints immediately, with noinitLogger()needed. It is the barelogAPI under the default slot, sologger.info('tag', 'message'),logger.info('message')andlogger.info({ event })all output right away. For wide events with drains and sampling,initLogger()andcreateLogger()stay the documented path.Running in production without
initLogger()now warns once on the first emitted event, pointing atinitLogger({ drain }): without it events carry the default service and environment, skip redaction, and reach no drain. Apps that already callinitLogger()see no change. -
#731
46cad75Thanks @evlogai! - Add anenrichTurnoption todefineEvlogHook()inevlog/eve. It runs once per turn where the turn logger is created, with the eve session in scope, so enrichers can reachctx.session.authand the session lineage instead of only HTTP-shaped context. Returned fields merge onto the turn event over the built-ineve,agentandchannelfields, and stay turn-scoped: they are not carried across turns of the same session. The existingenrichoption keeps its HTTP-shaped context. -
#754
aebed60Thanks @HugoRCD! -evlognow ships theevlogexecutable: once evlog is installed,npx evlog init,npx evlog map,npx evlog doctorandnpx evlog agentsare available without adding anything. The executable runs@evlog/cliwhen it is installed and otherwise fetches it with the package manager that launched it (npx,pnpm dlx,bunx,yarn dlx), soevloggains no dependency. Add@evlog/clias a dev dependency for a pinned, instant run in CI.@evlog/clinow declaresevlogas a peer dependency instead of a dependency, so a project carries one copy of the logger. -
#742
3fc8c1fThanks @evlogai! - Addfatalandtracelog levels.log.fatal()emits an error-level event that sampling always keeps, andlog.trace()emits a debug-level event that is dropped by default; opt in withsampling.rates.trace. Both levels flow through console output, colors, OTLP severity mapping, Datadog status mapping and the ingest validation, and the request logger acceptsfatal()andtrace()entries (tracenever raises the event level,fatalescalates it aboveerror). -
#748
7af9cafThanks @HugoRCD! - Align the OTLP adapter with the OpenTelemetry exporter specification.createOTLPDrain()now readsOTEL_EXPORTER_OTLP_LOGS_ENDPOINT(used as the full logs URL, without appending/v1/logs),OTEL_EXPORTER_OTLP_LOGS_HEADERS(merged overOTEL_EXPORTER_OTLP_HEADERS) andOTEL_RESOURCE_ATTRIBUTES, so a deployment already configured for an OTel SDK needs no evlog-specific variables. A newcompression: 'gzip'option, also read fromOTEL_EXPORTER_OTLP_[LOGS_]COMPRESSION, gzips the request body.Fix attribute encoding in the OTLP, HyperDX and PostHog adapters: non-integer numbers are sent as
doubleValueinstead of strings, and arrays of a single primitive type asarrayValue, so backends can aggregate and filter on them. Malformed or all-zerotraceId/spanIdvalues are kept as attributes instead of being placed in the record's trace fields, where collectors reject them. Events that differ inversion,regionorcommitHashno longer share a resource, and the instrumentation scope carries the evlog version. -
#750
5e0d543Thanks @HugoRCD! - Addprotocol: 'http/protobuf'to the OTLP adapter for collectors and gateways that only accept protobuf. The protocol is also read fromOTEL_EXPORTER_OTLP_LOGS_PROTOCOLandOTEL_EXPORTER_OTLP_PROTOCOL. The encoder has no dependencies and is loaded only when selected; it is also exported asencodeOTLPLogsRequest()fromevlog/otlp/protobuf. Integers outside the safe integer range are now sent asdoubleValueinstead of a roundedintValue. -
#749
11e1d4fThanks @HugoRCD! -createTraceContextEnricher()no longer setsevent.spanIdfrom an incomingtraceparent. That span belongs to the caller, so linking the event to it pointed log-to-span correlation one level too high. The id is now recorded asevent.parentSpanId(andtraceContext.parentSpanId), andevent.spanIdis left for your tracer to set from the active server span, for exampletrace.getActiveSpan()?.spanContext().spanIdwith OpenTelemetry. If you relied on the enricher forspanIdin the OTLP or Datadog adapters, set it from the active span.The OTLP adapter's default
jsonrecord shape now sends nested objects as OTLP key-value lists (kvlistValue) instead of JSON strings, so collectors and backends can read their fields. Thecompactshape is unchanged.A new
semanticConventions: trueoption oncreateOTLPDrain()adds OpenTelemetry semantic convention attributes next to the evlog field names:http.request.method,url.path,http.response.status_code,user_agent.original,exception.*andgen_ai.*(model, provider, response id, token usage, finish reasons), plus thedeployment.environment.nameresource attribute. It becomes the default in the next major.
Patch Changes
-
#725
543b00fThanks @HugoRCD! - Allow Eve agents to disable subagent lifecycle subscriptions withsubagentEvents: falsewhen those events do not carry hook session context. -
#764
24ffe06Thanks @HugoRCD! - MeasuredurationMsbefore tail-samplingkeephooks run, so a hook that awaits I/O no longer inflates the request duration on the emitted event. -
#741
fe75141Thanks @evlogai! - Support printf-style interpolation inlogmessages:%s,%d, and%jin a message string are formatted with the extra arguments, matching node'sutil.formatsemantics for the supported specifiers. Interpolation applies to the message only, never to field values, and the formatter stays tree-shakeable. -
#738
5b4a493Thanks @jamalkamaladdin! - Serialize anErrorinerror.causethe same way as the top-level error, withname,message,stackand its metadata fields. A wrapped driver error such as thepgerror inside aDrizzleQueryErrorno longer reaches drains as{}, and a cause chain that loops back emits[Circular]. -
#764
24ffe06Thanks @HugoRCD! - Write the console line after enrichers run. Fields added inenrich(UserAgent, Geo, TraceContext,@evlog/signalsverdicts, your own plugins) now appear in stdout and in platform logs such as Vercel, not only in drains. Events that neither enrich nor drain are printed as before.