<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shivanshu</title>
    <description>The latest articles on DEV Community by Shivanshu (@ishivanshuk).</description>
    <link>https://dev.to/ishivanshuk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4048268%2Faf3504fd-6e96-4ae7-9cef-954a835270b3.jpg</url>
      <title>DEV Community: Shivanshu</title>
      <link>https://dev.to/ishivanshuk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ishivanshuk"/>
    <language>en</language>
    <item>
      <title>Helios: Turning SigNoz Telemetry into an On-Call AI Agent</title>
      <dc:creator>Shivanshu</dc:creator>
      <pubDate>Sun, 26 Jul 2026 18:13:14 +0000</pubDate>
      <link>https://dev.to/ishivanshuk/helios-turning-signoz-telemetry-into-an-on-call-ai-agent-5ce6</link>
      <guid>https://dev.to/ishivanshuk/helios-turning-signoz-telemetry-into-an-on-call-ai-agent-5ce6</guid>
      <description>&lt;p&gt;After a deploy, the question is rarely “do we have dashboards?” — it’s “what actually broke, and what should we do?” Helios is our answer: an AI agent that treats SigNoz as the source of truth, queries it through the SigNoz MCP, and answers like a sharp on-call engineer.&lt;/p&gt;

&lt;p&gt;This post walks through what we built for the Agents of SigNoz hackathon, how OpenTelemetry and SigNoz fit in, and the gotchas we hit wiring an LLM to real traces.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Helios is
&lt;/h2&gt;

&lt;p&gt;Helios is a CLI + optional HTTP API that runs observability tasks:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;helios investigate "…"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Freeform questions over live telemetry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;helios deploy-health&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compare a deploy window vs baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;helios rca&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Root-cause a timeout / error window&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;helios autoscale&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Argue for HPA changes from pressure signals&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Under the hood it is a standard agent loop: &lt;strong&gt;LLM ↔ tools ↔ validated JSON&lt;/strong&gt;. The tools are not home-grown scrapers — they are &lt;strong&gt;SigNoz MCP tools&lt;/strong&gt; pointed at a local SigNoz CE stack.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SigNoz
&lt;/h2&gt;

&lt;p&gt;We needed three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;OpenTelemetry-native ingest&lt;/strong&gt; — demo apps already speak OTLP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queryable APIs for an agent&lt;/strong&gt; — MCP exposes list/search/aggregate without reinventing ClickHouse SQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A UI humans trust&lt;/strong&gt; — every Helios answer can deep-link to the same traces an engineer opens in SigNoz.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Self-hosted SigNoz CE (Docker Compose via Foundry/casting) gave us UI on &lt;code&gt;:8080&lt;/code&gt;, OTLP on &lt;code&gt;:4317/:4318&lt;/code&gt;, and MCP on &lt;code&gt;:8000/mcp&lt;/code&gt; with no SaaS lock-in for the demo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture (brief)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  loadgen ──► checkout ──► payment ──► inventory     
                    │ OTLP
                    ▼
            otel-collector (kind: observability)
                    │ OTLP → host gateway :4317
                    ▼
         ┌──────────────────────────┐
         │  SigNoz CE (Docker)      │
         │  UI :8080 · OTLP · CH    │
         │  MCP :8000/mcp           │
         └────────────▲─────────────┘
                      │ MCP tools
         ┌────────────┴─────────────┐
         │  Helios (CLI / :9090)    │
         │  LLM + agent loop        │
         └──────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pipeline roles&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apps&lt;/strong&gt; — FastAPI services instrumented with OpenTelemetry (FastAPI + httpx auto-instrumentation).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collector&lt;/strong&gt; — Batches traces/metrics/logs and exports to SigNoz.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SigNoz&lt;/strong&gt; — Stores telemetry; UI for humans; MCP for the agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Helios&lt;/strong&gt; — Plans investigations, calls MCP tools, emits structured results.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How we emit telemetry into SigNoz
&lt;/h2&gt;

&lt;p&gt;Each demo service configures a tracer provider and OTLP gRPC exporter toward the in-cluster collector:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://otel-collector:4317&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service.name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;service_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...})&lt;/span&gt;
&lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TracerProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;exporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OTLPSpanExporter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;insecure&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_span_processor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BatchSpanProcessor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exporter&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;FastAPIInstrumentor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instrument_app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nc"&gt;HTTPXClientInstrumentor&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;instrument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Faults are injected as Deployment env (&lt;code&gt;ERROR_RATE&lt;/code&gt;, &lt;code&gt;BASE_LATENCY_MS&lt;/code&gt;, &lt;code&gt;FAIL_DOWNSTREAM&lt;/code&gt;, &lt;code&gt;CPU_BURN_MS&lt;/code&gt;) so we can replay scenarios: healthy baseline, elevated checkout errors, payment→inventory timeouts, and load pressure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gotcha we hit:&lt;/strong&gt; On Docker Desktop + kind, &lt;code&gt;host.docker.internal&lt;/code&gt; for the collector → SigNoz hop preferred IPv6 and broke gRPC. Pinning the exporter to the host-gateway IPv4 (&lt;code&gt;192.168.65.254:4317&lt;/code&gt;) fixed “traces missing in ClickHouse.”&lt;/p&gt;




&lt;h2&gt;
  
  
  How Helios &lt;em&gt;reads&lt;/em&gt; SigNoz (MCP)
&lt;/h2&gt;

&lt;p&gt;Helios connects to &lt;code&gt;http://localhost:8000/mcp&lt;/code&gt;, lists tools (~40 in our demo), and lets the model call them. The playbook is deliberate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;signoz_list_services&lt;/code&gt; — confirm the service exists in the window.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;signoz_aggregate_traces&lt;/code&gt; — &lt;code&gt;count&lt;/code&gt; / &lt;code&gt;p95&lt;/code&gt; with &lt;code&gt;aggregateOn=duration_nano&lt;/code&gt;, plus &lt;code&gt;error: true&lt;/code&gt; for failures.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;signoz_search_traces&lt;/code&gt; — sample error spans.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;signoz_get_trace_details&lt;/code&gt; — when RCA needs the payment→inventory story.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Local casting config enables MCP and impersonation so the agent does not need a client API key; the MCP server holds a server-side credential.&lt;/p&gt;

&lt;p&gt;Example freeform investigation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helios &lt;span class="nt"&gt;--quiet&lt;/span&gt; investigate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"Why is payment timing out? Is inventory the failing dependency?"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--service&lt;/span&gt; payment-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--service&lt;/span&gt; inventory-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; demo &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--start&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$START&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--end&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$END&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typical answer (paraphrased from a real run): payment is timing out because inventory p95 latency sits around ~3s; payment sees &lt;code&gt;ReadTimeout&lt;/code&gt; / HTTP 504 — inventory is the failing dependency even when it doesn’t emit error spans of its own.&lt;/p&gt;

&lt;p&gt;That distinction — &lt;strong&gt;slow dependency vs erroring dependency&lt;/strong&gt; — only shows up clearly when the agent can join cross-service traces in SigNoz.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo scenarios we validated against SigNoz
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Fault&lt;/th&gt;
&lt;th&gt;What Helios should conclude&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Healthy&lt;/td&gt;
&lt;td&gt;Reset env&lt;/td&gt;
&lt;td&gt;Low/zero errors, stable latency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy degraded&lt;/td&gt;
&lt;td&gt;Checkout &lt;code&gt;ERROR_RATE≈0.25&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Elevated errors vs prior window&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Downstream timeout&lt;/td&gt;
&lt;td&gt;Payment short timeout + slow inventory&lt;/td&gt;
&lt;td&gt;Dependency / inventory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load pressure&lt;/td&gt;
&lt;td&gt;Higher RPS + CPU burn&lt;/td&gt;
&lt;td&gt;Scale / pressure recommendation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We scripted one-at-a-time injection (&lt;code&gt;make demo-scenario-*&lt;/code&gt;), waited for traffic, then ran &lt;code&gt;investigate&lt;/code&gt; so signals don’t mix. Answers deep-link to &lt;code&gt;http://localhost:8080&lt;/code&gt; so judges (and we) can verify in the SigNoz UI.&lt;/p&gt;




&lt;h2&gt;
  
  
  What surprised us
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Empty logs ≠ missing telemetry.&lt;/strong&gt; Our demos are trace-heavy. Early prompts over-weighted “no logs” as failure. We taught the agent: prefer traces; treat empty logs as normal in the local demo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggregations need explicit fields.&lt;/strong&gt; &lt;code&gt;signoz_aggregate_traces&lt;/code&gt; wants &lt;code&gt;aggregation&lt;/code&gt; (and &lt;code&gt;aggregateOn&lt;/code&gt; for p95). Vague tool calls burn retries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema discipline matters.&lt;/strong&gt; The model occasionally returned &lt;code&gt;confidence: "high"&lt;/code&gt; or &lt;code&gt;severity: "major"&lt;/code&gt;. We tightened prompts &lt;em&gt;and&lt;/em&gt; added Pydantic coercions so the CLI doesn’t explode mid-demo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Baselines beat absolute thresholds.&lt;/strong&gt; “10% errors” means more when the prior window was 0% — Helios compares windows the same way a human would in SigNoz.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SigNoz is not just a dashboard in Helios — it is the &lt;strong&gt;memory and toolkit&lt;/strong&gt; of the agent.&lt;/li&gt;
&lt;li&gt;OpenTelemetry + collector + SigNoz CE is enough to stand up a credible multi-service demo on a laptop.&lt;/li&gt;
&lt;li&gt;MCP is the right abstraction: the LLM learns &lt;em&gt;tool names&lt;/em&gt;, not proprietary SQL.&lt;/li&gt;
&lt;li&gt;The best agent answers are the ones you can click into SigNoz and reproduce.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re building AI on top of observability, start with a real backend and a real UI. For us, that backend and UI were SigNoz.&lt;/p&gt;

</description>
      <category>signoz</category>
      <category>opentelemetry</category>
      <category>mcp</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
