Documentation
Best Practices/Events Best Practices

Events Best Practices

Best practices for creating effective events in your AI applications

Follow these best practices to create meaningful, well-timed events that provide valuable insights into your application's behavior and state changes.

🎯 Meaningful Event Names

Clear and Descriptive Names

# Good: Clear and descriptive
"customer.query.received"
"ai.model.selected"
"error.rate_limit.exceeded"
 
# Bad: Generic or unclear
"event1"
"something_happened"
"error"

Action-Based Naming

# 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"

Hierarchical Naming

# Use dot notation to create logical hierarchies
"customer.query.received"
"customer.query.processed"
"customer.query.completed"
 
"ai.model.selected"
"ai.response.generated"
"ai.error.occurred"
 
"system.cache.hit"
"system.cache.miss"
"system.retry.attempted"

🎪 Event Timing

Add Events at Meaningful Points

# Add events at meaningful points
span.add_event("operation.started", {"timestamp": time.time()})
 
# Do the work
result = perform_operation()
 
span.add_event("operation.completed", {
    "timestamp": time.time(),
    "result.size": len(result)
})

Consistent Timestamps

# Use consistent timestamp format
timestamp = time.time()
 
span.add_event("operation.started", {
    "timestamp": timestamp,
    "timestamp.iso": datetime.fromtimestamp(timestamp).isoformat()
})

📊 Rich Context

Include Relevant Context

# Include relevant context in events
span.add_event("ai.model.selected", {
    "timestamp": time.time(),
    "model": "gpt-4",
    "reason": "complex_query",
    "query.complexity_score": 0.85,
    "customer.tier": "premium",
    "fallback.used": False
})

State Change Events

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
    })

🔄 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

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

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 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
})

🎯 Business Events

Customer Interaction 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"
})

Business Logic Events

span.add_event("business.rule.applied", {
    "timestamp": time.time(),
    "rule.name": "premium_customer_priority",
    "rule.condition": "customer.tier == premium",
    "rule.action": "upgrade_to_gpt4"
})

🔍 Error Events

Comprehensive Error Tracking

# 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
})

Error Context

span.add_event("error.occurred", {
    "timestamp": time.time(),
    "error.type": "ValidationError",
    "error.field": "email",
    "error.value": "invalid-email",
    "error.expected_format": "[email protected]",
    "error.user_id": "user_123"
})

🎪 Performance Events

Performance Milestones

span.add_event("performance.milestone", {
    "timestamp": time.time(),
    "milestone": "database_query_completed",
    "duration_ms": 150,
    "records_processed": 1000
})

Resource Usage Events

span.add_event("resource.usage", {
    "timestamp": time.time(),
    "cpu.usage_percent": 75.5,
    "memory.usage_mb": 512,
    "disk.usage_percent": 45.2
})

🛠️ Debugging Support

Debug Events

span.add_event("debug.checkpoint", {
    "timestamp": time.time(),
    "checkpoint": "before_ai_call",
    "variables": {
        "query_length": len(query),
        "model_selected": "gpt-4",
        "temperature": 0.7
    }
})

Trace Correlation

span.add_event("correlation.established", {
    "timestamp": time.time(),
    "correlation.id": correlation_id,
    "external.service": "payment_gateway",
    "external.request_id": external_request_id
})

🚀 Next Steps

Now that you understand event best practices, explore these related concepts:


Well-timed events provide the timeline and context that make your traces meaningful. By following these best practices, you'll create events that enable detailed analysis and debugging.

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.