wip: Otel log correlation #412
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Airbyte Server - Automatic HTTP Request Tracing Implementation
Overview
This implementation adds automatic distributed tracing to all HTTP requests in the Airbyte server without requiring any changes to existing business logic. Every HTTP request now automatically gets:
Architecture
Components Added
MicronautHttpTracingFilter.kt
- Core HTTP filter that automatically instruments all requestsObservationRegistryBeanFactory.kt
- Creates and configures the OpenTelemetry SDKapplication.yml
- Comprehensive OpenTelemetry and Micronaut tracing configurationHow It Works
Key Features
1. Automatic Span Creation
Every HTTP request automatically gets an OpenTelemetry span with:
2. Structured Logging Integration
The existing
LogEvent.kt
automatically includes trace correlation:3. Zero Code Changes Required
Existing controllers work unchanged:
This automatically gets traced with no modifications needed.
4. Dual Tracing Integration
The implementation uses both:
Configuration
Environment Variables
All tracing can be controlled via environment variables:
Local-Only Tracing
The configuration is set up for local tracing only (no external exporters):
This means traces are generated for logging correlation but not exported to external systems by default.
Micronaut Tracing Configuration
Benefits
1. Request Correlation
Every log message from a request contains the same
traceId
, making it trivial to:2. Observability Ready
The implementation is production-ready and can easily be extended to:
3. Performance Monitoring
Automatic timing and error tracking for:
4. Thread-Safe MDC Management
Handles Micronaut's async request processing correctly:
doFinally
to prevent leaksUsage Examples
View Traces in Logs
Sample Log Output
Add Custom Spans (Optional)
For business logic that needs custom spans:
Implementation Details
Why This Approach?
Manual MDC Population: We manually populate SLF4J MDC in the HTTP filter because Micronaut's automatic MDC integration wasn't working reliably across thread boundaries in reactive contexts.
HTTP Filter + Micronaut Integration: We use both:
Reactive-Safe Design: The filter uses Reactor's
doFinally
for cleanup, ensuring MDC is cleared even if requests are cancelled or exceptions occur.Local-Only Default: External trace export is disabled by default to avoid operational overhead while still providing local correlation benefits.
File Structure
Span Attributes
Each HTTP request span includes:
Error Handling
span.recordException(e)
ERROR
for failures,OK
for success)Monitoring and Debugging
Verify Tracing is Working
Troubleshooting
No trace IDs in logs:
OTEL_TRACING_ENABLED=true
MICRONAUT_TRACING_ENABLED=true
MicronautHttpTracingFilter
is loadedInconsistent trace IDs:
doFinally
Performance impact:
OTEL_SAMPLER_RATIO=0.1
(10% sampling)HTTP_SERVER_TRACING_ENABLED=false
Future Extensions
This foundation enables easy addition of:
External Trace Export
Custom Business Spans
Distributed Tracing
APM Integration
Summary
Result: Every HTTP request to Airbyte server now automatically includes distributed tracing with complete log correlation, requiring zero changes to existing business logic!
Key Benefits:
The implementation provides a solid foundation for observability while maintaining simplicity and requiring no changes to existing code.
Requires