Noveum.ai
Noveum Docs
Best PracticesEvents 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": "user@domain.com",
    "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.