Skip to content

callbacks/otel: add OpenTelemetry callback handler#1506

Open
pm32900 wants to merge 2 commits into
tmc:mainfrom
pm32900:feature/otel-callback-handler
Open

callbacks/otel: add OpenTelemetry callback handler#1506
pm32900 wants to merge 2 commits into
tmc:mainfrom
pm32900:feature/otel-callback-handler

Conversation

@pm32900

@pm32900 pm32900 commented Jun 17, 2026

Copy link
Copy Markdown

Summary

Adds a new callbacks/otel package that implements the callbacks.Handler
interface and creates OpenTelemetry trace spans for LangChainGo lifecycle
events (LLM, chain, tool, retriever).

Motivation

LangChainGo has a clean callback interface but no first-class OpenTelemetry
integration. Production Go applications need standard observability — this
handler bridges that gap without touching any existing code or interfaces.

What's included

  • callbacks/otel/handler.go — the Handler struct implementing callbacks.Handler
  • callbacks/otel/options.go — functional options (WithTracerProvider, WithCaptureInput, WithCaptureOutput)
  • callbacks/otel/handler_test.go — unit tests using tracetest.SpanRecorder (no external services)
  • callbacks/otel/README.md — usage docs, privacy warning, instrumented events table
  • examples/otel-callback-example/ — runnable example with stdout exporter

Design decisions

  • Subpackage (callbacks/otel) so the go.opentelemetry.io/otel dependency
    is opt-in and does not affect users who don't need tracing
  • Falls back to the global OTel TracerProvider if none is supplied — works
    with zero configuration
  • No prompt/completion content captured by default — users must explicitly
    pass WithCaptureInput(true) / WithCaptureOutput(true)
  • Streaming (HandleStreamingFunc) is intentionally a no-op — per-chunk spans
    would be extremely noisy
  • GenAI semconv attribute keys (gen_ai.operation.name, gen_ai.usage.input_tokens, etc.)
    are local constants in one file, easy to update when otel/semconv stabilises them
  • No existing interfaces or files were changed

Testing

go test ./callbacks/otel/...   # all pass
go test ./callbacks/...        # no regressions
go vet ./callbacks/otel/...    # clean

References
OpenTelemetry GenAI semantic conventions: https://opentelemetry.io/docs/specs/semconv/gen-ai/
Existing callbacks.Handler interface: callbacks/callbacks.go
Modelled after the existing LogHandler style in callbacks/log.go


### PR Checklist

- [x] Read the [Contributing documentation](https://github.com/tmc/langchaingo/blob/main/CONTRIBUTING.md).
- [x] Read the [Code of conduct documentation](https://github.com/tmc/langchaingo/blob/main/CODE_OF_CONDUCT.md).
- [x] Name your Pull Request title clearly, concisely, and prefixed with the name of the primarily affected package you changed according to [Good commit messages](https://go.dev/doc/contribute#commit_messages) (such as `memory: add interfaces for X, Y` or `util: add whizzbang helpers`).
- [x] Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
- [x] Provide a description in this PR that addresses **what** the PR is solving, or reference the issue that it solves (e.g. `Fixes #123`).
- [x] Describes the source of new concepts.
- [x] References existing implementations as appropriate.
- [x] Contains test coverage for new functions.
- [ ] Passes all [`golangci-lint`](https://golangci-lint.run/) checks.

@pm32900

pm32900 commented Jun 30, 2026

Copy link
Copy Markdown
Author

Hi! Just checking in to see if there's anything I can update or clarify to help move this PR forward. Happy to make any requested changes. Thanks!

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.

1 participant