Skip to content

feat(otel): add OpenTelemetry instrumentation support#28

Merged
erikhoward merged 4 commits intomainfrom
feat/otel-instrumentation
Mar 17, 2026
Merged

feat(otel): add OpenTelemetry instrumentation support#28
erikhoward merged 4 commits intomainfrom
feat/otel-instrumentation

Conversation

@erikhoward
Copy link
Member

Summary

  • Add optional OpenTelemetry instrumentation for LLM requests via new contrib/otel package
  • Create ContextualTelemetryHook interface for context-aware telemetry (backward compatible)
  • Support GenAI semantic conventions for PetalTrace and standard observability tools

Changes

Core (core/)

  • Add ContextualTelemetryHook interface extending TelemetryHook with context support
  • Update GetResponse(), Stream(), and wrapStreamWithTelemetry() to use contextual hooks when available

New Package (contrib/otel/)

  • Hook implementation that creates OTel spans for LLM requests
  • GenAI semantic convention attributes (gen_ai.system, gen_ai.request.model, gen_ai.usage.*)
  • Configurable options: custom tracer provider, span name function, additional attributes

Usage

import irisotel "github.com/petal-labs/iris/contrib/otel"

hook := irisotel.New()
client := core.NewClient(provider, core.WithTelemetry(hook))
// All LLM calls now emit OTel spans

Test plan

  • All existing core tests pass (backward compatibility)
  • New contextual telemetry hook tests pass
  • OTel hook tests verify span creation, attributes, error handling, context propagation

🤖 Generated with Claude Code

erikhoward and others added 4 commits March 16, 2026 20:16
Add optional OpenTelemetry instrumentation for LLM requests through a new
contrib/otel package. This enables automatic span creation for all provider
calls with GenAI semantic convention attributes.

Changes:
- Add ContextualTelemetryHook interface to core/telemetry.go for context-aware
  telemetry hooks that need access to context.Context
- Update core/client.go to detect and use ContextualTelemetryHook when available
- Create contrib/otel package with Hook implementation that creates OTel spans
- Support GenAI semantic conventions (gen_ai.system, gen_ai.request.model,
  gen_ai.usage.input_tokens, gen_ai.usage.output_tokens)
- Add configuration options: custom tracer provider, span name function,
  additional attributes, error recording control

The implementation is fully backward compatible - existing TelemetryHook
implementations continue to work unchanged.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix staticcheck SA1029 lint error by using a custom type instead of
a string literal as the context key in telemetry tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Downgrade OpenTelemetry dependencies from v1.42.0 to v1.34.0
  to support Go 1.24 (v1.42.0 requires Go >= 1.25)
- Remove contrib/otel from go.work to fix golangci-lint
  "no go files to analyze" error in CI
- The contrib/otel package still works with GOWORK=off and when
  used as a standalone module

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The contrib/otel module is a separate Go module with its own
go.mod and dependencies. Gosec cannot resolve its OTel imports
when scanning from the root workspace.

Exclude the contrib directory from gosec since these modules
should be scanned independently if needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@erikhoward erikhoward merged commit 18e4e74 into main Mar 17, 2026
6 checks passed
@erikhoward erikhoward deleted the feat/otel-instrumentation branch March 17, 2026 03:37
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