<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Observability on GENIE.AI</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/</link><description>Recent content in Observability on GENIE.AI</description><generator>Hugo</generator><language>en</language><atom:link href="https://genie-ai-7e342b.opensource.unicc.org/docs/observability/index.xml" rel="self" type="application/rss+xml"/><item><title>Stack Overview</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/overview/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/overview/</guid><description>&lt;p&gt;The observability stack has four layers: &lt;strong&gt;instrumentation&lt;/strong&gt; (in the apps),
&lt;strong&gt;collection&lt;/strong&gt; (the OpenTelemetry Collector), &lt;strong&gt;storage&lt;/strong&gt; (the Victoria trio),
and &lt;strong&gt;presentation&lt;/strong&gt; (Grafana).&lt;/p&gt;
&lt;h2 id="layer-1--instrumentation"&gt;Layer 1 — Instrumentation&lt;/h2&gt;
&lt;p&gt;Each application service initialises the OpenTelemetry SDK and emits telemetry
through the standard OTLP protocol.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Service&lt;/th&gt;
 &lt;th&gt;Language&lt;/th&gt;
 &lt;th&gt;What it emits&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Backend (BFF)&lt;/td&gt;
 &lt;td&gt;Node.js&lt;/td&gt;
 &lt;td&gt;Express request spans, ArangoDB query spans, custom business spans, Prometheus metrics.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;OPEA services&lt;/td&gt;
 &lt;td&gt;Python&lt;/td&gt;
 &lt;td&gt;FastAPI spans, per-RAG-stage spans (retrieval, reranking, labelling…), service logs.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Kong gateway&lt;/td&gt;
 &lt;td&gt;Lua&lt;/td&gt;
 &lt;td&gt;OTel plugin forwards request traces.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Instrumentation helpers enforce a single way to create spans (so attributes and
PII filtering stay consistent):&lt;/p&gt;</description></item><item><title>Tracing</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/tracing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/tracing/</guid><description>&lt;p&gt;Tracing is what makes a GENIE.AI user query legible. Because every service
propagates a single W3C &lt;code&gt;traceparent&lt;/code&gt; header and every RAG stage emits a span,
one user question produces one contiguous trace that can be read end-to-end in
Grafana — revealing exactly where time went and which chunks were retrieved.&lt;/p&gt;
&lt;h2 id="trace-propagation"&gt;Trace propagation&lt;/h2&gt;
&lt;p&gt;The trace starts at the edge. Kong creates the root span and injects a
&lt;code&gt;traceparent&lt;/code&gt; header into the request. Each downstream hop reads that header,
joins the trace as a child span, and re-injects the header for the next hop:&lt;/p&gt;</description></item><item><title>Dashboards</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/dashboards/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/dashboards/</guid><description>&lt;p&gt;Grafana dashboards are &lt;strong&gt;auto-provisioned&lt;/strong&gt; from &lt;code&gt;configs/grafana/provisioning/&lt;/code&gt;,
so a deployment gets a working set of dashboards the moment the stack starts — no
manual import. They are grouped into two folders.&lt;/p&gt;
&lt;h2 id="application-folder"&gt;Application folder&lt;/h2&gt;
&lt;p&gt;Operational views of the GENIE.AI services themselves.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Dashboard&lt;/th&gt;
 &lt;th&gt;What it shows&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Service health&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Per-service up/down, replica count, error rate, request rate. The landing view for &amp;ldquo;is anything broken?&amp;rdquo;.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Application metrics&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Business and HTTP metrics: request rates, latency distributions, error rates, custom counters.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Service logs&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Centralised log search across all services (VictoriaLogs). Pivot from a metric spike to the matching logs.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Trace explorer&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Distributed-trace search (VictoriaTraces via the Jaeger datasource): filter by service, operation, duration, attribute.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;RAG pipeline trace waterfall&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;A waterfall charting per-service latency across the RAG pipeline (backend, chatqna, retriever, reranker, dataprep), so the slow stage is immediately visible.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="observability-folder"&gt;Observability folder&lt;/h2&gt;
&lt;p&gt;Health of the observability stack itself — so the monitoring does not fail
silently.&lt;/p&gt;</description></item><item><title>Alerting</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/alerting/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/alerting/</guid><description>&lt;p&gt;Alerting is auto-provisioned alongside the dashboards, so a fresh deployment
already watches the failures that matter most: &lt;strong&gt;the stack going silent, storage
filling up, the log pipeline breaking, and trace export failing&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Three files under &lt;code&gt;configs/grafana/provisioning/alerting/&lt;/code&gt; define the setup:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;File&lt;/th&gt;
 &lt;th&gt;Purpose&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;alert-rules.yml&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;The alert definitions (condition + for-duration).&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;notification-policies.yml&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Which alerts route to which contact points, and grouping/escalation.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;contact-points.yml&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Where notifications are sent. The shipped default is a single webhook contact point; Slack/SMTP/PagerDuty are added per environment.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="built-in-alert-rules"&gt;Built-in alert rules&lt;/h2&gt;
&lt;p&gt;The rules target the failure modes that would otherwise make the observability
stack &lt;em&gt;itself&lt;/em&gt; lie to you.&lt;/p&gt;</description></item><item><title>Configuration</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/observability/configuration/</guid><description>&lt;p&gt;The observability stack is &lt;strong&gt;disabled by default&lt;/strong&gt;. Enabling it is a single
environment variable, but a handful of related variables control access,
retention, and sampling.&lt;/p&gt;
&lt;h2 id="enabling"&gt;Enabling&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Variable&lt;/th&gt;
 &lt;th&gt;Default&lt;/th&gt;
 &lt;th&gt;Notes&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;ENABLE_OBSERVABILITY&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Must be &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;&lt;/strong&gt; (not &lt;code&gt;true&lt;/code&gt;/&lt;code&gt;false&lt;/code&gt;). Swarm mode reads this to place the stack.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;http://otel-collector:4318&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;OTLP base URL all instrumented services export to. Override only for an external collector.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;How it is enabled per deployment mode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Docker Compose&lt;/strong&gt; — &lt;code&gt;docker compose --profile observability up -d&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker Swarm&lt;/strong&gt; — &lt;code&gt;ENABLE_OBSERVABILITY=1&lt;/code&gt; in &lt;code&gt;.env&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ansible&lt;/strong&gt; — &lt;code&gt;enable_observability: &amp;quot;1&amp;quot;&lt;/code&gt; in &lt;code&gt;group_vars/all.yml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sampling"&gt;Sampling&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Variable&lt;/th&gt;
 &lt;th&gt;Default&lt;/th&gt;
 &lt;th&gt;Notes&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;OTEL_TRACES_SAMPLER_RATE&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;100.0&lt;/td&gt;
 &lt;td&gt;Trace sampling percentage. Lower for high-volume prod; raise when diagnosing. Metrics and logs are not sampled.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;KONG_TRACING_SAMPLING_RATE&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;1.0&lt;/td&gt;
 &lt;td&gt;Kong trace sampling rate (0–1), aligned with &lt;code&gt;OTEL_TRACES_SAMPLER_RATE&lt;/code&gt;.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;KONG_TRACING_INSTRUMENTATIONS&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;request&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Kong tracing instrumentations. Negligible overhead when the OTel plugin is disabled.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="retention"&gt;Retention&lt;/h2&gt;
&lt;p&gt;Each Victoria store keeps data for a configurable window; lower it to save disk,
raise it for longer historical analysis.&lt;/p&gt;</description></item></channel></rss>