traceloop / traceloop/openllmetry
Proposal: Add a custom attribute to the entry span for LLM trace identification
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 7.4k
- Forks
- 1.1k
- Avg merge
- 8d 14h
- Merged PRs (30d)
- 2
Description
Add GenAI Trace Count Metric for Mixed Application Scenarios
Background
In modern AI applications, LLM components are often integrated with traditional infrastructure components (Redis, databases, web services, message queues, etc.). This creates mixed tracing scenarios where a single trace may contain both:
- Pure GenAI traces: Traces consisting entirely of LLM-related spans
- Mixed traces: Traces containing both traditional infrastructure spans and GenAI spans
Our team is leveraging OpenLLMetry and opentelemetry-python-contrib to build a new LLM monitoring platform. This means we'll be building a combined agent by installing instrumentation packages from openllmetry on top of the opentelemetry-python-contrib agent. One of the key challenges is we need to expose a new metric representing the count of traces that contain LLM spans(like fastapi -> langchain(mixed) or langchain -> chromadb(pure LLM)).
Current Challenge
Currently, there's no straightforward way to distinguish and count traces that involve GenAI operations. This makes it difficult to:
- Monitor GenAI adoption and usage patterns in mixed applications
- Understand the proportion of requests that involve AI processing vs traditional processing
- Set up proper alerting and monitoring for GenAI-specific operations
Use Case Example
Consider a typical e-commerce application that has integrated AI features:
HTTP Request → Web Service → Database → LLM (Product Recommendations) → Response
↓ ↓ ↓ ↓
Traditional Traditional Traditional GenAI Span
Span Span Span
In this scenario, we need to identify that this entire trace involved GenAI processing, even though it contains traditional infrastructure spans.
Our Goal: Counter Metrics Support of Mixed Instrumentation
This approach correctly handles mixed instrumentation scenarios:
| Scenario | genai_trace_count |
|---|---|
Web(root) → LLM(child) |
1 |
LLM(root) |
1 |
Web(root) → LLM1 + LLM2 |
1 |
Proposed Solution
New Metric: genai_trace_count
Add a new counter metric that tracks the number of completed traces that contain GenAI operations.
Metric Specification:
- Name:
genai_trace_count - Type: Counter
- Description: "Number of completed traces containing GenAI operations"
- Unit: "1"
- Labels: Could include trace status (success/error), root service, etc.
Implementation Approach
1. Trace-Level Counting Strategy
We count each unique trace that contains GenAI operations:
def on_end(self, span: ReadableSpan) -> None:
trace_id = span.context.trace_id
if trace_id not in self._counted_traces:
self._counted_traces[trace_id] = timestamp
self._genai_trace_counter.add(1)
2. Core Data Structure
Use OrderedDict to store trace IDs with timestamps for efficient cleanup:
_counted_traces: OrderedDict[int, float] = OrderedDict()
# ↑ ↑
# trace_id timestamp
3. Deduplication Logic
Problem: Multiple GenAI spans in the same trace would cause over-counting
Solution: Track trace IDs instead of individual spans
Example:
Flask Request (trace_id: 123)
├── LangChain Call (trace_id: 123) ← First GenAI span: COUNT +1
└── OpenAI Call (trace_id: 123) ← Same trace: SKIP
4. Memory Management
Implement automatic cleanup to prevent memory leaks:
- Time-based cleanup: Remove traces older than TTL (default: 1 hour)
- Size-based cleanup: Remove oldest traces when exceeding limit (default: 50K)
- Periodic cleanup: Run cleanup every 5 minutes or when limit exceeded
Integration Points
- TracerWrapper: Add the processor to the tracer provider
- Metrics Configuration: Include the new metric in metric views
- Initialization: Add configuration parameter to
Traceloop.init()
Backward Compatibility
- This is a purely additive feature
- No breaking changes to existing APIs
- Can be disabled via configuration if not needed
- Does not affect existing span processing or metrics
The proposed approach provides accurate, real-time counting with minimal overhead.
Since mixed instrumentation traces are infrequent and to mitigate potential performance overhead, this metric will be disabled by default and activated using an environment variable.
@nirga If you approve this proposal, I'll submit a PR to implement this functionality. The implementation shouldn't be overly complex.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the proposed on_end trace-counting strategy and the TracerWrapper, metric views, and Traceloop.init() integration points named in the issue. Define how configuration and cleanup should work before implementing the opt-in genai_trace_count metric. Done means completed traces containing GenAI operations are counted once, mixed traces are supported, and the feature remains disabled by default.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- observability
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100