Send OpenLIT Traces to Future AGI

Send OpenLIT traces to Future AGI with openlit.init(), and configure content capture and export settings.

Configure OpenLIT to export OpenTelemetry traces to a Future AGI project over OTLP/HTTP.

Note

This recipe uses Python 3.10–3.13, openlit 1.45.0 and openai 2.54.0 for synchronous OpenAI Chat Completions over OTLP/HTTP.

1. Install

pip install "openlit==1.45.0" "openai==2.54.0"

OpenLIT 1.45.0 requires openai>=1.92.0,<3.0.0, so stay on the 2.x line.

2. Configure

Review the capture controls before exporting: disabling message capture does not hide tool arguments, user values, decorated function data, provider error bodies or request URLs. Use this setup only for data you are allowed to store in Future AGI.

See the runnable app.py recipe. For the inline setup below, first create an empty local pricing table so initialization does not download one:

printf '{}\n' > empty_pricing.json
export OPENLIT_PRICING_JSON="$PWD/empty_pricing.json"
export FI_API_KEY="YOUR_API_KEY"
export FI_SECRET_KEY="YOUR_SECRET_KEY"
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
export OTEL_EXPORTER_OTLP_ENDPOINT="https://YOUR_FUTURE_AGI_COLLECTOR_ORIGIN"   # origin only, no path
export OTEL_RESOURCE_ATTRIBUTES="project_name=my-chatbot,project_type=observe"
import os
from urllib.parse import quote
import openlit

openlit.init(
    service_name="my-app",
    otlp_endpoint=os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"],
    otlp_headers={
        "x-api-key": quote(os.environ["FI_API_KEY"], safe=""),
        "x-secret-key": quote(os.environ["FI_SECRET_KEY"], safe=""),
    },
    capture_message_content=False,  # OpenLIT's default is True
    disable_metrics=True,           # Future AGI ingests traces only
    disable_events=True,            # events go to /v1/logs, which is not served
    pricing_json=os.environ["OPENLIT_PRICING_JSON"],
)

Why each setting matters:

SettingReason
Endpoint is the originOpenLIT’s exporter always appends /v1/traces. A full .../v1/traces URL doubles the path and returns 404.
Percent-encoded header valuesOpenLIT joins the header dict on commas. Encoding keeps a secret that contains , or = intact.
project_name in OTEL_RESOURCE_ATTRIBUTESinit() has no resource argument. A batch with no project_name is rejected with HTTP 400.
disable_metrics, disable_eventsMetrics and events are sent to /v1/metrics and /v1/logs, which Future AGI does not serve.
pricing_jsonWithout it, every init() downloads a price table from raw.githubusercontent.com. Pass a local file (the recipe ships an empty table).

In the same script, call OpenAI after initialization:

from openai import OpenAI

response = OpenAI().chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "What is the refund window?"}],
)
print(response.choices[0].message.content)

A short script exports its spans when the process exits.

3. What is captured

One chat call produces a chat <model> span with model, provider, input tokens, output tokens and a derived total, plus a child POST span from OpenLIT’s httpx instrumentation. A tool-calling run adds one chat span per model call. Functions you wrap with @openlit.trace become spans too.

Open your project in Observe to inspect the trace and its spans.

A failed call (for example an unknown model) is stored with status ERROR.

Storage behavior in Future AGI 1.56.1:

  • The collector promotes gen_ai.input.messages and gen_ai.output.messages into the span’s input and output when present, and retains the raw attributes. With message capture off, those message attributes are absent.
  • gen_ai.usage.cost is not a cost field; cost is empty or computed from the model and token counts by Future AGI’s own price table, when configured.
  • @openlit.trace spans, and the POST spans, have no span-kind attribute and show as unknown.

4. Privacy defaults and opt-in

OpenLIT captures message content by default (capture_message_content=True). The recipe turns it off, and with it off the prompt, answer and system prompt are not exported. To turn content on, pass capture_message_content=True (or leave it out).

capture_message_content=False is not a full privacy switch. These still reach Future AGI:

  • Tool-call arguments the model generated (gen_ai.tool.args), which often repeat what the user typed.
  • The user argument of chat.completions.create() (gen_ai.request.user).
  • The function arguments and return value of anything wrapped in @openlit.trace.
  • The provider’s error body, in the span’s status message on a failed call.
  • The full request URL on the POST span.

If tool arguments or user values can carry personal data, pass disabled_instrumentors=["openai"] to openlit.init() (no model-call span is then created) or accept that these keys are exported.

5. Using OpenLIT with other Future AGI integrations

  • traceai-openai. Enabling both on one client gives two LLM spans for one call, and traceai-openai’s span carries the prompt and answer even when OpenLIT’s content capture is off. Pick one. disabled_instrumentors=["openai"] leaves only traceAI’s span.
  • traceAI register(). If register() already set a global tracer provider, openlit.init() reuses it and adds no exporter of its own.
  • Firecrawl. OpenLIT’s Firecrawl instrumentor wraps the v1 FirecrawlApp client and ignores the content switch. The traceAI Firecrawl package wraps the v2 client. Use one.

6. Troubleshooting

SymptomCause and fix
Nothing arrives, no errorThe exporter logs export failures and carries on. Check stderr for Failed to export spans batch code: 401 (keys) or 400 (no project_name).
HTTP 404The endpoint includes /v1/traces. Use the origin only.
Spans print to the terminalNo endpoint is set; OpenLIT falls back to the console.
Two LLM spans per callOpenLIT and traceai-openai are both enabled.
No input or output in the trace viewMessage capture is off in this recipe. With capture on, Future AGI 1.56.1 promotes the message attributes; check the collector version and exported attributes.
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT or OTEL_TRACES_EXPORTER setThese override the recipe. OpenLIT also writes the endpoint and headers into os.environ, so later OTLP exporters in the same process, and child processes, inherit them.

7. Limitations

  • Traces only. OpenLIT metrics and events are disabled, not translated.
  • Supported execution is synchronous OpenAI Chat Completions with the pinned versions above. Streaming, embeddings, the Responses API, gRPC and other OpenLIT instrumentors are outside this recipe’s scope.
  • Older OpenLIT versions and Python 3.9 are not supported by this recipe.
Was this page helpful?

Questions & Discussion