Skip to main content

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.

Use Cases

Environment-Based Routing

Route traces to different projects based on environment:
import os
from honeyhive import HoneyHiveTracer, trace

env = os.getenv("ENVIRONMENT", "development")

tracer = HoneyHiveTracer.init(
    project=f"myapp-{env}",
    source=env
)

Multi-Tenant SaaS

Each tenant gets their own tracer with isolated context:
from honeyhive import HoneyHiveTracer
import os

def handle_request(request):
    tracer = HoneyHiveTracer.init(
        api_key=os.environ["HH_API_KEY"],
        project=f"saas-{request.tenant_id}",
        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 with separate tracers:
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"],
        project="ab-test",
        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 different projects:
from honeyhive import HoneyHiveTracer, trace

customer_tracer = HoneyHiveTracer.init(
    project="customer-facing-api",
    source="production"
)

admin_tracer = HoneyHiveTracer.init(
    project="admin-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"],
        project="my-app",
        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:
        ctx = contextvars.copy_context()
        futures = [
            executor.submit(ctx.run, process_item, item)
            for item in items
        ]
        return [f.result() for f in futures]

Best Practices

  • Keep tracer instances in a central registry - create once, reuse many times
  • Use consistent naming conventions ({app}-{environment})
  • Use environment variables for API keys, never hard-code them
  • Use metadata to differentiate when possible, rather than creating additional tracers
  • 2-5 tracers per application is typical and performant

Performance

MetricImpact
Memory~100KB per tracer instance
NetworkBatched, async export per tracer
Span ProcessingEach tracer has its own processor