span-events-to-logs-migration
Span Events to Logs Migration
Use this skill to migrate instrumentation from the deprecated Span Event API (AddEvent, RecordException) to the Logs API, following the OTEP 4430 deprecation plan.
Background
The OpenTelemetry project is deprecating Span.AddEvent and Span.RecordException in favor of emitting events and exceptions through the Logs API. The Span Event API is deprecated, but Span Events as a concept remain valid -- they are now emitted via logs that correlate to the active span.
See references/deprecation-plan.md for the full context.
Workflow
- Prepare before migrating.
- check the project's OpenTelemetry SDK version supports log-based events (check the
manual-instrumentationskill's version index if available) - identify whether the project has a LoggerProvider configured; if not, one must be set up
- determine if downstream consumers (backends, dashboards, alerts) depend on span events appearing in the span proto envelope
- Scan the codebase for span event usage.
- search for
AddEvent,add_event,addEvent,RecordException,record_exception,recordException, and language-specific variants - categorize each call site: general event, exception recording, or informational annotation
- note the span context, attributes, and timestamp usage at each site
- Classify each call site using the decision tree.
- see
references/decision-tree.mdfor the full classification logic - the three outcomes are: migrate to log-based event, convert to span attributes, or remove
- Apply the migration for each call site.
- see
references/migration-patterns.mdfor language-specific before/after patterns - ensure the replacement log record carries the correct span context, event name, attributes, and timestamp
- for exceptions, preserve the applicable semconv attributes:
exception.typeandexception.message(at least one is required), plusexception.stacktracewhen the language/error type makes it meaningful (in Go, omit it unless an error library preserves the origin stack -- do not callruntime.Stackat the emit site)
- If backward compatibility is needed, configure the SDK bridge.
- see
references/backward-compat.md - this is an SDK-level log processor that converts log-based events back to span events
- only needed when downstream systems require span events in the same proto envelope as the span
- Verify the migration.
Required Completion Loop
Follow this loop every time:
- scan and classify all span event call sites
- migrate each call site following the decision tree and patterns
- review the changed code against the checklist below
- re-open the changed files and confirm each checklist item with codebase evidence
- if any item is unresolved, patch the code or mark it not applicable with a reason, then repeat the review
- do not finish until every checklist item is completed or explicitly marked not applicable
Do not mark a checklist item complete based on intent alone. Mark it complete only after confirming it in the current codebase.
Migration Checklist
For every item, report one of these statuses in the final answer:
[x]completed[~]not applicable, with a reason[ ]unresolved
Include file references as evidence for every completed item.
[ ]AllAddEvent/add_event/addEventcall sites identified and classified.[ ]AllRecordException/record_exception/recordExceptioncall sites identified and classified.[ ]A LoggerProvider is configured in the SDK setup (or already existed).[ ]Each migrated event uses the Logs API with the correct event name and attributes.[ ]Each migrated exception preserves the applicable semconv attributes:exception.typeandexception.message(at least one is required), plusexception.stacktracewhen the language/error type makes it meaningful.[ ]Migrated log records carry the active span context for trace correlation.[ ]Call sites classified as "convert to span attributes" now use span attributes instead.[ ]Call sites classified as "remove" have been removed with justification.[ ]Backward compatibility bridge is configured if downstream systems require span events in the span envelope.[ ]No remaining references to the deprecatedAddEventorRecordExceptionAPIs unless intentionally kept for the current major version.[ ]The changed files were re-read after implementation to verify the final state.[ ]The final answer includes this checklist, file evidence, and any remaining risks or gaps.
Final Review Format
In the final answer, include the checklist in this format:
[x]LoggerProvider configured. Evidence:src/telemetry/setup.go:42-- added OTLP log exporter with batch processor.[~]Backward compatibility bridge. Reason: no downstream systems depend on span events in the proto envelope.[ ]Exception migration. Missing evidence; re-check required.
More from ollygarden/opentelemetry-agent-skills
sdk-setup
OpenTelemetry SDK initialization and configuration. Use when setting up or reviewing TracerProvider, MeterProvider, or LoggerProvider; choosing exporters, processors, or propagators; configuring OTLP transport; or extending an existing SDK setup for new signals. Use this skill whenever the task involves wiring up the OpenTelemetry SDK, even if the user only mentions "add tracing" or "set up metrics" without saying "SDK.
8telemetrygen
Construct telemetrygen commands for generating synthetic OpenTelemetry traces, metrics, and logs via OTLP. Use this skill whenever the user wants to generate test telemetry, load test a collector or backend, create synthetic OTLP data, send sample traces/metrics/logs to an endpoint, test collector pipelines or processors, validate OTTL transforms, test tail sampling, or mentions telemetrygen in any context. Also trigger when the user asks how to simulate telemetry traffic, stress test an observability stack, or produce sample data for dashboards.
8sdk-versions
OpenTelemetry SDK and package version lookup across languages. Use when choosing the latest compatible released OpenTelemetry SDK or package version and locating setup docs or examples.
8semantic-conventions
OpenTelemetry semantic convention lookup and naming guidance. Use when selecting released semantic convention groups, attributes, or span naming rules, or when checking semantic convention compliance.
8manual-instrumentation
OpenTelemetry best practices for manual instrumentation. Use when adding, changing, or reviewing OpenTelemetry instrumentation in code. Guidance to choose runtime boundaries, choose signals, apply semantic conventions, handle propagation, control cardinality, and verify the result.
8otel-js
OpenTelemetry in Node.js / JavaScript / TypeScript — NodeSDK, declarative YAML configuration, auto-instrumentations, ESM vs CJS import patterns. Use when adding, reviewing, or configuring OpenTelemetry in a Node.js service. Triggers on "setup otel in node", "js telemetry", "node tracing setup", "NodeSDK", "auto instrumentation node", "TracerProvider node", or any Node.js-related OTel question.
2