Documentation Index Fetch the complete documentation index at: https://docs.honeyhive.ai/llms.txt
Use this file to discover all available pages before exploring further.
Overview
HoneyHive supports multiple tracer instances in a single application. Each instance maintains its own session context, configuration, and OTel TracerProvider. Instances do not share context.
Projects are selected by the API key. Use a separate project-scoped API key when a tracer should write to a different HoneyHive project. Use metadata or session enrichment when traces should stay in the same project.
Use Cases
Environment-Based Tracing
Send each environment to the project scoped to its API key:
import os
from honeyhive import HoneyHiveTracer, trace
env = os.getenv( "ENVIRONMENT" , "development" )
api_keys = {
"development" : os.environ[ "HH_API_KEY_DEVELOPMENT" ],
"staging" : os.environ[ "HH_API_KEY_STAGING" ],
"production" : os.environ[ "HH_API_KEY_PRODUCTION" ],
}
tracer = HoneyHiveTracer.init(
api_key = api_keys[env],
source = env
)
Multi-Tenant SaaS
Give each tenant its own tracer and session metadata. If tenants need project-level isolation, select a project-scoped API key for that tenant:
from honeyhive import HoneyHiveTracer
import os
TENANT_API_KEYS = {
"acme" : os.environ[ "HH_API_KEY_TENANT_ACME" ],
"globex" : os.environ[ "HH_API_KEY_TENANT_GLOBEX" ],
}
def handle_request ( request ):
tracer = HoneyHiveTracer.init(
api_key = TENANT_API_KEYS [request.tenant_slug],
source = "production"
)
tracer.enrich_session({
"tenant_id" : request.tenant_id,
"plan" : request.tenant_plan
})
return process_with_tracer(request, tracer)
A/B Testing
Run different configurations side-by-side and compare them with session metadata:
from honeyhive import HoneyHiveTracer, trace
import os
def ab_test_handler ( request ):
variant = get_ab_variant(request.user_id)
tracer = HoneyHiveTracer.init(
api_key = os.environ[ "HH_API_KEY" ],
source = "production"
)
tracer.enrich_session({
"variant" : variant,
"user_id" : request.user_id
})
if variant == "A" :
return process_with_gpt4(request, tracer)
else :
return process_with_claude(request, tracer)
Feature Isolation
Route different features to projects scoped by separate API keys:
from honeyhive import HoneyHiveTracer, trace
import os
customer_tracer = HoneyHiveTracer.init(
api_key = os.environ[ "HH_API_KEY_CUSTOMER_EXPERIENCE" ],
source = "production"
)
admin_tracer = HoneyHiveTracer.init(
api_key = os.environ[ "HH_API_KEY_INTERNAL_TOOLS" ],
source = "production"
)
@trace ( tracer = customer_tracer)
def handle_customer_query ( query : str ) -> str :
...
@trace ( tracer = admin_tracer)
def generate_internal_report ( data : dict ) -> str :
...
Per-Request Initialization
For full isolation, initialize a tracer per request:
import os
from honeyhive import HoneyHiveTracer
from flask import Flask, request
app = Flask( __name__ )
@app.route ( "/api/process" , methods = [ "POST" ])
def handle ():
tracer = HoneyHiveTracer.init(
api_key = os.environ[ "HH_API_KEY" ],
source = "api-server"
)
tracer.enrich_session({
"endpoint" : request.path,
"method" : request.method
})
result = process_request(request.json)
tracer.force_flush()
return result
Thread Safety
HoneyHive uses Python’s contextvars for thread safety. When using thread pools, propagate context explicitly:
from concurrent.futures import ThreadPoolExecutor
import contextvars
def process_in_threads ( items , tracer ):
def process_item ( item ):
return do_work(item)
with ThreadPoolExecutor( max_workers = 4 ) as executor:
futures = [
executor.submit(contextvars.copy_context().run, process_item, item)
for item in items
]
return [f.result() for f in futures]
Copy the context for each executor.submit() call. Reusing a single context object across threads causes race conditions. See Multi-Threading for details.
Best Practices
Keep tracer instances in a central registry - create once, reuse many times
Use project-scoped API keys when a tracer should write to a different project
Store API keys in environment variables or a secret manager, never hard-code them
Use metadata to differentiate when possible, rather than creating additional tracers
2-5 tracers per application is typical and performant
Metric Impact Memory ~100KB per tracer instance Network Batched, async export per tracer Span Processing Each tracer has its own processor
Production Deployment Initialization patterns for production environments
Multi-Threaded Tracing Context propagation across threads