Documentation Index
Fetch the complete documentation index at: https://docs.crewship.ai/llms.txt
Use this file to discover all available pages before exploring further.
OTLP tracing setup
Crewship emits OpenTelemetry GenAI spans for every LLM call viainternal/telemetry. Any OTLP-compatible backend (self-hosted or
managed) can receive those spans by setting two env vars on the
Crewship process — no code change required.
Prerequisites
- An OTLP/HTTP-capable tracing backend reachable from the Crewship process.
- Credentials supplied by your backend (typical formats: a bearer token, a Basic-auth pair, or an API-key header).
OTEL_EXPORTER_OTLP_*env vars supported by Crewship since theinternal/telemetrypackage was added.
Configure
Set the env vars on the Crewship process (.env.local for dev.sh,
systemd unit Environment= for prod, container -e for Docker):
/api/public/otel), append it to OTEL_EXPORTER_OTLP_ENDPOINT —
the OTel SDK still appends /v1/traces to whatever you set here.
Compute a Basic-auth header once if needed:
crewship. The init logs one of:
OTel GenAI telemetry enabled endpoint=http://...→ workingtelemetry init failed, falling back to noop tracer→ check endpoint reachability and that header values parse (no quotes, no newline in base64).
Smoke test
Verify endpoint + auth without waiting for an LLM call:crewship-smoke service should
appear shortly after.
What you get
Crewship’sinternal/telemetry wires GenAI Semantic Convention
attributes on every LLM call (defined in internal/telemetry/spans.go):
gen_ai.system—anthropic,openai,ollamagen_ai.request.model— model identifiergen_ai.usage.input_tokens/output_tokens/cached_input_tokensgen_ai.usage.cache_creation_tokensgen_ai.cost.total_usd
spans.go:
crewship.agent.id,crewship.agent.typecrewship.crew.id,crewship.mission.idcrewship.tool.name,crewship.tool.args_hash,crewship.tool.side_effect
spans_routine.go):
crewship.routine.slug,crewship.routine.run_id,crewship.routine.pipeline_idcrewship.routine.step.id,crewship.routine.step.type,crewship.routine.step.attempt
Operational notes
- Same-host loopback avoids the reverse-proxy hop. If the backend
is on a different host, point the endpoint at its public DNS —
Crewship uses HTTPS automatically when the endpoint URL starts
https://. - Batching is 5 s / 2048 spans / 512 per batch (see
internal/telemetry/provider.go). Spans emitted shortly before a forced shutdown may drop; the shutdown hook flushes whatever is still queued. - No-op fallback — empty
OTEL_EXPORTER_OTLP_ENDPOINTkeeps the binary running without an observability stack, which is the local dev default. - Per-deployment isolation — if your backend supports per-project
credentials, give every deployment its own pair so dev/staging/prod
traces stay sorted. Only
OTEL_EXPORTER_OTLP_HEADERSneeds to change.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
telemetry init failed | Endpoint unreachable | curl $OTEL_EXPORTER_OTLP_ENDPOINT/v1/traces to confirm |
| Smoke test 401/403 | Wrong credentials | Re-check the header value your backend expects (Bearer, Basic, API key) |
| Smoke test 2xx but no traces in UI | UI looking at wrong project / wrong filter | Verify the credentials map to the project shown in your backend |
Traces appear with no gen_ai.* attrs | LLM call went through code path that bypasses telemetry.LLMMiddleware | Add caller = telemetry.LLMMiddleware(caller) to the new code path (see internal/llm/middleware.go for the pattern) |
| Spans drop on graceful shutdown | Shutdown hook not running | Confirm the binary exits via Shutdown() not SIGKILL; telemetryShutdown is called from server_lifecycle.go:Shutdown |