Skip to content

feat: app-level instrumentation#236

Open
LucasAlvesSoares wants to merge 9 commits into
mainfrom
app-level-instrumentation
Open

feat: app-level instrumentation#236
LucasAlvesSoares wants to merge 9 commits into
mainfrom
app-level-instrumentation

Conversation

@LucasAlvesSoares

@LucasAlvesSoares LucasAlvesSoares commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Description

Introduces a library instrumentation layer to the SDK's telemetry module. Instead of relying solely on framework-level auto-instrumentation, the SDK now instruments common HTTP clients, web frameworks, and data libraries directly, ensuring spans are created and baggage/context is propagated correctly regardless of how the service is deployed.

The implementation follows an extensible registry pattern:

  • LibraryInstrumentor — abstract base class with instrument(), uninstrument(), and is_instrumented(). The public methods handle guards (library not installed, already instrumented); subclasses only implement the inner logic.
  • _registry — a module-level list. Any code (including third-party contributors) can call register() to add a new instrumentor.
  • instrumentors/ — one file per library. Each file creates an instrumentor instance and calls register() at module load time.
  • auto_instrument() — now calls all registered instrumentors after the tracer provider is initialized.

Libraries instrumented out of the box:

Library Dep type
httpx, requests, grpcio Hard (already SDK dependencies)
starlette, fastapi Optional [starlette], [fastapi]
aiohttp Optional [aiohttp]
sqlalchemy, redis Optional [sqlalchemy], [redis]
django, flask Optional [django], [flask]

The OTEL contrib instrumentation packages (opentelemetry-instrumentation-*) are hard dependencies — they are always installed with the SDK. The target frameworks remain optional extras, as they are today.

Adding a new instrumentor requires only creating a single file in instrumentors/ and calling register() — no other changes needed.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • Dependency update

How to Test

  1. Install the SDK with an optional extra, e.g. pip install sap-cloud-sdk[starlette]
  2. Call auto_instrument() at application startup
  3. Make an outbound HTTP request via httpx or requests, or serve an inbound request via Starlette/FastAPI/Django/Flask
  4. Observe that spans are created for those calls and that W3C baggage from upstream requests is propagated into the trace context
  5. Install without an optional extra (e.g. no starlette) and verify startup does not raise ImportError

Checklist

  • I have read the Contributing Guidelines
  • I have verified that my changes solve the issue
  • I have added/updated automated tests to cover my changes
  • All tests pass locally
  • I have verified that my code follows the Code Guidelines
  • I have updated documentation (if applicable)
  • I have added type hints for all public APIs
  • My code does not contain sensitive information (credentials, tokens, etc.)
  • I have followed Conventional Commits for commit messages

Additional Notes

The grpcio instrumentor instruments both client and server interceptors (GrpcInstrumentorClient and GrpcInstrumentorServer) since the same package is used for both roles.

All opentelemetry-instrumentation-* packages are pinned with ~=0.63b1, the same compatible-release style used for the existing OTEL exporters

@LucasAlvesSoares LucasAlvesSoares changed the title App level instrumentation feat: app-level instrumentation Jul 20, 2026
@LucasAlvesSoares
LucasAlvesSoares marked this pull request as ready for review July 21, 2026 08:26
@LucasAlvesSoares
LucasAlvesSoares requested a review from a team as a code owner July 21, 2026 08:26
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