Observability
DeepFellow Server and DeepFellow Infra expose three kinds of observability data: Prometheus metrics, OpenTelemetry traces and logs, and simple health checks. This page gathers the endpoints, environment variables, and metric names in one place. For how to view container logs from the CLI, see Logs and Status. For how to edit these settings after installation, see DeepFellow Server Web Panel and DeepFellow Infra Web Panel.
Quick Start
To go from a fresh installation to dashboards and traces, work through these steps in order:
- Confirm the built-in health checks respond, so you know the endpoints are reachable before adding anything else.
- Read the metrics auth credentials and confirm
GET /metricsreturns data. - Point a Prometheus server at both
/metricsendpoints, then add it as a Grafana data source and build dashboards from the metric tables below. - Enable OpenTelemetry tracing and logging, and point
otel_exporter_otlp_endpointat a collector, either a local debug collector or Jaeger. - Send a request and confirm the trace and log records arrive at your collector before relying on them.
The sections below cover each step in detail, with example configuration and commands to verify each one works.
Health Checks
Both components expose a GET /health endpoint that requires no authentication and returns a static "ok" response. Use it for Docker health checks and load balancer probes.
curl http://localhost:8000/health
curl http://localhost:8086/healthBoth components also expose a GET /info endpoint that requires authentication and returns version information:
- On DeepFellow Server,
/inforeturns the server's version and the connectivity status and version of the configured DeepFellow Infra. - On DeepFellow Infra,
/inforeturns the running Infra's version.
DeepFellow Server also exposes GET /ready, which requires no authentication and checks its dependencies. It returns 200 with {"status": "ready"} when MongoDB answers. Otherwise, it returns 503 with {"status": "not_ready"}. MongoDB is the only dependency the server cannot work without, so RabbitMQ, DeepFellow Infra, and the vector database do not affect /ready. The response does not say why the server is not ready. To check every dependency, read the dependency_up metric. Use /ready for readiness probes, and /health for liveness probes.
curl http://localhost:8000/readyDeepFellow Server additionally exposes GET /admin/infra/health, an admin-only endpoint that probes the configured DeepFellow Infra directly and reports one of ok, wrong_api_key, not_found, unreachable, or timeout.
The Nightshift worker has no /health endpoint. To check it, run python -m server.workers.healthcheck in the worker's environment. See Nightshift Health Check.
Metrics (Prometheus)
Both components expose a GET /metrics endpoint formatted for Prometheus scraping. Metrics are always collected, independent of the OpenTelemetry tracing and logging settings described below.
The endpoint requires HTTP Basic authentication. Configure the credentials with the DF_METRICS_USERNAME and DF_METRICS_PASSWORD environment variables, or through the Metrics Auth section of the Server Configuration card and the equivalent Infra Configuration page.
Verify the endpoint with the credentials you configured:
curl -u "$DF_METRICS_USERNAME:$DF_METRICS_PASSWORD" http://localhost:8000/metrics
curl -u "$DF_METRICS_USERNAME:$DF_METRICS_PASSWORD" http://localhost:8086/metricsViewing Metrics in Grafana
Point a Prometheus server at /metrics on DeepFellow Server and DeepFellow Infra, with HTTP Basic authentication configured in its scrape config:
scrape_configs:
- job_name: deepfellow-server
basic_auth:
username: <DF_METRICS_USERNAME>
password: <DF_METRICS_PASSWORD>
static_configs:
- targets: ["deepfellow-server-host:8000"]
- job_name: deepfellow-infra
basic_auth:
username: <DF_METRICS_USERNAME>
password: <DF_METRICS_PASSWORD>
static_configs:
- targets: ["deepfellow-infra-host:8086"]Then, in Grafana, go to Connections > Data sources > Add data source, choose Prometheus, and set its Connection URL to your Prometheus server's address, for example http://prometheus:9090. Click Save & test to confirm Grafana can reach it. From there, create a dashboard and add a panel for each metric you want to chart, using the metric names listed below as the query.

Server Metrics
Every label has a small, fixed set of values. No label holds a user, organization, project, file, or vector store ID, a URL, or a prompt. The http_route label holds the matched route template, for example /v1/files/{file_id}, or unmatched for a request that matched no route.
HTTP
| Metric | Type | Description |
|---|---|---|
http_server_request_duration_seconds | Histogram | Duration of HTTP requests, across all routes. For a streamed response, the duration covers the whole stream. |
http_server_active_requests | Gauge | Number of HTTP requests currently being processed |
http_server_max_concurrent_requests | Gauge | Configured max_concurrent_requests. To chart saturation, divide http_server_active_requests by it. |
http_server_auth_failures_total{http_route,credential_type,reason} | Counter | Number of requests rejected with 401 (reason="unauthorized") or 403 (reason="forbidden"). credential_type is bearer, basic, api_key, other, or none. forbidden also covers an authorization denial for valid credentials, such as a project scope or a plugin guard, so to detect credential stuffing, use only reason="unauthorized". |
http_server_stream_terminations_total{http_route,reason} | Counter | Number of streamed responses that failed midway (reason="error") or that the client left (reason="client_disconnect") |
errors_handled_total{error,status_code} | Counter | Number of errors that DeepFellow Server turned into a response. error is doc_chunker, reranker, graph_query, rabbitmq_unavailable, infra_auth, or unhandled. |
sentry_events_total{outcome} | Counter | Number of exceptions reported to Sentry. outcome is sent or failed. |
GenAI and DeepFellow Infra Calls
| Metric | Type | Description |
|---|---|---|
gen_ai_server_time_to_first_token_seconds | Histogram | Time from request receipt to the first generated token, for streamed requests |
gen_ai_server_tokens_per_second | Histogram | Output token throughput |
gen_ai_client_token_usage | Histogram | Number of input and output tokens a request used |
upstream_request_duration_seconds{service,outcome} | Histogram | Duration of calls to DeepFellow Infra services. Its _count is the number of calls. |
task_manager_active_tasks{task_manager} | Gauge | Number of tasks queued or running in the embedding worker pool |
task_manager_capacity{task_manager} | Gauge | Configured maximum concurrent tasks of the embedding worker pool |
For upstream_request_duration_seconds, service is embedding, sparse_embedding, reranker, lemmatizer, doc_chunker, entity_extractor, image_generation, llm_metadata, llm_summarization, or llm_df_abuse. outcome is success, timeout, quota (status 429), http_4xx, http_5xx, cancelled (the client left), or error.
Files and Vector Stores
| Metric | Type | Description |
|---|---|---|
storage_file_upload_count_total{filetype,outcome} | Counter | Number of file uploads. outcome is success, too_large, cancelled (the client aborted the upload), or error. |
storage_file_upload_size_bytes_total{filetype} | Counter | Bytes of successfully uploaded files |
storage_file_download_count_total{kind,outcome} | Counter | Number of file downloads. kind is content or asset. outcome is success, not_found, or error. |
storage_file_download_size_bytes_total{kind} | Counter | Bytes of successfully downloaded files |
vector_store_insert_count_total{db_system} | Counter | Number of vectors the vector database accepted |
vector_store_insert_size_bytes_total{db_system} | Counter | Bytes of dense vector data the vector database accepted, at 4 bytes per value |
vector_store_search_count_total{outcome} | Counter | Number of vector store searches. outcome is success, client_error (status 404 or another 4xx), or error. |
vector_store_search_size_bytes_total | Counter | Bytes of text that searches returned |
vector_store_expired_deleted_total | Counter | Number of expired vector stores that the expiry sweeper deleted |
vector_db_operation_duration_seconds{db_system,db_operation_name,outcome} | Histogram | Duration of vector database operations. outcome is success, failure (the database reported an error), or error (the call raised an exception). |
vector_db_remove_vectors_failed_attempts_total{db_system} | Counter | Number of failed attempts to delete vectors, each of which DeepFellow Server retries if the error is temporary |
graph_operation_duration_seconds{operation,outcome} | Histogram | Duration of Knowledge Graph operations: ingest, finalize, remove, retrieve, or complete |
For filetype, DeepFellow Server reports the lowercase file extension of a known type, for example .pdf. Any other extension is other, and a file without an extension is none.
Plugins
| Metric | Type | Description |
|---|---|---|
plugin_invocation_count_total{plugin,hook,outcome} | Counter | Number of plugin hook calls |
plugin_duration_seconds{plugin,hook,outcome} | Histogram | Duration of a plugin hook call |
ti_check_duration_seconds{plugin,outcome} | Histogram | Duration of a Threat Intelligence check |
anonymize_entities_total{entity_type} | Counter | Number of entities that the df_anonymize plugin replaced with tokens |
hook is before_request, after_request, or on_error. outcome is ok, blocked (the plugin stopped the request), cancelled (the client left), or error (the hook raised an error and DeepFellow Server skipped it).
For ti_check_duration_seconds, outcome is safe, unsafe, rejected, fail_open, unavailable_blocked, or error. A fail_open check means Threat Intelligence was unreachable and the plugin let the request through unchecked. To get notified, alert on increase(ti_check_duration_seconds_count{outcome="fail_open"}[10m]) > 0.
Datastores and Queues
| Metric | Type | Description |
|---|---|---|
mongodb_command_duration_seconds{db_operation_name,outcome} | Histogram | Duration of MongoDB commands. outcome is success or failure. |
mongodb_connections_open | Gauge | Number of connections open in the MongoDB connection pool |
mongodb_connections_in_use | Gauge | Number of MongoDB connections that an operation currently holds |
mongodb_connection_checkout_failures_total{reason} | Counter | Number of failed attempts to get a connection from the pool |
rabbitmq_connected | Gauge | 1 while DeepFellow Server has a RabbitMQ connection, 0 otherwise |
rabbitmq_reconnects_total | Counter | Number of times DeepFellow Server re-established a lost RabbitMQ connection |
rabbitmq_publish_count_total{queue,outcome} | Counter | Number of messages DeepFellow Server published. outcome is success or error. |
rabbitmq_queue_messages{queue,kind} | Gauge | Number of messages waiting in a Nightshift queue. kind="main" is the queue itself, and kind="retry" is the sum over its retry queues. |
rabbitmq_queue_consumers{queue} | Gauge | Number of consumers attached to a Nightshift queue |
rabbitmq_queue_poll_failures_total{queue} | Counter | Number of queue depth checks that failed or timed out |
DeepFellow Server polls the queue gauges every 15 seconds, so they can lag the broker slightly. While the broker is unreachable, they report nothing. When the check of a single queue fails, only that queue's gauges disappear, and rabbitmq_queue_poll_failures_total counts the failure.
Dependencies and Health
| Metric | Type | Description |
|---|---|---|
dependency_up{dependency} | Gauge | 1 if the dependency answered the last check, 0 otherwise. dependency is mongodb, rabbitmq, infra, or vector_db. |
build_info{version} | Gauge | Always 1. The version label holds the DeepFellow Server version. |
process_started_seconds | Gauge | Unix time that the process started |
config_updates_total{outcome} | Counter | Number of PUT /admin/config calls. outcome is applied, rejected, or failed. |
smtp_emails_total{outcome} | Counter | Number of emails sent through SMTP. outcome is sent or failed. |
DeepFellow Server checks the dependencies every 15 seconds. The /ready endpoint does not use them, because it checks only MongoDB. DeepFellow Infra is 1 only if its /info endpoint answers with status 200, so a wrong API key reports 0.
Background Jobs, Webhooks, and MCP
| Metric | Type | Description |
|---|---|---|
background_job_runs_total{background_job,outcome} | Counter | Number of runs of a periodic job. background_job is expiry_sweeper or fine_tuning_poll. outcome is success, partial (some items failed), or error (the run raised an error, or every item failed). |
background_job_last_success_seconds{background_job} | Gauge | Unix time of the job's last success or partial run. To get the time since then, use time() - background_job_last_success_seconds. |
background_job_item_failures_total{background_job} | Counter | Number of items that a periodic job failed to handle, such as an expired vector store or a fine-tuning job |
fine_tuning_jobs_active{status} | Gauge | Number of fine-tuning jobs that are not finished, as of the last poll |
fine_tuning_sync_failures_total{reason} | Counter | Number of failed attempts to read a job's status from its worker. reason is worker_not_found, worker_error, or marked_failed. |
webhook_deliveries_total{result,status_class} | Counter | Number of webhook delivery attempts |
webhook_delivery_duration_seconds{result,status_class} | Histogram | Duration of a webhook delivery attempt |
mcp_sessions | Gauge | Number of MCP sessions in the session pool |
mcp_session_creations_total{outcome} | Counter | Number of attempts to open an MCP session. outcome is success, error, or cooldown (skipped because the endpoint failed recently). |
mcp_call_duration_seconds{operation,outcome} | Histogram | Duration of MCP calls. outcome is success, skipped, or error. |
For webhook_deliveries_total, result is delivered, http_error, timeout, network_error, dropped_endpoint_missing, or dropped_error. status_class is 2xx, 3xx, 4xx, 5xx, or none when there was no response. A webhook whose endpoint no longer exists counts as dropped_endpoint_missing, and an unexpected error while sending counts as dropped_error. A delivery that used up all its retries appears in nightshift_messages_total{queue="webhook_deliveries",outcome="dropped_exhausted"}.
The background_job label is not named job, because Prometheus reserves job for the scrape target and would rename it to exported_job. DeepFellow Server sets background_job_last_success_seconds when the job starts, so before the first run it holds the start time, not the time of a success. This way, a staleness alert also works after a restart.
Token Usage and Throughput Metrics
gen_ai_server_time_to_first_token_seconds and gen_ai_server_tokens_per_second cover /v1/chat/completions, /v1/completions, /v1/responses, /v1/messages, and the Ollama-compatible /api/chat. gen_ai_client_token_usage covers the same endpoints, plus /v1/embeddings and /v1/images/generations. All three metrics record only responses with status 200. gen_ai_server_time_to_first_token_seconds records only requests that set stream: true. The other two metrics record both streamed and non-streamed requests.
All three metrics carry the gen_ai_request_model, http_route, and http_request_method labels. gen_ai_server_tokens_per_second also carries stream. gen_ai_client_token_usage also carries gen_ai_token_type, and records a separate sample for each token type: input and output.
Throughput varies by endpoint. To compare gen_ai_server_tokens_per_second over time, filter it by http_route. For /v1/responses with server-side tool calls, the throughput time includes running the tools.
Token counts come from the usage object of the response. Anthropic-style cached prompt tokens count as input tokens. If a response reports no usage, for example a streamed /v1/completions request without stream_options.include_usage, DeepFellow Server records neither a token usage sample nor a throughput sample for it. If a stream fails or the client leaves it early, the output so far is partial. In that case, DeepFellow Server records only the input tokens and no throughput sample.
The _sum series of gen_ai_client_token_usage is the total token count. To chart the token rate per model and token type, use this query:
sum by (gen_ai_request_model, gen_ai_token_type) (rate(gen_ai_client_token_usage_sum[5m]))Infra Metrics
| Metric | Type | Description |
|---|---|---|
deepfellow | Info | Infra name and URL |
deepfellow_models_installed | Gauge | Number of currently installed models across all services |
deepfellow_services_installed | Gauge | Number of installed services |
deepfellow_subinfras_count | Gauge | Number of connected child Infras in a Mesh |
deepfellow_infra_gpu_count | Gauge | Number of available GPUs |
deepfellow_model_usage{model_name,model_type} | Gauge | Current concurrent usage per model |
deepfellow_requests_total{model_name,model_type,status} | Counter | Total number of requests |
deepfellow_request_duration_seconds{model_name,model_type} | Histogram | Request duration |
deepfellow_request_errors_total{model_name,error_type} | Counter | Total request errors, by type |
deepfellow_requests_in_flight{model_type} | Gauge | Number of requests currently being processed |
Nightshift Metrics
The Nightshift worker serves its own /metrics endpoint on port DF_NIGHTSHIFT_METRICS_PORT (default 9464). On every scrape of its own /metrics, DeepFellow Server fetches the worker's endpoint from DF_NIGHTSHIFT_METRICS_URL and serves the worker's metrics too. The DeepFellow Server scrape config above covers both processes. You don't need a separate scrape job for the worker. For the settings, see Nightshift Monitoring.
Every sample from the worker carries the label process="nightshift". The label keeps the worker's samples apart from the server's samples of the same metric, such as target_info or upstream_request_duration_seconds.
nightshift_metrics_up reports whether the worker's metrics were collected. It is 1 when DeepFellow Server fetched them for the current scrape, and 0 when the worker did not answer, or did not answer within 2 seconds. A worker that fails or answers slowly never fails the DeepFellow Server scrape.
nightshift_metrics_up is also 0 while the worker is stopped on purpose, for example outside the hours of shift mode. Do not alert on it alone. The NightshiftDown rule in Alerts and Dashboard also requires waiting messages in a queue.
If you scrape the worker's endpoint directly, set DF_NIGHTSHIFT_METRICS_URL to an empty value. Otherwise, Prometheus collects every worker series twice.
Every Nightshift metric carries a queue label with the name of the RabbitMQ queue: metadata_expansion, document_summarization, webhook_deliveries, vector_store_file_processing, ontology_discovery, or graph_document_ingestion.
| Metric | Type | Description |
|---|---|---|
nightshift_messages_total{queue,outcome} | Counter | Number of messages handled, by how each one ended |
nightshift_handler_duration_seconds{queue,outcome} | Histogram | Time from a message's delivery to its acknowledgment, with buckets from 0.1 seconds up to 3 hours |
nightshift_in_flight{queue} | Gauge | Number of messages currently being handled |
nightshift_consumer_up{queue} | Gauge | 1 while the queue's consumer runs, 0 once it has stopped |
nightshift_last_message_seconds{queue} | Gauge | Unix time that the queue's consumer last finished a message. The worker sets it when the consumer starts, so before the first message it holds the start time. This way, a stuck-consumer alert also works after a restart. |
process_started_seconds | Gauge | Unix time that the worker process started. It changes each time the worker restarts to apply a configuration reload. |
The outcome label takes one of the following values:
| Outcome | Meaning |
|---|---|
success | The message was processed. |
failed | The job recorded the failure itself, for example by marking a document, file, ontology, or Knowledge Graph ingestion job as failed. The message is not redelivered. |
retry | The attempt failed, and the message is scheduled for redelivery with backoff. See Retry Behavior. |
dropped_malformed | The message body was invalid, so the worker dropped it without a retry. |
dropped_exhausted | The last allowed attempt failed with an error, so the worker dropped the message. |
dropped_retry_failed | The attempt failed, and the worker could not schedule the redelivery, so it dropped the message. |
A queue with waiting messages (rabbitmq_queue_messages{kind="main"} > 0) whose nightshift_last_message_seconds is old has a stuck consumer. The worker also reports the server metrics that apply to it, such as upstream_request_duration_seconds from GenAI and DeepFellow Infra Calls and webhook_deliveries_total from Background Jobs, Webhooks, and MCP, labelled process="nightshift". For a webhook delivery, failed means the worker dropped it because of an unexpected error while sending (result="dropped_error"). A webhook whose endpoint no longer exists ends as success, with result="dropped_endpoint_missing".
A nightshift_consumer_up series appears for a queue only once its consumer has started. A worker that is still connecting to RabbitMQ reports no nightshift_consumer_up series at all.
Alerts and Dashboard
The monitoring/ directory of the DeepFellow Server repository holds a ready-made setup:
prometheus.yml: scrapes the DeepFellow Server (with basic authentication), which also serves the Nightshift worker's metrics.rules/df-server.rules.yml: alert rules for these conditions:- API: the server is down, a 5xx rate above 5% (
DfServerHigh5xxRate), requests nearmax_concurrent_requests, a spike in authentication failures (DfServerAuthFailureSpike), failing streams, and a slow time to first token. - Dependencies: a dependency that is down, failing calls to DeepFellow Infra services (
DfServerInfraCallsFailing), vector database errors, MongoDB command failures, MongoDB pool checkout failures (DfServerMongoPoolCheckoutFailures), a saturated worker pool, and Threat Intelligence failing open. - Background jobs: a stale job (
DfServerBackgroundJobStale) and a job that fails to handle some items (DfServerBackgroundJobItemsFailing). - Nightshift and RabbitMQ: the worker's metrics are unavailable while a queue has waiting messages (
NightshiftDown), a stopped or stuck consumer, a queue backlog, a queue without consumers (NightshiftQueueWithoutConsumers), dropped messages (NightshiftMessagesDropped), queue depth checks that keep failing (NightshiftQueueMonitoringBlind), and a lost RabbitMQ connection (RabbitMqDisconnected). - Webhooks: failing deliveries and deliveries that were permanently lost.
- API: the server is down, a 5xx rate above 5% (
grafana/df-server-dashboard.json: a Grafana dashboard that charts the metrics above. To use it, go to Dashboards > New > Import and upload the file.
The rules are a starting point. Adjust the thresholds to your traffic, and check the rule file with promtool check rules.
Tracing and Logs (OpenTelemetry)
Both DeepFellow Server and DeepFellow Infra export traces and logs to an OpenTelemetry collector over OTLP gRPC. Both export under the service name llm-audit, so you will correlate spans and log records from both components in your observability backend. The Nightshift worker exports under the service name nightshift. Tracing and log export are independent; enable each one separately.
On DeepFellow Server, these are dynamic settings, editable through the OpenTelemetry section of the Server Configuration card or the /admin/config API:
| Setting | Environment variable | Default | Description |
|---|---|---|---|
otel_exporter_otlp_endpoint | DF_OTEL_EXPORTER_OTLP_ENDPOINT | http://localhost:4317 | OTLP gRPC endpoint. Must accept the connection over insecure gRPC. |
otel_tracing_enabled | DF_OTEL_TRACING_ENABLED | false | Exports request traces. |
otel_logging_enabled | DF_OTEL_LOGGING_ENABLED | false | Forwards server log records to the collector. |
DeepFellow Infra exposes the same three settings (otel_exporter_otlp_endpoint, otel_tracing_enabled, otel_logging_enabled) as dynamic configuration, editable with deepfellow infra config set or from the Infra Web Panel's Configuration page.
For setup during installation, including running a local debug-only collector with --otel-local or connecting to an existing one with --otel-url, see Installing DeepFellow Server. The --otel-local collector only writes trace data to its own container logs; it has no browser UI. To browse traces, point otel_exporter_otlp_endpoint at a backend such as Jaeger instead, as described below.
What Gets Traced
When tracing is enabled, DeepFellow Server instruments:
- Every HTTP endpoint request, capturing the route, headers, authentication and project or organization IDs, request body fields, including full message lists for chat, messages, completions, and responses endpoints, with PII anonymization applied, and the response text.
- Token usage of AI endpoint requests, as described in Token Usage in Traces.
- Vector store searches and other internal service calls.
- MCP tool calls, captured as
mcp.call_toolspans with the tool name.
Token Usage in Traces
For both streamed and non-streamed requests to /v1/chat/completions, /v1/completions, /v1/responses, /v1/messages, /api/chat, /v1/embeddings, and /v1/images/generations, the endpoint span carries the following OpenTelemetry GenAI attributes:
| Attribute | Description |
|---|---|
gen_ai.usage.input_tokens | Number of input tokens, including Anthropic-style cached prompt tokens |
gen_ai.usage.output_tokens | Number of output tokens |
gen_ai.response.finish_reasons | Reasons the model stopped generating, for example length when it reached max_tokens |
For /v1/responses with server-side tool calls, the token counts cover every model call that DeepFellow Server makes while running the tools. If a response reports no usage, its span gets no gen_ai.usage.* attributes. The span still gets gen_ai.response.finish_reasons if the response reports a finish reason. If a stream fails or the client leaves it early, its span gets only gen_ai.usage.input_tokens, because the output so far is partial.
To keep memory use bounded, DeepFellow Server reads only the usage object at the end of a response body or stream event larger than 256 KiB, such as a large embeddings batch or a base64-encoded image. For such a response, the span gets no gen_ai.response.finish_reasons. Ollama reports token counts outside usage, so for such an /api/chat response, neither the span nor the token usage metrics get token counts.
Nightshift Traces
The Nightshift worker reads the same otel_* settings from config.json as DeepFellow Server, and applies a change on its next configuration reload. With otel_tracing_enabled, the worker handles each message in a nightshift <queue> span, for example nightshift metadata_expansion. The span continues the trace of the API request that queued the message, so one trace shows both the request and the background work it started. Every redelivery of a failed message stays in the same trace.
Each span records the attempt number in nightshift.attempt, the attempt limit in nightshift.max_attempts, and how the message ended in nightshift.outcome, with the same values as the outcome metric label. A span whose attempt raised an error has an error status and records the exception.
Messages queued before an upgrade to a DeepFellow Server version with Nightshift tracing carry no trace context. The worker processes them as before, each in a new trace.
Viewing Traces in a Browser
DeepFellow exports plain OTLP, so any OTLP-compatible backend will work. Jaeger is a common choice for viewing these traces in a browser. Run it with its OTLP receiver enabled, reachable from DeepFellow Server and Infra:
docker run -d --name jaeger -p 4317:4317 -p 16686:16686 jaegertracing/all-in-one:latestSet otel_exporter_otlp_endpoint to http://jaeger:4317 (or the host running Jaeger), enable otel_tracing_enabled, and send a request. Confirm the trace arrived before opening the UI:
curl 'http://localhost:16686/api/services'The response lists llm-audit once a trace has arrived. Open http://localhost:16686 to search and inspect traces by service name.

Selecting a trace shows its spans and their tags, for example the request's model and messages on a /v1/chat/completions span:

Viewing Collector Logs
To tail the logs of a locally installed OpenTelemetry collector, use deepfellow otel logs. See OpenTelemetry Collector Logs.
Log Level
DeepFellow Server controls its own log verbosity with the DF_LOG_LEVEL environment variable, or the LOG_LEVEL dynamic setting in the Server Configuration card. It defaults to INFO. The Nightshift worker applies the same setting, and logs one line per message with its queue, outcome, duration, and attempt number. This is separate from otel_logging_enabled, which controls whether those log records also export to the OpenTelemetry collector. DeepFellow Server logs to standard output as plain text; it does not emit structured or JSON-formatted logs. DeepFellow Infra has no equivalent log level setting.
We use cookies on our website. We use them to ensure proper functioning of the site and, if you agree, for purposes such as analytics, marketing, and targeting ads.