git:20260815.474f624 to git:20260827.e38e545

3 added, 3 removed. Audit A to A.

---
name: otel-span-events-to-logs-migration
description: Migrate OpenTelemetry Span Events (AddEvent, RecordException, and language equivalents) to the Logs API following the accepted OTEP 4430 migration plan. Use when migrating instrumentation from span events to log-based events, reviewing code that still uses AddEvent or RecordException, or planning a codebase migration while preserving trace correlation.
---
# Span Events to Logs Migration
Use this skill to migrate instrumentation from the Span Event API (`AddEvent`, `RecordException`, and language equivalents) to the Logs API, following the accepted [OTEP 4430 deprecation plan](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/oteps/4430-span-event-api-deprecation-plan.md).
## Background
The OpenTelemetry project accepted a plan to deprecate `Span.AddEvent` and `Span.RecordException` in favor of emitting events and exceptions through the Logs API. Span Events as a concept remain valid -- they can be emitted via logs that correlate to the active span, and optionally bridged back into the span proto.
- Status as of 2026-08-13: OTEP 4430 is accepted, log-based event/exception emission is specified in the Logs API, and the SDK "event to span event bridge" is specified with Development status. The trace API methods `AddEvent`/`RecordException` are not yet formally marked Deprecated in the specification -- that step is still pending. Treat existing span-event calls as migration candidates, not automatically invalid code; some SDK-specific equivalents have already changed status (for example OpenTelemetry .NET's `Activity.RecordException` extension is `[Obsolete]` in favor of `Activity.AddException`, which is still a span-event API).
+ Status as of 2026-08-26: OTEP 4430 is accepted, log-based event/exception emission is specified in the Logs API, and the SDK "event to span event bridge" is specified with Development status. The trace API methods `AddEvent`/`RecordException` are not yet formally marked Deprecated in the specification -- that step is still pending. Treat existing span-event calls as migration candidates, not automatically invalid code; some SDK-specific equivalents have already changed status (for example OpenTelemetry .NET's `Activity.RecordException` extension is `[Obsolete]` in favor of `Activity.AddException`, which is still a span-event API).
See `references/deprecation-plan.md` for the full context.
## Workflow
0. Prepare before migrating.
- - check the project's OpenTelemetry SDK version supports log-based events (check the `manual-instrumentation` skill's version index if available)
+ - check the project's OpenTelemetry SDK version supports log-based events (check the `otel-sdk-versions` skill'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
1. Scan the codebase for span event usage.
- - search for `AddEvent`, `add_event`, `addEvent`, `RecordException`, `record_exception`, `recordException`, `RecordError`, `AddException`, and language-specific variants
+ - search for `AddEvent`, `add_event`, `addEvent`, `RecordException`, `record_exception`, `recordException`, `RecordError`, `record_error`, `AddException`, 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
2. Classify each call site using the decision tree.
- see `references/decision-tree.md` for the full classification logic
- the three outcomes are: migrate to log-based event, convert to span attributes, or remove
3. Apply the migration for each call site.
- see `references/migration-patterns.md` for language-specific before/after patterns
- ensure the replacement log record carries the correct span context, event name, attributes, and timestamp; for exceptions use the applicable semantic-convention event name (normally an operation-specific `.exception` name), reserving `exception` for generic handlers
- for exceptions, preserve the applicable semconv attributes: `exception.type` and `exception.message` (at least one is required), plus `exception.stacktrace` when the language/error type makes it meaningful (in Go, omit it unless an error library preserves the origin stack -- do not call `runtime.Stack` at the emit site)
4. 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
5. Verify the migration.
## Required Completion Loop
Follow this loop every time:
1. scan and classify all span event call sites
2. migrate each call site following the decision tree and patterns
3. review the changed code against the checklist below
4. re-open the changed files and confirm each checklist item with codebase evidence
5. if any item is unresolved, patch the code or mark it not applicable with a reason, then repeat the review
6. 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.
- `[ ]` All general span-event call sites identified and classified, including `AddEvent` / `add_event` / `addEvent` and language equivalents such as .NET `ActivityEvent`.
- `[ ]` All exception span-event call sites identified and classified, including `RecordException` / `record_exception` / `recordException` and language equivalents such as Go `RecordError`, Rust `record_error`, and .NET `AddException`.
- `[ ]` 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.type` and `exception.message` (at least one is required), plus `exception.stacktrace` when 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 span-event API call sites are left unintentionally; any retained `AddEvent` / `RecordException` / `RecordError` / `AddException` / `ActivityEvent` / equivalent call is justified for current-version compatibility.
- `[ ]` 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.