<?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: Shivam Singh</title>
    <description>The latest articles on DEV Community by Shivam Singh (@shivcodez).</description>
    <link>https://dev.to/shivcodez</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%2F4036841%2F92ddb2af-8ed1-4fe0-9df0-159a85b9941d.png</url>
      <title>DEV Community: Shivam Singh</title>
      <link>https://dev.to/shivcodez</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shivcodez"/>
    <language>en</language>
    <item>
      <title>I Built a 4 Service Cascade Failure Just to See If an AI Agent Could Actually Diagnose It</title>
      <dc:creator>Shivam Singh</dc:creator>
      <pubDate>Sat, 25 Jul 2026 20:22:16 +0000</pubDate>
      <link>https://dev.to/shivcodez/i-built-a-4-service-cascade-failure-just-to-see-if-an-ai-agent-could-actually-diagnose-it-1emd</link>
      <guid>https://dev.to/shivcodez/i-built-a-4-service-cascade-failure-just-to-see-if-an-ai-agent-could-actually-diagnose-it-1emd</guid>
      <description>&lt;p&gt;One of the example projects listed for this hackathon was basically "self healing infra." Alert fires, agent restarts a container, done. I figured half the submissions were going to be some version of that, so I didn't want to build it. Also, honestly, it didn't feel like it would prove anything. An agent reacting to a threshold isn't the same as an agent understanding what actually happened.&lt;/p&gt;

&lt;p&gt;So instead of one service with one alert, I built four, chained them together, and then broke one of them on purpose in a way that would trick anyone (or anything) that wasn't actually looking at the trace properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The chain
&lt;/h2&gt;

&lt;p&gt;Order calls Payment, Payment calls Inventory, Inventory calls Notification. Four FastAPI services, one request fans out through all of them over &lt;code&gt;httpx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then I did something mean to myself. I added a chaos flag to Payment that adds a random 2 to 5 second sleep to about 30% of requests, to simulate a flaky downstream dependency.&lt;/p&gt;

&lt;p&gt;Here's the part that made this actually worth building. When Payment is slow, Order looks slow too, because Order is just sitting there waiting on it. If you only look at "which service had the longest request," you'll blame whichever one happens to be closest to the client, which in my case would be Order, and that's the wrong answer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy7cox5m0m1klhpdyxuip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy7cox5m0m1klhpdyxuip.png" alt=" " width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting one trace instead of four
&lt;/h2&gt;

&lt;p&gt;The non negotiable part of this build was that a single request had to show up in SigNoz as one connected trace across all four services, not four separate ones that just happened to be related.&lt;/p&gt;

&lt;p&gt;I self hosted SigNoz through Foundry, same as my pre event blog, then added &lt;code&gt;opentelemetry-instrumentation-fastapi&lt;/code&gt; and &lt;code&gt;opentelemetry-instrumentation-httpx&lt;/code&gt; to each service and pointed the OTLP exporter at my existing deployment. The thing nobody warns you about is that if you create your &lt;code&gt;httpx.AsyncClient&lt;/code&gt; before the instrumentation is wired up, or if the async context gets dropped anywhere in the chain, you just quietly get four disconnected traces instead of one. No error, nothing obviously wrong. You only notice it if you go into SigNoz and check whether the trace IDs actually match across services.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnufgmiqnvbaroygy2n2c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnufgmiqnvbaroygy2n2c.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My root cause agent was confidently wrong once
&lt;/h2&gt;

&lt;p&gt;Once traces were flowing and I had an alert and a dashboard panel showing the cascade shape, I built the actual agent. It pulls a trace through the SigNoz MCP server, hands the span data to Gemini 2.5 Flash, and asks it to name the root cause.&lt;/p&gt;

&lt;p&gt;First version just fed Gemini each span's total duration. Worked fine when Payment's delay was obviously the biggest number in the trace. Then on one run where the trace was only a little slow (normal network jitter, chaos hadn't actually triggered), Gemini confidently blamed Notification. Not because it was reading the data wrong. Notification's own span really was the longest number on the page. It just didn't know that "longest span" and "root cause" aren't the same thing.&lt;/p&gt;

&lt;p&gt;That's the actual lesson I got out of this, and it's not something either the SigNoz docs or the OpenTelemetry docs tell you directly. A span's total duration includes time spent waiting on whatever it called downstream. So a service can look slow purely because something below it is slow. That's not evidence it's guilty. If anything it's evidence it's innocent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self time fixed it
&lt;/h2&gt;

&lt;p&gt;The number that actually matters is self time, how long a span took doing its own work, not counting time spent waiting on its children. I computed it straight from the trace data:&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;self_time_ms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;duration_ms&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;duration_ms&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sorted the spans by self time before sending them to Gemini, and rewrote the prompt to tell it explicitly that self time is the signal to trust, not raw duration. I also bumped my trace search filter from 1 second to 2 seconds, since anything under that was just normal noise, not my actual injected chaos.&lt;/p&gt;

&lt;p&gt;After both changes the diagnosis got reliable. Payment's own span consistently had the highest self time, and the agent named it correctly every time I reran the load test, not just on the runs where the chaos delay happened to be the single biggest number around.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1ywfzhnebg67jpzyoe0i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1ywfzhnebg67jpzyoe0i.png" alt=" " width="800" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Restarting it and then actually proving it worked
&lt;/h2&gt;

&lt;p&gt;Diagnosing the problem isn't the interesting part if the agent doesn't do anything about it. Once Payment is identified, the agent hits an admin endpoint on Payment to disable the chaos flag, standing in for restarting the actual failing dependency. Then it sends 10 fresh requests through the whole chain and times them itself.&lt;/p&gt;

&lt;p&gt;Before the fix, requests were taking 2000 to 5000ms because of the cascade. After, fresh requests averaged 46.12ms with a max of 53.91ms. Back to normal.&lt;/p&gt;

&lt;p&gt;One thing worth admitting. I also queried SigNoz for Payment's P95 as a second check, and that number came back higher than my fresh measurements, because its default window still had all the earlier chaos affected traffic mixed in with the clean requests. My own timed requests were the real proof. SigNoz's number was just supporting evidence, diluted by old data. Figuring out which of my two "proof" numbers to actually trust mattered more than any single line of code in this whole project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzbfo80ro2gs8tiav4trj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzbfo80ro2gs8tiav4trj.png" alt=" " width="800" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually think this proves
&lt;/h2&gt;

&lt;p&gt;Anyone can make an alert trigger a restart and record a demo that looks impressive. What I wanted to show is that the agent's diagnosis is actually grounded in the trace data instead of getting lucky on which number happened to be the biggest. Hitting that self time bug and having to fix it is honestly the part of this project I'm most glad happened, because it's the difference between an agent that looks right and one that's actually reasoning correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;p&gt;FastAPI, httpx, OpenTelemetry Python SDK, SigNoz self hosted through Foundry, Docker Compose, the SigNoz MCP server, Gemini 2.5 Flash on the free tier, and Docker for the remediation step.&lt;/p&gt;

&lt;p&gt;AI tool disclosure: GitHub Copilot for in editor code, Claude for architecture and debugging help while building this. Gemini 2.5 Flash is the model used inside the actual project for root cause reasoning, not for writing the code, it's a real part of the running system.&lt;/p&gt;

&lt;p&gt;Repo, with casting.yaml and casting.yaml.lock included: &lt;a href="https://github.com/shiv-codez/cascade-detective" rel="noopener noreferrer"&gt;https://github.com/shiv-codez/cascade-detective&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(I used Claude to help with debugging guidance, structuring this post, and editing for clarity, as disclosed per the hackathon rules. All setup, exploration, and technical decisions described here were done by me.)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opentelemetry</category>
      <category>signoz</category>
      <category>observability</category>
      <category>ai</category>
    </item>
    <item>
      <title>What Broke When I Self-Hosted SigNoz on Windows</title>
      <dc:creator>Shivam Singh</dc:creator>
      <pubDate>Sun, 19 Jul 2026 17:59:18 +0000</pubDate>
      <link>https://dev.to/shivcodez/what-broke-when-i-self-hosted-signoz-on-windows-4noj</link>
      <guid>https://dev.to/shivcodez/what-broke-when-i-self-hosted-signoz-on-windows-4noj</guid>
      <description>&lt;p&gt;I just finished my first year of CS. I know basic Python and C, and right now I'm doing DSA in Java. Before this weekend I had never touched Docker, WSL, or anything related to observability. When I saw the pre-event blog challenge for the "Agents of SigNoz" hackathon, I thought it would be a chill way to warm up before the real thing started. It was not chill. That's basically the whole post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Desktop was the wrong move and I almost didn't catch it
&lt;/h2&gt;

&lt;p&gt;I'm on Windows 11, so my first instinct was the obvious beginner move. Install Docker Desktop, click through it, done. Except SigNoz's own docs specifically say not to do this. There's a known bug where ClickHouse Keeper, one of SigNoz's core pieces, crashes when it runs under Docker Desktop's virtualization on Windows. Their fix is to skip Docker Desktop for actually running containers, and instead install Docker Engine natively inside WSL2.&lt;/p&gt;

&lt;p&gt;I didn't even know what WSL2 was before this. It's basically a real Linux environment that runs alongside Windows. So I had to turn on virtualization, install Ubuntu through WSL, and then run Docker's install script from inside that Ubuntu terminal instead of using the normal Windows installer. The part that actually confused me was that Docker Desktop auto connects itself to WSL by default. So even after I installed the native engine correctly, Docker Desktop was quietly sitting there ready to override it. I had to go into Docker Desktop's settings and manually turn off "WSL Integration" for my Ubuntu distro to keep the two separate.&lt;/p&gt;

&lt;p&gt;What I thought would take five minutes ended up eating close to an hour, mostly because I didn't know any of this going in. If you're on Windows and about to try this, just go straight for native Docker Engine in WSL. Don't let Docker Desktop anywhere near your containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Actually deploying SigNoz was the easy part
&lt;/h2&gt;

&lt;p&gt;Once Docker was finally behaving, deploying SigNoz itself was almost anticlimactic. SigNoz uses something called Foundry as its official installer. You write a small &lt;code&gt;casting.yaml&lt;/code&gt; file describing what you want (mine was just &lt;code&gt;flavor: compose, mode: docker&lt;/code&gt;), run &lt;code&gt;foundryctl cast -f casting.yaml&lt;/code&gt;, and it does the rest. Pulls images for ClickHouse, the SigNoz backend, the OTel collector, Postgres, and spins up around a dozen containers. It printed a clean list of everything that started and I didn't have to debug anything here.&lt;/p&gt;

&lt;p&gt;One thing I liked as a beginner: the whole setup lives in that one &lt;code&gt;casting.yaml&lt;/code&gt; file plus a &lt;code&gt;casting.yaml.lock&lt;/code&gt; it generates automatically. That's what the hackathon judges will use to reproduce my exact deployment. I don't usually think about reproducibility so it was a good habit to see in action.&lt;/p&gt;

&lt;h2&gt;
  
  
  I skipped their demo app on purpose
&lt;/h2&gt;

&lt;p&gt;SigNoz has an official demo app you can point at your instance and get realistic looking dashboards instantly. I decided not to use it. Running someone else's pre built app and screenshotting the output felt like it would teach me basically nothing. I wanted something that was actually mine to poke at. So I wrote a tiny Flask app instead. Three routes, &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;/orders&lt;/code&gt;, &lt;code&gt;/checkout&lt;/code&gt;. I added fake latency using &lt;code&gt;time.sleep()&lt;/code&gt; so requests wouldn't all look identical, and made &lt;code&gt;/checkout&lt;/code&gt; fail on purpose about 20% of the time, to simulate something like a flaky payment gateway.&lt;/p&gt;

&lt;p&gt;Getting OpenTelemetry hooked up took way less code than I expected. I ran &lt;code&gt;pip install opentelemetry-distro opentelemetry-exporter-otlp&lt;/code&gt;, then &lt;code&gt;opentelemetry-bootstrap -a install&lt;/code&gt;, which scans your installed packages and auto installs the right instrumentation for whatever you're using. Then instead of running my app normally, I ran it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;opentelemetry-instrument python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. I didn't add a single line of tracing code to my own routes. This was honestly the biggest "wait, that's all?" moment of the whole day. I expected instrumentation to mean manually wrapping functions or adding decorators everywhere. Instead the tracing just wraps around your app from the outside.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frpqs23dlttme9zzjg4py.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frpqs23dlttme9zzjg4py.png" alt=" " width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Seeing my own data show up was genuinely satisfying
&lt;/h2&gt;

&lt;p&gt;Once I hit my routes a bunch of times with curl, the SigNoz home page confirmed logs, traces, and metrics were all live. The Services panel showed real numbers pulled straight from my own traffic. P99 latency error rate, requests per second.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyv1uf3z0ut23cjli4rz4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyv1uf3z0ut23cjli4rz4.png" alt=" " width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The part I spent the most time on was the trace detail view. I filtered specifically for one of my &lt;code&gt;/checkout&lt;/code&gt; 500 errors and clicked into it. Full flame graph, a waterfall timeline, and a complete attributes panel with everything down to &lt;code&gt;http.status_code: 500&lt;/code&gt; and which client hit it. It correctly picked up &lt;code&gt;curl/8.18.0&lt;/code&gt;, which is kind of funny because that's literally just me testing it from my own terminal. Since my app only does one thing per request, the waterfall was just one flat bar. But it made obvious how this would look on a real app with multiple services. You'd see nested spans, and you could tell exactly which downstream call, a database, a third party API, actually caused the slowdown or the failure. Reading about tracing never made that click for me. Seeing an actual flame graph did.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3bmwx6ztqc2t38dxfp2c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3bmwx6ztqc2t38dxfp2c.png" alt=" " width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dashboard and alert, and one annoying gotcha
&lt;/h2&gt;

&lt;p&gt;I built a small dashboard with two panels. P99 latency grouped by route, and error count over time. The latency panel shows something real and visible. &lt;code&gt;/&lt;/code&gt; responds in under a millisecond, while &lt;code&gt;/checkout&lt;/code&gt; spikes to 300 to 400ms, which lines up exactly with the artificial delay I put in the code. The error panel isolated my one &lt;code&gt;/checkout&lt;/code&gt; failure down to the exact second it happened, which felt oddly precise for something I built in an afternoon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5ssf0eqgxtkx1ieia9jy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5ssf0eqgxtkx1ieia9jy.png" alt=" " width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setting up an alert (fire if errors go above 2 within a 5 minute window) is where I hit a small annoying wall. SigNoz won't let you save an alert rule at all unless it has a notification channel attached, even if you have zero intention of sending a notification anywhere. I ended up creating a fake webhook channel pointing at a placeholder URL just so it would let me save the rule. Small thing, but it cost me a few confused minutes, so noting it here in case someone else hits the same wall.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpe4fafc03sydcgyilaha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpe4fafc03sydcgyilaha.png" alt=" " width="799" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  I also poked at the MCP server without a full AI client hooked up
&lt;/h2&gt;

&lt;p&gt;SigNoz ships an MCP server, and it seems to be the actual headline feature of this whole hackathon. The idea is that an AI coding assistant can query your traces, dashboards, and alerts directly through natural language instead of you clicking through the UI. I enabled it through Foundry, just adding an &lt;code&gt;mcp&lt;/code&gt; block to the same casting config, confirmed it was actually alive by hitting its health check endpoint, and set up a scoped service account with an API key for it. I didn't get as far as connecting it to a live AI client this time. That's a whole separate setup I ran out of time for. But getting the server running and authenticated end to end still taught me more about how it fits into a workflow than just reading the docs page would have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things I'd tell myself from yesterday
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If you're on Windows, skip Docker Desktop entirely for this. Go straight to native Docker Engine inside WSL. Save yourself the hour.&lt;/li&gt;
&lt;li&gt;Auto instrumentation really is close to free. I expected to write tracing code and I wrote zero.&lt;/li&gt;
&lt;li&gt;Writing my own toy app instead of using SigNoz's demo cost me maybe 45 extra minutes, and it was worth every one of them. Describing your own bug just hits different than describing someone else's dashboard.&lt;/li&gt;
&lt;li&gt;I had to actually look up what "P99 latency" means properly. It's the slowest 1% of requests, not "99% of requests." That distinction actually matters when you're staring at a dashboard trying to figure out if something's wrong.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I went into this weekend not even knowing what Docker Desktop was, and came out having self hosted a full observability stack, broken it once, fixed it, and built my own dashboards on top of data from an app I wrote myself. Most of what I actually learned came from things not working the first time, not from anything I read beforehand. If you're a beginner thinking about trying this challenge, budget more time for environment setup than feels reasonable, and don't take the shortcut of using the official demo app. The friction is genuinely where the learning is.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(I used Claude to help with debugging guidance, structuring this post, and editing for clarity, as disclosed per the hackathon rules. All setup, exploration, and technical decisions described here were done by me.)&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
