Documentation

Events - Point-in-Time Occurrences

Understanding events and how they track point-in-time occurrences during trace execution

Events are point-in-time occurrences that happen during the execution of a trace or span. They provide a timeline of what happened, when it happened, and what the context was at that moment.

🎯 What are Events?

Events represent:

  • State changes during operation execution
  • Important milestones in your application flow
  • Error conditions and recovery actions
  • User interactions and system responses
  • Business logic decisions and outcomes

🏗️ Event Structure

Every event has:

  • Name: Descriptive name of what happened
  • Timestamp: When the event occurred
  • Attributes: Key-value metadata about the event
  • Span Context: Which span the event belongs to

📊 Event Categories

Operation Events

# Start and completion events
span.add_event("operation.started", {
    "timestamp": time.time(),
    "input.size": len(input_data),
    "input.type": "json"
})
 
span.add_event("operation.completed", {
    "timestamp": time.time(),
    "output.size": len(output_data),
    "success": True,
    "duration_ms": 1800
})

AI Events

# Model selection and response events
span.add_event("ai.model.selected", {
    "timestamp": time.time(),
    "model": "gpt-4",
    "reason": "complex_query",
    "fallback_used": False
})
 
span.add_event("ai.response.generated", {
    "timestamp": time.time(),
    "tokens_used": 200,
    "finish_reason": "stop",
    "response_time_ms": 1800
})

Business Events

# Customer interaction events
span.add_event("customer.query.received", {
    "timestamp": time.time(),
    "query.length": 45,
    "query.sentiment": "neutral",
    "customer.tier": "premium"
})
 
span.add_event("customer.query.processed", {
    "timestamp": time.time(),
    "processing_time_ms": 2000,
    "confidence_score": 0.85,
    "response.quality": "high"
})

Error Events

# Error tracking events
span.add_event("error.occurred", {
    "timestamp": time.time(),
    "error.type": "APIError",
    "error.message": "Rate limit exceeded",
    "error.retry_count": 3,
    "error.retry_after": 60
})
 
span.add_event("error.recovered", {
    "timestamp": time.time(),
    "recovery.action": "retry_with_backoff",
    "recovery.success": True,
    "total_retry_time_ms": 5000
})

🔄 Adding Events

Basic Event

span.add_event("user.login.attempted", {
    "timestamp": time.time(),
    "user.id": "user_123",
    "login.method": "email"
})

Event with Rich Context

span.add_event("ai.model.switched", {
    "timestamp": time.time(),
    "from.model": "gpt-3.5-turbo",
    "to.model": "gpt-4",
    "reason": "complex_query_detected",
    "query.complexity_score": 0.85,
    "fallback.triggered": True
})

Conditional Events

# Add events based on conditions
if response.confidence < 0.7:
    span.add_event("low.confidence.detected", {
        "timestamp": time.time(),
        "confidence.score": response.confidence,
        "threshold": 0.7,
        "action.taken": "escalate_to_human"
    })

🎯 Event Naming Conventions

Hierarchical Naming

Use dot notation to create logical hierarchies:

# Customer events
"customer.query.received"
"customer.query.processed"
"customer.query.completed"
 
# AI events
"ai.model.selected"
"ai.response.generated"
"ai.error.occurred"
 
# System events
"system.cache.hit"
"system.cache.miss"
"system.retry.attempted"

Action-Based Naming

Use action verbs to describe what happened:

# Good: Action-based naming
"user.login.attempted"
"user.login.succeeded"
"user.login.failed"
"ai.model.switched"
"ai.response.generated"
 
# Bad: State-based naming
"user.logged_in"
"ai.model_is_gpt4"
"ai.response_ready"

📈 Event Attributes

Timestamp Attributes

span.add_event("operation.started", {
    "timestamp": time.time(),
    "timestamp.iso": "2024-01-15T10:30:00Z",
    "timestamp.unix": 1705312200
})

Context Attributes

span.add_event("ai.model.selected", {
    "timestamp": time.time(),
    "context.query_type": "technical_support",
    "context.customer_tier": "premium",
    "context.complexity_score": 0.85
})

Result Attributes

span.add_event("ai.response.generated", {
    "timestamp": time.time(),
    "result.tokens_used": 200,
    "result.finish_reason": "stop",
    "result.quality_score": 0.92
})

Error Attributes

span.add_event("error.occurred", {
    "timestamp": time.time(),
    "error.type": "APIError",
    "error.code": 429,
    "error.message": "Rate limit exceeded",
    "error.retry_count": 3,
    "error.retry_after": 60
})

🎪 Event Patterns

Start/Complete Pattern

with trace_operation("process-query") as span:
    # Start event
    span.add_event("operation.started", {
        "timestamp": time.time(),
        "input.size": len(query),
        "input.type": "text"
    })
    
    try:
        # Process the query
        result = process_query(query)
        
        # Complete event
        span.add_event("operation.completed", {
            "timestamp": time.time(),
            "output.size": len(result),
            "success": True,
            "duration_ms": time.time() - start_time
        })
        
    except Exception as e:
        # Error event
        span.add_event("operation.failed", {
            "timestamp": time.time(),
            "error.type": type(e).__name__,
            "error.message": str(e),
            "duration_ms": time.time() - start_time
        })
        raise

State Change Pattern

with trace_operation("ai-completion") as span:
    # Initial state
    span.add_event("ai.initialization", {
        "timestamp": time.time(),
        "model": "gpt-3.5-turbo",
        "temperature": 0.7
    })
    
    # State change
    if query_complexity > 0.8:
        span.add_event("ai.model.upgraded", {
            "timestamp": time.time(),
            "from.model": "gpt-3.5-turbo",
            "to.model": "gpt-4",
            "reason": "high_complexity"
        })
    
    # Final state
    span.add_event("ai.completion.ready", {
        "timestamp": time.time(),
        "final.model": "gpt-4",
        "tokens.estimated": 200
    })

Retry Pattern

with trace_operation("api-call") as span:
    retry_count = 0
    max_retries = 3
    
    while retry_count <= max_retries:
        try:
            span.add_event("api.call.attempted", {
                "timestamp": time.time(),
                "attempt": retry_count + 1,
                "max_retries": max_retries
            })
            
            result = make_api_call()
            
            span.add_event("api.call.succeeded", {
                "timestamp": time.time(),
                "attempt": retry_count + 1,
                "duration_ms": time.time() - start_time
            })
            
            break
            
        except Exception as e:
            retry_count += 1
            
            span.add_event("api.call.failed", {
                "timestamp": time.time(),
                "attempt": retry_count,
                "error.type": type(e).__name__,
                "error.message": str(e),
                "will_retry": retry_count <= max_retries
            })
            
            if retry_count > max_retries:
                raise

🔍 Event Analysis

Timeline Analysis

Events provide a timeline of what happened:

# Find all events for a specific trace
events = get_trace_events(trace_id)
 
# Sort by timestamp
events.sort(key=lambda e: e.timestamp)
 
# Analyze the timeline
for event in events:
    print(f"{event.timestamp}: {event.name} - {event.attributes}")

Event Frequency

# Count events by type
event_counts = count_events_by_type(trace_id)
 
# Find common event patterns
common_events = find_common_event_patterns(traces)

Error Analysis

# Find all error events
error_events = find_events(trace_id, event_name="error.occurred")
 
# Analyze error patterns
error_patterns = analyze_error_patterns(error_events)

🚀 Next Steps

Now that you understand events, explore these related concepts:

Best Practices


Events provide the timeline and context that make your traces meaningful. They enable detailed analysis, debugging, and optimization of your AI applications.

Exclusive Early Access

Get Early Access to Noveum.ai Platform

Be the first one to get notified when we open Noveum Platform to more users. All users get access to Observability suite for free, early users get free eval jobs and premium support for the first year.

Sign up now. We send access to new batch every week.

Early access members receive premium onboarding support and influence our product roadmap. Limited spots available.