<?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: Bandari Vishnu</title>
    <description>The latest articles on DEV Community by Bandari Vishnu (@bandari-vishnu).</description>
    <link>https://dev.to/bandari-vishnu</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%2F4026545%2Fd4b0323e-da7e-487d-950b-265b3c7b15b8.jpeg</url>
      <title>DEV Community: Bandari Vishnu</title>
      <link>https://dev.to/bandari-vishnu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bandari-vishnu"/>
    <language>en</language>
    <item>
      <title>I Thought My Python API Was Fast—Until SigNoz Showed Me Where the Time Went</title>
      <dc:creator>Bandari Vishnu</dc:creator>
      <pubDate>Mon, 13 Jul 2026 13:37:36 +0000</pubDate>
      <link>https://dev.to/bandari-vishnu/i-thought-my-python-api-was-fast-until-signoz-showed-me-where-the-time-went-1lfg</link>
      <guid>https://dev.to/bandari-vishnu/i-thought-my-python-api-was-fast-until-signoz-showed-me-where-the-time-went-1lfg</guid>
      <description>&lt;p&gt;When an application works on my machine, it is easy to assume everything is fine.&lt;/p&gt;

&lt;p&gt;The API returns a response. The terminal shows no obvious problem. The application is running.&lt;/p&gt;

&lt;p&gt;But that does not answer some important questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which endpoint is slow?&lt;/li&gt;
&lt;li&gt;How many requests are failing?&lt;/li&gt;
&lt;li&gt;What caused an HTTP 500 error?&lt;/li&gt;
&lt;li&gt;How long did a request actually take?&lt;/li&gt;
&lt;li&gt;Can I detect failures before manually checking the application?&lt;/li&gt;
&lt;li&gt;Can AI help explain an error and suggest a possible fix?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted to explore these questions by building a small &lt;strong&gt;AI-powered observability project&lt;/strong&gt; using &lt;strong&gt;Python, Flask, OpenTelemetry, SigNoz, and Gemini AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What started as a simple Python API became a hands-on experiment in tracing, dashboards, alerts, error analysis, and AI-assisted troubleshooting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;The project is a Python Flask application with intentionally different application behaviors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/fast&lt;/code&gt; — returns a fast response&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/slow&lt;/code&gt; — intentionally waits before responding&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/error&lt;/code&gt; — intentionally generates an HTTP 500 error&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/health&lt;/code&gt; — checks application health&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/ai-analysis&lt;/code&gt; — analyzes an error and returns a possible issue, root cause, severity, and suggested fix&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The application is instrumented with &lt;strong&gt;OpenTelemetry&lt;/strong&gt; and sends telemetry data to &lt;strong&gt;SigNoz&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I then created a custom observability dashboard to monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total Requests&lt;/li&gt;
&lt;li&gt;HTTP 500 Errors&lt;/li&gt;
&lt;li&gt;Request Latency&lt;/li&gt;
&lt;li&gt;Requests by Endpoint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also added an HTTP 500 alert and an AI-powered error analysis component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Architecture
&lt;/h2&gt;

&lt;p&gt;The overall flow of the project is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User / Test Requests
        |
        v
Python Flask Application
        |
        v
OpenTelemetry Instrumentation
        |
        v
      SigNoz
   /     |      \
Traces Dashboard Alerts

Application Error
        |
        v
AI Error Analyzer
   /           \
Gemini AI   Rule-Based Fallback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gave me two different layers of troubleshooting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SigNoz tells me what happened in the application.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The AI analyzer helps explain what the error might mean and what I can investigate next.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: Creating the Python API
&lt;/h2&gt;

&lt;p&gt;I created a simple Flask application with multiple endpoints.&lt;/p&gt;

&lt;p&gt;The fast endpoint returns immediately:&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="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/fast&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fast&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fast endpoint called&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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;fast&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;status&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;healthy&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;message&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;This response was fast!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The slow endpoint intentionally adds latency:&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="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/slow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;slow&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Slow endpoint called - simulating latency&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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;slow&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;status&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;slow&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;duration&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;2 seconds&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;message&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;This response was intentionally delayed by 2 seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error endpoint intentionally generates a failure:&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="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error endpoint called&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Intentional demo error for SigNoz observability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These endpoints gave me predictable traffic patterns that I could observe inside SigNoz.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Instrumenting the Application with OpenTelemetry
&lt;/h2&gt;

&lt;p&gt;The application was started using OpenTelemetry auto-instrumentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;OTEL_SERVICE_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;python-signoz-demo &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:4317 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;OTEL_EXPORTER_OTLP_PROTOCOL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;grpc &lt;span class="se"&gt;\&lt;/span&gt;
opentelemetry-instrument python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service name was set to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python-signoz-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the application started sending telemetry, I generated traffic using requests to the different endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:5000/fast
curl http://localhost:5000/slow
curl http://localhost:5000/error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also generated repeated requests so that the dashboard had enough data to visualize:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..10&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:5000/fast &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
  curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:5000/slow &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For HTTP 500 errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..20&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:5000/error &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
  &lt;span class="nb"&gt;sleep &lt;/span&gt;1
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the project became much more interesting.&lt;/p&gt;

&lt;p&gt;Instead of only seeing a terminal response, I could now inspect the behavior of the application through telemetry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Building the SigNoz Dashboard
&lt;/h2&gt;

&lt;p&gt;I created a custom dashboard called:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python AI Observability Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The dashboard included four main panels.&lt;/p&gt;

&lt;h3&gt;
  
  
  Total Requests
&lt;/h3&gt;

&lt;p&gt;This panel shows the total number of requests received by the application.&lt;/p&gt;

&lt;p&gt;It gives a quick overview of application traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP 500 Errors
&lt;/h3&gt;

&lt;p&gt;This panel tracks failed requests.&lt;/p&gt;

&lt;p&gt;Because the &lt;code&gt;/error&lt;/code&gt; endpoint intentionally raises a &lt;code&gt;RuntimeError&lt;/code&gt;, I could immediately see the failures appearing in the dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Request Latency
&lt;/h3&gt;

&lt;p&gt;This was one of the most useful panels.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/fast&lt;/code&gt; endpoint responds almost immediately, while the &lt;code&gt;/slow&lt;/code&gt; endpoint intentionally waits for approximately two seconds.&lt;/p&gt;

&lt;p&gt;Seeing the difference visually made the value of observability very clear.&lt;/p&gt;

&lt;p&gt;Without telemetry, I only knew that a request "felt slow."&lt;/p&gt;

&lt;p&gt;With tracing and latency data, I could see &lt;strong&gt;where the time went&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requests by Endpoint
&lt;/h3&gt;

&lt;p&gt;This panel helped compare traffic across:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/
/fast
/slow
/error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This made it easier to understand which routes were receiving traffic and which endpoints were responsible for failures or increased latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Investigating HTTP 500 Errors
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;/error&lt;/code&gt; endpoint intentionally generates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RuntimeError: Intentional demo error for SigNoz observability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of only seeing a generic response such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;500 Internal Server Error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;observability data can help provide more context around the failed request.&lt;/p&gt;

&lt;p&gt;This is one of the biggest lessons I learned from the project:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A status code tells you that something failed. Observability helps you investigate what happened around that failure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tracing makes it possible to inspect individual requests, their duration, status, attributes, and associated errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Creating an HTTP 500 Alert
&lt;/h2&gt;

&lt;p&gt;Dashboards are useful when someone is actively watching them.&lt;/p&gt;

&lt;p&gt;But real systems also need proactive detection.&lt;/p&gt;

&lt;p&gt;I created an alert for HTTP 500 errors in the Python service.&lt;/p&gt;

&lt;p&gt;The goal was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the application starts generating server errors, the observability system should detect the condition instead of waiting for someone to manually discover it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This adds another important layer to the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application Failure
        ↓
Telemetry
        ↓
SigNoz
        ↓
Alert Detection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The combination of dashboards and alerts provides both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual investigation&lt;/li&gt;
&lt;li&gt;Proactive failure detection&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 6: Adding AI-Powered Error Analysis
&lt;/h2&gt;

&lt;p&gt;After building the observability layer, I wanted to experiment with another idea:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can AI help turn a raw error message into a more understandable troubleshooting summary?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I created an &lt;code&gt;/ai-analysis&lt;/code&gt; endpoint.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-G&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s2"&gt;"error=Database connection timeout"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  http://localhost:5000/ai-analysis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The analyzer returns structured information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HIGH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Database connection establishment timed out"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"root_cause"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Potential database connection or resource issue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"suggested_fix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Inspect database utilization, connection pools, network connectivity, and long-running queries"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"analysis_source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Gemini AI"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The purpose of the AI component is not to replace observability.&lt;/p&gt;

&lt;p&gt;Instead, the idea is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Telemetry → Evidence
AI → Interpretation Assistance
Developer → Final Decision
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SigNoz provides the telemetry and evidence.&lt;/p&gt;

&lt;p&gt;The AI analyzer attempts to explain the error in a more structured format and suggest areas to investigate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Adding a Rule-Based Fallback
&lt;/h2&gt;

&lt;p&gt;While testing the Gemini integration, I encountered real API availability problems.&lt;/p&gt;

&lt;p&gt;At one point, a model was unavailable. At another point, the API returned a temporary high-demand error.&lt;/p&gt;

&lt;p&gt;Instead of allowing the entire analysis feature to fail, I added a rule-based fallback.&lt;/p&gt;

&lt;p&gt;For example, if an error contains the word &lt;code&gt;timeout&lt;/code&gt;, the fallback can return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MEDIUM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Request timeout detected"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"root_cause"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The operation took longer than expected."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"suggested_fix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Check slow dependencies, database queries, and external APIs."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"analysis_source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rule-based fallback"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This taught me another useful engineering lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An AI-powered feature should not necessarily make the entire application dependent on the availability of an external AI service.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The final design therefore supports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error
  |
  v
Try Gemini AI
  |
  +---- Success ----&amp;gt; AI Analysis
  |
  +---- Failure ----&amp;gt; Rule-Based Fallback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This made the project more resilient.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Real Debugging Problem I Faced
&lt;/h2&gt;

&lt;p&gt;One of the issues I encountered was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Address already in use
Port 5000 is in use by another program.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I checked which process was using the port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;lsof &lt;span class="nt"&gt;-i&lt;/span&gt; :5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I stopped the old process before restarting the instrumented application.&lt;/p&gt;

&lt;p&gt;This was a simple issue, but it reinforced an important point: observability projects involve more than creating dashboards. You also need to understand the application process, ports, telemetry pipeline, instrumentation, and the environment in which everything is running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another Challenge: Querying the Correct Latency Field
&lt;/h2&gt;

&lt;p&gt;While creating the request latency panel, I initially tried to query a field that was not available.&lt;/p&gt;

&lt;p&gt;The dashboard returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;field `duration` not found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After checking the available trace fields, I used the correct duration field for the telemetry data.&lt;/p&gt;

&lt;p&gt;That small debugging step was valuable because it forced me to understand the actual structure of the collected trace data instead of assuming field names.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Testing
&lt;/h2&gt;

&lt;p&gt;I tested the complete application using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:5000/health
curl http://localhost:5000/fast
curl http://localhost:5000/slow
curl http://localhost:5000/error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for dynamic AI analysis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-G&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s2"&gt;"error=Database connection timeout"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  http://localhost:5000/ai-analysis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application successfully demonstrated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Healthy requests&lt;/li&gt;
&lt;li&gt;Fast requests&lt;/li&gt;
&lt;li&gt;Slow requests&lt;/li&gt;
&lt;li&gt;HTTP 500 errors&lt;/li&gt;
&lt;li&gt;OpenTelemetry instrumentation&lt;/li&gt;
&lt;li&gt;SigNoz observability&lt;/li&gt;
&lt;li&gt;Custom dashboards&lt;/li&gt;
&lt;li&gt;Error alerting&lt;/li&gt;
&lt;li&gt;AI-assisted error analysis&lt;/li&gt;
&lt;li&gt;Rule-based fallback analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;The main project files are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python-ai-observability-signoz/
├── .gitignore
├── README.md
├── ai_analyzer.py
├── app.py
└── requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;app.py&lt;/code&gt; contains the Flask application and endpoints.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ai_analyzer.py&lt;/code&gt; contains the AI-assisted error analysis logic and fallback mechanism.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;requirements.txt&lt;/code&gt; contains the Python dependencies required to reproduce the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;This project changed how I think about application monitoring.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. "The application is running" is not enough
&lt;/h3&gt;

&lt;p&gt;A service can be running while some endpoints are slow or failing.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. HTTP 500 is only the beginning of the investigation
&lt;/h3&gt;

&lt;p&gt;Knowing that a request failed is useful, but traces and error details provide the context needed for troubleshooting.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Latency becomes easier to understand when it is visualized
&lt;/h3&gt;

&lt;p&gt;The difference between the &lt;code&gt;/fast&lt;/code&gt; and &lt;code&gt;/slow&lt;/code&gt; endpoints became immediately visible in the dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Alerts reduce dependence on manual monitoring
&lt;/h3&gt;

&lt;p&gt;Instead of continuously watching a dashboard, alerts can detect important failure conditions.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. AI can assist troubleshooting, but telemetry should remain the source of truth
&lt;/h3&gt;

&lt;p&gt;AI-generated explanations can be useful, but they should be grounded in actual application errors and observability data.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Fallbacks matter
&lt;/h3&gt;

&lt;p&gt;External AI services can be unavailable, overloaded, or changed. A fallback strategy makes the system more resilient.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Idea
&lt;/h2&gt;

&lt;p&gt;The most interesting part of this project was combining traditional observability with AI-assisted analysis.&lt;/p&gt;

&lt;p&gt;A possible future workflow could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
    ↓
OpenTelemetry
    ↓
SigNoz
    ↓
Anomaly or Error Detected
    ↓
Relevant Telemetry Collected
    ↓
AI-Assisted Analysis
    ↓
Suggested Root Cause and Next Investigation Steps
    ↓
Developer Review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is still a lot that could be improved.&lt;/p&gt;

&lt;p&gt;Future enhancements could include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically retrieving real trace context for AI analysis&lt;/li&gt;
&lt;li&gt;Sending alerts to Slack or another notification channel&lt;/li&gt;
&lt;li&gt;Correlating logs and traces&lt;/li&gt;
&lt;li&gt;Adding database telemetry&lt;/li&gt;
&lt;li&gt;Detecting unusual latency patterns&lt;/li&gt;
&lt;li&gt;Generating AI summaries from actual telemetry&lt;/li&gt;
&lt;li&gt;Adding authentication and production deployment&lt;/li&gt;
&lt;li&gt;Containerizing the complete application&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I started this project with a simple Python API.&lt;/p&gt;

&lt;p&gt;By the end, I had explored:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flask application monitoring&lt;/li&gt;
&lt;li&gt;OpenTelemetry instrumentation&lt;/li&gt;
&lt;li&gt;Distributed tracing&lt;/li&gt;
&lt;li&gt;Request latency&lt;/li&gt;
&lt;li&gt;HTTP 500 error monitoring&lt;/li&gt;
&lt;li&gt;Custom dashboards&lt;/li&gt;
&lt;li&gt;Alerting&lt;/li&gt;
&lt;li&gt;AI-assisted root cause analysis&lt;/li&gt;
&lt;li&gt;Fallback mechanisms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson for me was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You cannot improve what you cannot see.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And sometimes, an API that looks fast from the outside has a very different story inside its traces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;The complete project is available on my GitHub repository:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python AI Observability with SigNoz&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Technologies Used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Flask&lt;/li&gt;
&lt;li&gt;OpenTelemetry&lt;/li&gt;
&lt;li&gt;SigNoz&lt;/li&gt;
&lt;li&gt;Gemini AI&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;GitHub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you found this project interesting, I would love to hear your feedback and ideas for improving the AI-assisted observability workflow.&lt;br&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%2Fz41ixott4roh09cudgoc.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%2Fz41ixott4roh09cudgoc.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>signoz</category>
      <category>opentelemetry</category>
      <category>observability</category>
      <category>python</category>
    </item>
  </channel>
</rss>
