traced()
The traced()
function wraps any function with OpenTelemetry tracing to automatically track its execution. It creates a span for each function call, records input arguments and return values, and captures any exceptions that occur during execution.
When used with the GentraceSpanProcessor
(configured in your OpenTelemetry setup), Gentrace simplifies the process of converting baggage values to span attributes, ensuring the OpenTelemetry Collector can properly filter and route traces to Gentrace.
Basic usage
- TypeScript
- Python
typescript
import { init, traced } from 'gentrace';import OpenAI from 'openai';init({apiKey: process.env.GENTRACE_API_KEY,});const openai = new OpenAI({apiKey: process.env.OPENAI_API_KEY,});async function generateResponse(prompt: string): Promise<string> {const response = await openai.chat.completions.create({model: 'gpt-4',messages: [{ role: 'user', content: prompt }],});return response.choices[0].message.content || '';}const tracedGenerateResponse = traced('generateResponse', generateResponse);const aiResponse = await tracedGenerateResponse('What is the capital of France?');
python
import asyncioimport osfrom gentrace import init, tracedfrom openai import OpenAIinit(api_key=os.environ["GENTRACE_API_KEY"])openai = OpenAI(api_key=os.environ["OPENAI_API_KEY"])@traced(name="generate_response")async def generate_response(prompt: str) -> str:response = await openai.chat.completions.create(model="gpt-4",messages=[{"role": "user", "content": prompt}])return response.choices[0].message.content or ""# Run the async functionasync def main():ai_response = await generate_response("What is the capital of France?")print(ai_response)asyncio.run(main())
Overview
The traced()
function provides automatic instrumentation for any function in your codebase. It:
- Creates OpenTelemetry spans for each function execution with customizable names
- Records function arguments as span events for debugging and analysis
- Captures return values as span events to track function outputs
- Handles errors automatically by recording exceptions and setting appropriate span status
- Supports both sync and async functions with proper typing preservation
- Allows custom attributes to be attached to spans for enhanced observability
Parameters
- TypeScript
- Python
Function signature
typescript
function traced<F extends (...args: any[]) => any>(name: string,fn: F,config?: TracedConfig): F
Parameters
name
(string, required): The name for the OpenTelemetry span. This will appear in your tracing dashboard.fn
(function, required): The function to wrap with tracing. Can be synchronous or asynchronous.config
(TracedConfig, optional): Additional configuration options for the traced function.
TracedConfig
typescript
type TracedConfig = {attributes?: Record<string, any>;}
attributes
(object, optional): Custom attributes to attach to the span for additional context.
Decorator signature
python
def traced(*,name: Optional[str] = None,attributes: Optional[Dict[str, Any]] = None,) -> Callable[[F], F]
Parameters
name
(str, optional): Custom name for the OpenTelemetry span. If not provided, uses the function's__name__
or "anonymous_function" as fallback.attributes
(dict, optional): Custom attributes to attach to the span. These will be formatted for OTLP compatibility.
Return value
Returns a decorator that, when applied to a function, returns a new function with the same signature but enhanced with tracing capabilities.
Advanced usage
You can add custom attributes to the OpenTelemetry span using the attributes
option.
- TypeScript
- Python
typescript
import { traced } from 'gentrace';// Add custom attributes for enhanced observabilityfunction processData(data: any[]): any[] {return data.map(item => ({ ...item, processed: true }));}const tracedProcessData = traced('processData', processData, {attributes: {'service.name': 'data-processor','service.version': '1.2.0','operation.type': 'batch_processing'}});const result = tracedProcessData([{ id: 1 }, { id: 2 }]);
python
from gentrace import traced# Add custom attributes for enhanced observability@traced(name="process_data",attributes={"service.name": "data-processor","service.version": "1.2.0","operation.type": "batch_processing"})def process_data(data: list) -> list:return [{"processed": True, **item} for item in data]result = process_data([{"id": 1}, {"id": 2}])
Tracing AI/LLM functions
- TypeScript
- Python
typescript
import { traced } from 'gentrace';import OpenAI from 'openai';const openai = new OpenAI({apiKey: process.env.OPENAI_API_KEY,});// Trace LLM calls with relevant attributesasync function generateResponse(prompt: string): Promise<string> {const completion = await openai.chat.completions.create({model: 'gpt-4o',messages: [{ role: 'user', content: prompt }],temperature: 0.7,});return completion.choices[0].message.content || '';}const tracedGenerateResponse = traced('generateResponse', generateResponse, {attributes: {'llm.vendor': 'OpenAI','llm.model': 'gpt-4o','llm.temperature': 0.7,'operation.type': 'text_generation'}});const response = await tracedGenerateResponse('Explain quantum computing');
python
import osfrom openai import OpenAIfrom gentrace import tracedclient = OpenAI(api_key=os.environ["OPENAI_API_KEY"])# Trace LLM calls with relevant attributes@traced(name="generate_response",attributes={"llm.vendor": "OpenAI","llm.model": "gpt-4o","llm.temperature": 0.7,"operation.type": "text_generation"})async def generate_response(prompt: str) -> str:completion = client.chat.completions.create(model="gpt-4o",messages=[{"role": "user", "content": prompt}],temperature=0.7,)return completion.choices[0].message.content or ""response = await generate_response("Explain quantum computing")
Tracing database operations
- TypeScript
- Python
typescript
import { traced } from 'gentrace';// Trace database operationsasync function getUserById(userId: string): Promise<User | null> {const query = 'SELECT * FROM users WHERE id = $1';const result = await db.query(query, [userId]);return result.rows[0] || null;}const tracedGetUserById = traced('getUserById', getUserById, {attributes: {'db.system': 'postgresql','db.operation': 'select','db.table': 'users'}});const user = await tracedGetUserById('user-123');
python
from gentrace import traced# Trace database operations@traced(name="get_user_by_id",attributes={"db.system": "postgresql","db.operation": "select","db.table": "users"})async def get_user_by_id(user_id: str) -> dict | None:query = "SELECT * FROM users WHERE id = %s"result = await db.fetch_one(query, user_id)return dict(result) if result else Noneuser = await get_user_by_id("user-123")
Automatic data capture
The traced()
function automatically captures:
Function arguments
All input arguments are serialized and recorded as span events, making it easy to debug function calls and understand what data was processed.
Return values
Function return values are captured and stored as span events, allowing you to track outputs and verify function behavior.
Error handling
When functions throw exceptions or reject promises, the traced()
function automatically:
- TypeScript
- Python
typescript
import { traced } from 'gentrace';// Function that might throw an errorfunction riskyOperation(input: string): string {if (input === 'error') {throw new Error('Something went wrong!');}return `Processed: ${input}`;}const tracedRiskyOperation = traced('riskyOperation', riskyOperation);try {const result = tracedRiskyOperation('error');} catch (error) {// Error is automatically captured in the span with:// - Exception details and stack trace// - Span status set to ERROR// - Error type attribute setconsole.log('Operation failed:', error.message);}
python
from gentrace import traced# Function that might raise an exception@traced(name="risky_operation")def risky_operation(input_str: str) -> str:if input_str == "error":raise ValueError("Something went wrong!")return f"Processed: {input_str}"try:result = risky_operation("error")except ValueError as e:# Exception is automatically captured in the span with:# - Exception details and stack trace# - Span status set to ERROR# - Error type attribute setprint(f"Operation failed: {e}")
Span events and attributes
The traced()
function creates the following span events and attributes:
Span events
- Function Arguments: Captured at the start of function execution
- Function Output: Captured when the function completes successfully
- Exceptions: Captured when errors occur, including full stack traces
Span attributes
- Custom Attributes: Any attributes provided in the configuration
- Error Information: When exceptions occur:
error.type
: The type/class name of the exception- Span status set to
ERROR
with error message
Requirements
- OpenTelemetry Setup: The
traced()
function requires OpenTelemetry to be configured for tracing - Gentrace SDK Initialization: Must call
init()
with a valid API key before using traced functions - Function Compatibility: Works with both synchronous and asynchronous functions
Related functions
init()
- Initialize the Gentrace SDKinteraction()
- Higher-level wrapper for AI/LLM function tracing with automatic baggage handlingexperiment()
- Create testing contexts that can contain traced functionseval()
/evalOnce()
- Run evaluations that can include traced functions