Skip to main content

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.

The honeyhive-logger package is a lightweight API wrapper with start(), log(), and update() functions. The v1 honeyhive package adds OpenTelemetry tracing, automatic context propagation, decorators, instrumentors, and evaluation support. Use this guide when moving Python code from honeyhive-logger to honeyhive>=1.0.0.
The logger package is useful when you need a dependency-free client. Migrate to the v1 SDK when you want automatic spans, nested trace trees, framework integrations, or evaluate().
Use this HoneyHive migration guide: https://docs.honeyhive.ai/v2/sdk-reference/python/migration/logger-to-v1.md

Explore my codebase to find where HoneyHive logging is used. Ask me any questions needed to understand the project context, runtime, and migration constraints. Then present a concise migration plan for my confirmation. After I confirm the plan, implement the migration changes.

API mapping

Logger APIv1 SDK replacementNotes
(no logger equivalent)HoneyHiveTracer.init(...)New in v1: call once at app startup before any logger replacement.
start(...)tracer.create_session(...) / tracer.acreate_session(...) / tracer.with_session(...)Choose with_session() for scoped blocks, acreate_session() for async frameworks (FastAPI, async Flask).
log(...) (creates a new event)@trace or enrich_span_context(...)Both create a new span/event. Prefer decorators for function-level tracing.
log(...) then enrich the same eventtracer.enrich_span(...) inside the active spanenrich_span() attaches fields to the currently active span. It does not create a new span on its own.
update(event_id=...)tracer.enrich_span(event_id=...)Updates a specific existing event by ID via the events API.
update(event_id=session_id, ...)tracer.enrich_session(session_id=...)Updates a session.
duration_msCaptured by spans automaticallyUse metrics only if you need custom duration fields.

1. Replace the package

pip uninstall honeyhive-logger -y
pip install "honeyhive>=1.0.0"
Set credentials:
export HH_API_KEY="your-honeyhive-api-key"
export HH_SOURCE="production"
You no longer need to set HH_PROJECT or pass project= to HoneyHiveTracer.init(). HoneyHive API keys are project-scoped — the API key alone determines which project traces are routed to. Drop HH_PROJECT and project= anywhere they are set in logger code; neither has any effect on the API or SDK behavior. Passing project= explicitly to HoneyHiveTracer.init(...) emits a DeprecationWarning because the kwarg will be removed in v2.0. The examples below use HoneyHiveTracer.init() with no kwargs.

2. Migrate session creation

Logger code usually starts a session and passes session_id to every event. In v1, initialize a tracer once and use session helpers to scope work.
import os
from honeyhive_logger import start

session_id = start(
    api_key=os.environ["HH_API_KEY"],
    project="support-bot",
    session_name="support-chat",
    source="production",
    inputs={"message": "How do I reset my password?"},
    metadata={"tenant_id": "acme"},
    user_properties={"user_id": "user-123"},
)
For async frameworks (FastAPI, async Flask), use await tracer.acreate_session(...) — same arguments as create_session().
Unlike the logger, the v1 SDK can serve concurrent requests safely from a single shared tracer because create_session() / acreate_session() / with_session() store the session ID in OpenTelemetry baggage (ContextVar-based) rather than on the tracer instance. See Tracer Initialization for FastAPI, Flask, and Lambda patterns.
For single-operation scripts, with_session() keeps session setup close to the work:
with tracer.with_session(
    session_name="support-chat",
    inputs={"message": message},
    user_properties={"user_id": user_id},
):
    response = answer(message)
    tracer.enrich_session(outputs={"response": response})

3. Replace log() with @trace

Use @trace when the event maps to a Python function.
from honeyhive_logger import log

def answer(message: str, session_id: str) -> str:
    response = call_model(message)
    log(
        session_id=session_id,
        event_name="model_inference",
        event_type="model",
        config={"model": "gpt-4o-mini"},
        inputs={"prompt": message},
        outputs={"response": response},
        metadata={"route": "password-reset"},
    )
    return response
The decorator captures function inputs and outputs automatically. Use tracer.enrich_span(...) inside the function for extra metadata, metrics, feedback, config, or a custom output shape.

4. Replace log() with manual spans when decorators do not fit

Use enrich_span_context() for loops, conditional blocks, or code that is not cleanly wrapped by a function.
event_id = log(
    session_id=session_id,
    event_name="retrieve_documents",
    event_type="tool",
    inputs={"query": query},
    outputs={"documents": docs},
)
In honeyhive>=1.0.0, enrich_span_context is not re-exported at honeyhive or honeyhive.tracer. Import it from honeyhive.tracer.processing.context. Always pass tracer_instance=tracer — otherwise the helper falls back to an unconfigured OpenTelemetry tracer and spans will not reach HoneyHive. enrich_span_context does not expose an event_type parameter; set it via the raw attributes={"honeyhive_event_type": "tool"} attribute when migrating a log(event_type=...) call.
Use tracer.start_span() only when you need raw OpenTelemetry control:
with tracer.start_span("retrieve_documents") as span:
    span.set_attribute("query", query)
    docs = retrieve_documents(query)
    span.set_attribute("document_count", len(docs))

5. Replace update() for events

When you need to update a known event ID, pass it to tracer.enrich_span().
Use event_id when you want to update an existing event in HoneyHive. If you are updating the current active span, omit event_id.
Getting an event_id back. The @trace decorator and enrich_span_context() do not return event IDs — they manage span IDs through OpenTelemetry context. If you need the same “create event, hold on to its ID, update it later” pattern as the logger, use the lower-level tracer.create_event(...) method, which posts the event directly via the events API and returns its ID.
event_id = tracer.create_event(
    event_name="model_inference",
    event_type="model",
    inputs={"prompt": message},
    outputs={"response": response},
)
# ...later, anywhere in the codebase
tracer.enrich_span(event_id=event_id, feedback={"rating": 5})
There is also an update_event_id parameter on tracer.enrich_span(...) that lets you tag the current span with a client-supplied UUID and later look that event up with enrich_span(event_id=...), but the round-trip depends on backend behavior we have not validated end-to-end — prefer the create_event path above unless you have already confirmed the UUID flow against your HoneyHive deployment.
from honeyhive_logger import update

update(
    event_id=event_id,
    feedback={"rating": 5},
    metrics={"quality_score": 0.94},
    outputs={"response": response},
)
If the event is the current active span, omit event_id:
tracer.enrich_span(
    feedback={"rating": 5},
    metrics={"quality_score": 0.94},
)

6. Replace update() for sessions

Logger uses update(event_id=session_id, ...) for session updates. In v1, use session enrichment.
update(
    event_id=session_id,
    outputs={"answer": answer_text},
    feedback={"thumbs_up": True},
    user_properties={"plan": "enterprise"},
)
If you created the session with create_session() in the active request, you can omit session_id:
tracer.enrich_session(outputs={"answer": answer_text})

7. Add automatic provider instrumentation

After migrating logger calls, you can add automatic model or framework spans.
pip install "honeyhive[openinference-openai]"
from honeyhive import HoneyHiveTracer
from openinference.instrumentation.openai import OpenAIInstrumentor

# Reads HH_API_KEY from the environment.
tracer = HoneyHiveTracer.init()
OpenAIInstrumentor().instrument(tracer_provider=tracer.provider)
Initialize the tracer before any instrumentor, and call instrument() before constructing your provider client (for example, openai.OpenAI()). See Integrations for provider-specific setup.

Complete before and after

from honeyhive_logger import start, log, update

def handle_chat(message: str, user_id: str) -> str:
    session_id = start(
        session_name="support-chat",
        inputs={"message": message},
        user_properties={"user_id": user_id},
    )

    response = call_model(message)
    event_id = log(
        session_id=session_id,
        event_name="model_inference",
        event_type="model",
        inputs={"prompt": message},
        outputs={"response": response},
    )

    update(event_id=event_id, metrics={"quality_score": score(response)})
    update(event_id=session_id, outputs={"response": response})
    return response
Flush before process exit in short-lived scripts. Unlike honeyhive-logger, which sends each call synchronously, the v1 SDK batches spans on a background thread by default. For scripts, notebooks, Lambda handlers, and one-off jobs, call tracer.flush() (or initialize with disable_batch=True) before the process exits, otherwise the last batch of spans may be dropped. See Span Export Modes.

Migration checklist

  • Replace honeyhive-logger with honeyhive>=1.0.0
  • Export HH_API_KEY in the environment (API keys are project-scoped; remove any HH_PROJECT or project= left over from logger code)
  • Initialize one HoneyHiveTracer at startup
  • Replace start() with create_session(), acreate_session(), or with_session()
  • Replace function-level log() calls with @trace
  • Replace block-level log() calls with enrich_span_context()
  • Replace event update() calls with tracer.enrich_span(event_id=...)
  • Replace session update() calls with tracer.enrich_session(...)
  • Call tracer.flush() (or set disable_batch=True) for scripts, notebooks, and serverless handlers
  • Add provider instrumentors where automatic tracing is useful
  • Confirm traces show nested spans and session outputs in HoneyHive

Custom Spans

Learn decorator and manual span patterns.

Tracer Initialization

Place tracer initialization correctly for your runtime.

Enriching Traces

Add metadata, metrics, feedback, and outputs.

OpenAI Integration

Add automatic model call tracing.