<?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: databufflabs</title>
    <description>The latest articles on DEV Community by databufflabs (@databufflabs).</description>
    <link>https://dev.to/databufflabs</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%2F3993960%2F8b10c56f-bbd4-4580-a8b1-a1e732e4be57.png</url>
      <title>DEV Community: databufflabs</title>
      <link>https://dev.to/databufflabs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/databufflabs"/>
    <language>en</language>
    <item>
      <title>A Different Way to Handle Everyday Operations: A Preview of OpenOcta</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Mon, 14 Sep 2026 11:35:07 +0000</pubDate>
      <link>https://dev.to/databufflabs/a-different-way-to-handle-everyday-operations-a-preview-of-openocta-3g4m</link>
      <guid>https://dev.to/databufflabs/a-different-way-to-handle-everyday-operations-a-preview-of-openocta-3g4m</guid>
      <description>&lt;p&gt;Let's start with four familiar operations headaches, then look at four ways OpenOcta addresses them.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Four everyday problems
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem 1/4: Investigating one issue means switching between several systems
&lt;/h3&gt;

&lt;p&gt;Finding out why a service has slowed down often starts with opening several different systems.&lt;/p&gt;

&lt;p&gt;First, you check the &lt;strong&gt;CMDB&lt;/strong&gt; to find the hosts running the service and the team responsible for it. Then you open &lt;strong&gt;Prometheus or Zabbix&lt;/strong&gt; to check metrics and host status.&lt;/p&gt;

&lt;p&gt;Next comes &lt;strong&gt;APM&lt;/strong&gt; to find the slow part of a request, &lt;strong&gt;Elasticsearch&lt;/strong&gt; to search logs from the same period, and your &lt;strong&gt;change management system&lt;/strong&gt; to check for recent releases.&lt;/p&gt;

&lt;p&gt;Each switch means finding the service again, selecting a time range, and setting filters. One system expects a service name; another needs a host IP.&lt;/p&gt;

&lt;p&gt;You still have to bring the results together yourself. When a new clue appears, you return to an earlier system and keep searching.&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%2F22qrm7ljfec18ljwt899.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%2F22qrm7ljfec18ljwt899.png" alt="Investigating one issue across inventory, monitoring, APM, logs, and change records" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Problem illustration: information about the same issue is spread across several systems.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if I could ask in one place, have it query those systems, and continue the investigation using the results?&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 2/4: Alerts arrive everywhere, and you have to identify duplicates
&lt;/h3&gt;

&lt;p&gt;Prometheus sends an alert. Zabbix reports something too. You open both pages and compare the service, host, and time to work out whether they are related. Before you finish, the same abnormal condition triggers another notification.&lt;/p&gt;

&lt;p&gt;Without a shared view, you first have to work out which notifications represent new problems and which are repeats. Once you find the alert that needs attention, there are still metrics to check, logs to search, and possible remedies to investigate.&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%2F24tv8iakkyzroj3xpri0.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%2F24tv8iakkyzroj3xpri0.png" alt="Alerts arrive from multiple systems, requiring manual comparison before investigation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Problem illustration: several systems raise alerts; someone must identify duplicates before investigating.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if I could see these alerts together, group repeated notifications, and continue straight into investigation and handling?&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 3/4: Daily, weekly, and monthly work still involves repetitive manual steps
&lt;/h3&gt;

&lt;p&gt;Even when no alert interrupts you, routine work keeps coming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Daily health checks&lt;/strong&gt; mean reviewing the status and metrics of core services one by one. If something looks wrong, you gather more information. Then you write up the results.&lt;/p&gt;

&lt;p&gt;Scripts can do part of the work, but someone often still has to decide what to run first and what to check next.&lt;/p&gt;

&lt;p&gt;What if I could describe the services and checks, have the steps run, investigate abnormalities, and receive a report?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weekly reviews of unresolved issues&lt;/strong&gt; raise another set of questions: which alerts from last week remain unresolved, and which problems have returned? With records spread across systems, you have to compare them by business service and time.&lt;/p&gt;

&lt;p&gt;What if last week's records could give me an initial list of unresolved and recurring issues, instead of making me find everything again?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monthly operational summaries&lt;/strong&gt; require collecting alert, health-check, and handling records, then calculating statistics and reviewing trends for the services you own. The report format barely changes, but next month you repeat the collection and organization with a new set of data.&lt;/p&gt;

&lt;p&gt;What if I could specify the services and period, and have that summary prepared for me?&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%2F55f5djid5uraxg591wko.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%2F55f5djid5uraxg591wko.png" alt="Daily checks, weekly reviews, and monthly summaries repeat manual work" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Problem illustration: check status each day, follow up on issues each week, and compile a summary each month.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 4/4: A fixed dashboard may not fit the work you are doing
&lt;/h3&gt;

&lt;p&gt;While on call, you want to know whether your services are healthy, which alerts need attention, and what recent checks found.&lt;/p&gt;

&lt;p&gt;When preparing a change, you care about the affected systems and their check results. During a monthly review, you need trends over a longer period. You are the same person, but the information you need changes with the job.&lt;/p&gt;

&lt;p&gt;A fixed dashboard often meets only part of that need. You filter and combine the remaining information yourself. Adding another service or changing a calculation may require another request for page development.&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%2F8fetlvoanvzezxhd364x.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%2F8fetlvoanvzezxhd364x.png" alt="On-call work, change preparation, and monthly reviews need different views" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Problem illustration: when the work changes, the view needs to change too.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if I could describe the services I own and the work I need to do, generate a suitable operations view, and keep refining it through conversation?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Four corresponding approaches
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Approach 1/4: Connect systems and investigate one question across them
&lt;/h3&gt;

&lt;p&gt;Your CMDB, Prometheus, Zabbix, APM, Elasticsearch, and your team's change management system can connect to &lt;strong&gt;OpenOcta&lt;/strong&gt; through the interfaces and tools each provides.&lt;/p&gt;

&lt;p&gt;OpenOcta supports MCP, API, and CLI integrations, allowing existing query capabilities to be used together.&lt;/p&gt;

&lt;p&gt;Once connections, access permissions, and tool instructions are configured, you can ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find out why the payment service has slowed down in the last half hour, and check whether there were any releases during that period.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Based on the question, the AI queries the CMDB for related resources, monitoring and APM for abnormal metrics and slow calls, then combines those findings with logs and recent change records to investigate possible causes.&lt;/p&gt;

&lt;p&gt;You continue asking questions in the same conversation. It calls the systems it needs and uses the returned data to continue the investigation.&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%2F0k67bms6i58l3vbjc97j.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%2F0k67bms6i58l3vbjc97j.png" alt="OpenOcta queries several systems around a single service issue" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Approach illustration: connected systems provide inventory, monitoring, tracing, logs, and change information for the same question.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This can reduce copying service names, repeatedly selecting time ranges, and moving query results between systems. The same integrations can also support workflows and operations views.&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach 2/4: Bring alerts together, group them by rules, and connect handling workflows
&lt;/h3&gt;

&lt;p&gt;Alerts from systems such as Prometheus and Zabbix appear in a shared alert dashboard, with their sources, affected objects, and status visible together.&lt;/p&gt;

&lt;p&gt;Repeated alerts of the same kind for the same object can be grouped using configured labels and time windows. Original events remain available when you need to inspect individual records.&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%2Fnbz3lda3bo3x3iiqvdyn.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%2Fnbz3lda3bo3x3iiqvdyn.png" alt="Incoming alerts are grouped by rules and connected to a handling workflow" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Approach illustration: view alerts together, group them by rules, then use an associated workflow to investigate and handle them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can then associate a handling workflow with that type of alert: query the connected monitoring, APM, and log systems, have the AI analyze the findings, and proceed through predefined handling steps.&lt;/p&gt;

&lt;p&gt;The workflow runs with the alert's context. When another alert of that type arrives, investigation can follow the existing process.&lt;/p&gt;

&lt;p&gt;Your configuration determines which steps run automatically and which require human confirmation. You can also see how far the process has progressed and what it found.&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach 3/4: Generate workflows to carry out repetitive steps
&lt;/h3&gt;

&lt;p&gt;Workflows can also handle daily checks, weekly reviews, and monthly summaries. Each has its own process, which can be generated from your requirements.&lt;/p&gt;

&lt;p&gt;For example, describe a health check:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the services I own in the CMDB, check their operating status, query related metrics and logs if anything is abnormal, and compile a health-check report.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI generates a workflow from that request. You can inspect each step, adjust the scope and handling steps, and give it a trial run.&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%2F9aka33zbrsp10b2i6ob6.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%2F9aka33zbrsp10b2i6ob6.png" alt="A request becomes a workflow with query, analysis, handling, and reporting steps" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Teaser illustration: describe the work, generate a workflow, then inspect and adjust its steps.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once the necessary systems are connected and you have confirmed the process, the workflow can use tools to query, check, analyze, and summarize.&lt;/p&gt;

&lt;p&gt;Steps that previously required someone to pass one result to the next can run in sequence. Human confirmation can remain wherever your judgment is needed.&lt;/p&gt;

&lt;p&gt;A weekly review can query alerts and handling records for a specified period and summarize unresolved issues. A monthly summary can collect data by business service, calculate statistics, and produce a report.&lt;/p&gt;

&lt;p&gt;Save the workflow, and you can run the same steps again with a different time range.&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach 4/4: Generate operations views around your work
&lt;/h3&gt;

&lt;p&gt;Now consider the fixed dashboard that does not quite fit. You can describe the view you need:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create an on-call view for the payment service, bringing together service health, priority alerts, recent changes, and the health-check workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI generates a page from that request, drawing data from connected systems. Inventory, monitoring, alerts, and change information can appear together around the business service you care about.&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%2F1by57fevuf0rmersaumr.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%2F1by57fevuf0rmersaumr.png" alt="An operations view combines health trends, priority items, and related work" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Teaser illustration: generate an operations view for the work you do each day.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The generated view supports further queries and changes to the time range. You can ask for another trend or replace information you rarely use.&lt;/p&gt;

&lt;p&gt;For monthly reviews, you can generate a separate view focused on trends and statistics. Choose the view that suits the work you are doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. OpenOcta launch preview
&lt;/h2&gt;

&lt;p&gt;This is a first look at &lt;strong&gt;OpenOcta&lt;/strong&gt;, ahead of its launch. These are a few glimpses; fuller demonstrations of the actual workflows will follow.&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%2Fcxd656czbfyvfm5bsnif.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%2Fcxd656czbfyvfm5bsnif.png" alt="OpenOcta launch invitation with September 15, 19:00 and the event QR code" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenOcta launches on September 15, 2026, at 7:00 p.m. China Standard Time (UTC+8).&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ai</category>
      <category>automation</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Where Does an Ops Topology Actually Come From?</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Tue, 08 Sep 2026 02:00:43 +0000</pubDate>
      <link>https://dev.to/databufflabs/where-does-an-ops-topology-actually-come-from-52hl</link>
      <guid>https://dev.to/databufflabs/where-does-an-ops-topology-actually-come-from-52hl</guid>
      <description>&lt;p&gt;A checkout hits which services? OpenTelemetry records the app handling a request, calling downstream, and talking to the database. One full request is a Trace. Each hop inside it is a Span.&lt;/p&gt;

&lt;p&gt;Look at three checkouts. The entry is &lt;strong&gt;A (service-a)&lt;/strong&gt;. It sometimes calls &lt;strong&gt;B (service-b)&lt;/strong&gt; and also queries MySQL directly. B uses the same database. The numbers below are simplified. All three requests succeed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trace ① · A entry 100 ms
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;B · 80 ms&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;MySQL · 40 ms&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL · 10 ms&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Trace ② · A entry 200 ms
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;B · 120 ms&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;MySQL · 60 ms&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL · 20 ms&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Trace ③ · A entry 100 ms
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;MySQL · 10 ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This one never called B. Indentation is who called whom: ① and ② each hit the database twice; ③ once. Internal work is omitted. IDs and numbers are teaching examples.&lt;/p&gt;

&lt;p&gt;These calls wait for the downstream reply. If B spent 80 ms, that already includes 40 ms waiting on MySQL — do not add them to 120 ms. A's entry time is the whole wait from request in to response out.&lt;/p&gt;

&lt;p&gt;One trace shows one request. When traffic grows, you also want: &lt;strong&gt;who depends on whom across the system? From A, where does the time go?&lt;/strong&gt; Reading traces one by one gets painful.&lt;/p&gt;

&lt;p&gt;DataBuff is an &lt;strong&gt;AI-native backend&lt;/strong&gt; for OpenTelemetry: it receives what apps report, serves query pages, and lets AI experts query the same data through tools. The project is open source: &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;. Follow these three traces to see how it builds a global topology and a service flow.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you get&lt;/th&gt;
&lt;th&gt;What it keeps&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Global topology&lt;/td&gt;
&lt;td&gt;Merge calls into one graph: who depends on whom.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service flow&lt;/td&gt;
&lt;td&gt;Keep the entry and the paths: who A went through, and each path's share of time.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Architecture first: who processes, who stores, who queries.
&lt;/h2&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%2Fwqdjsb662kr7zagu6w6q.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%2Fwqdjsb662kr7zagu6w6q.png" alt="diagram-architecture" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Collector is an optional forwarder. OTLP is the OpenTelemetry export protocol. Both graphs are computed on the backend by fixed rules; the UI draws them. AI experts can query the same data.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ingest first groups fragments of the same request.
&lt;/h2&gt;

&lt;p&gt;Records from A and B may arrive in batches. Every request has a &lt;code&gt;trace_id&lt;/code&gt;. Ingest groups fragments by that id. Each fragment also has its own id and a parent id &lt;code&gt;parent_span_id&lt;/code&gt;: this hop started during that parent's work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trace ①: same trace_id, joined by parent
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;s1 · A receives the checkout · 100 ms&lt;/strong&gt; (no parent: this is the entry)

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;s2 · A calls B · 80 ms&lt;/strong&gt; (parent = s1)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;s3 · B receives the request · 80 ms&lt;/strong&gt; (parent = s2 → s2 belongs to A → B's upstream is A)

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;s4 · B queries MySQL · 40 ms&lt;/strong&gt; (parent = s3)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;s5 · A queries MySQL directly · 10 ms&lt;/strong&gt; (parent = s1 → this query belongs to A)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;s1–s5 are short labels. s2 is A waiting on B; s3 is B handling the request. In the example both are 80 ms. Real ends can differ; it is still one A→B call.&lt;/p&gt;

&lt;p&gt;When Ingest sees s3's parent is s2, and s2 belongs to A, it fills B's upstream as A and A's downstream as B. s1 and s2 both belong to A, so it does not draw A→A. Ingest can wait for late fragments, but it must continue on timeout — it cannot always wait until every piece arrives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then it turns database spans into database nodes.
&lt;/h2&gt;

&lt;p&gt;s4 is recorded by the probe on B. It carries the database type and name. Ingest can name the component and remember B's edge to it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;B's DB span s4: &lt;code&gt;db.system = mysql&lt;/code&gt;, &lt;code&gt;db.name = demo_apm&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Component node: &lt;code&gt;[mysql]demo_apm&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Edge: B → MySQL, 40 ms, success&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;s5 fills A → the same MySQL. Later we just say MySQL. Whether the fields are enough depends on what was collected.&lt;/p&gt;

&lt;p&gt;Redis and message queues use their own component fields. You do not need an agent on every middleware to draw the edge. That is not the same as having all of their internal metrics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Only then are many calls rolled into stats.
&lt;/h2&gt;

&lt;p&gt;Count the right records. How many times A was entered: A's entry spans. How many times B queried the DB: B's DB spans. &lt;strong&gt;Trace ① lists five spans; A still received the checkout once.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pick records by use: A's request count from s1; B's DB count from s4&lt;/li&gt;
&lt;li&gt;Extract numbers: call count +1, error count +1 on errors, duration = end − start&lt;/li&gt;
&lt;li&gt;Roll up by minute: add like with like, keep counts and total duration&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is the second kind of aggregation: statistics over many calls. Grouping by trace id was the first: putting one request's fragments together.&lt;/p&gt;

&lt;p&gt;Assume the three requests finished in the same minute, and A's call to B matches B's receive time. The rollup looks like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;After the three example requests&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;th&gt;Total duration&lt;/th&gt;
&lt;th&gt;Average&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A entry&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;400 ms&lt;/td&gt;
&lt;td&gt;~133 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A → B&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;200 ms&lt;/td&gt;
&lt;td&gt;100 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B → MySQL&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;100 ms&lt;/td&gt;
&lt;td&gt;50 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A → MySQL directly&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;40 ms&lt;/td&gt;
&lt;td&gt;~13 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Average duration is &lt;strong&gt;total duration ÷ call count&lt;/strong&gt;. Error rate is &lt;strong&gt;errors ÷ call count&lt;/strong&gt;. In the example every error rate is 0%. Across several minutes, add counts and durations first — do not average the averages.&lt;/p&gt;

&lt;p&gt;Service flow also keeps the entry and the path. For A→B→DB the parent path is A→B; for A→DB the parent is A. Store those two DB paths separately so the tree knows where each hangs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data lands in Doris; the page queries by time.
&lt;/h2&gt;

&lt;p&gt;What is stored is detail and stats, not a pre-drawn picture:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data and example tables&lt;/th&gt;
&lt;th&gt;What it stores&lt;/th&gt;
&lt;th&gt;Where it is used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Trace detail &lt;code&gt;trace_dc_span&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Spans with relations filled in&lt;/td&gt;
&lt;td&gt;Open one request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service stats &lt;code&gt;metric_service&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Request counts, duration, …&lt;/td&gt;
&lt;td&gt;Service metrics; services with traffic but no edges still show&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pair stats &lt;code&gt;metric_service_http&lt;/code&gt;, &lt;code&gt;metric_service_db&lt;/code&gt;, …&lt;/td&gt;
&lt;td&gt;Minute stats for A→B, A→DB, B→DB&lt;/td&gt;
&lt;td&gt;Topology edges and numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entry-path stats &lt;code&gt;metric_service_flow&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Entry, parent/child path, counts and duration&lt;/td&gt;
&lt;td&gt;Build the service-flow tree&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;The UI sends a time range; service flow also picks an entry&lt;/li&gt;
&lt;li&gt;Web queries Doris: merge stats in the window, assemble nodes and edges&lt;/li&gt;
&lt;li&gt;The UI lays out nodes, draws lines, shows numbers and status&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each graph queries its own stats. Opening the page does not scan raw spans.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same data, why two graphs?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Global topology: who depends on whom
&lt;/h3&gt;

&lt;p&gt;The backend merges call stats for the selected window. One identity is one node. Arrows go from caller to callee. A node is a service or component, not a machine.&lt;/p&gt;

&lt;p&gt;When both A and B counted A→B, the current implementation prefers A's side so the two copies are not added. Edges carry count, error rate, and average duration. Node alerts are queried and joined separately.&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%2F434c2c8w8eevvp40f7ns.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%2F434c2c8w8eevvp40f7ns.png" alt="diagram-global-topology" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Three example requests become three edges. Both callers connect to one MySQL node. This graph summarizes many requests; it does not keep each request's full path.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  DataBuff global topology (demo data)
&lt;/h3&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%2F46ppclftjibnhmg9kkov.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%2F46ppclftjibnhmg9kkov.png" alt="01-global-topology" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;service-a and service-b both connect to &lt;code&gt;[mysql]demo_apm&lt;/code&gt;. Red comes from node alerts in that window — not automatically the root cause.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Service flow: which paths from the entry
&lt;/h3&gt;

&lt;p&gt;The backend loads path stats with A as entry: A→B hangs under A, A→B→DB hangs under B, A→DB hangs under A. Repeat calls on the same path merge. The two DB paths stay separate.&lt;/p&gt;

&lt;p&gt;After the tree is built, each path node's total duration divided by the entry's total duration is &lt;strong&gt;response contribution&lt;/strong&gt;. The UI uses that ratio to order branches. It is the time mix of many requests in the window, not the order of one checkout.&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%2F5ojrcl80j70fvzkq36i9.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%2F5ojrcl80j70fvzkq36i9.png" alt="diagram-service-flow" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All numbers come from the three examples. MySQL appears on two paths. Vertical position is not execution order.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Response contribution = that path node's total duration ÷ entry total duration&lt;/p&gt;

&lt;p&gt;B: 200 ÷ 400 = 50% | MySQL under B: 100 ÷ 400 = 25%&lt;/p&gt;

&lt;p&gt;A's direct DB: 40 ÷ 400 = 10%&lt;/p&gt;

&lt;p&gt;MySQL twice means two access paths, not two databases. 25% is vs entry A, not “25% of B”. B's 50% already includes waiting on that query; &lt;strong&gt;do not add 50% and 25%&lt;/strong&gt;. Parallel calls can overlap in time.&lt;/p&gt;

&lt;p&gt;The shares also need not add to 100%. The entry still spends time on compute and other waits. This graph does not split the whole response into non-overlapping slices.&lt;/p&gt;

&lt;h3&gt;
  
  
  DataBuff service flow (demo data)
&lt;/h3&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%2F4ru07tvd9q6qs764dgjb.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%2F4ru07tvd9q6qs764dgjb.png" alt="02-service-flow" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The live page also splits the two DB paths. The screenshot is another batch (449 calls, 58% / 31% / 8%) for the UI only — not used in the example math.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Open-source APM products draw these relations differently. SkyWalking and SigNoz have dependency maps. Jaeger's deep dependency graph can show paths through a chosen service from search results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DataBuff is more complete here:&lt;/strong&gt; the open-source build ships both a global dependency view and a minute-aggregated service flow from an entry, with response contribution. One graph shows the system; the other narrows where to look.&lt;/p&gt;

&lt;p&gt;After new calls are processed and written, refresh or change the time range and the graph is rebuilt from what was queried. Missing instrumentation, or async calls that did not propagate context, can drop an edge. Filters and display limits can too.&lt;/p&gt;

&lt;p&gt;On-call, global topology shows dependencies; service flow shows paths worth checking. High contribution or a red node is a clue: still compare latency and errors to a healthy window, then confirm the slow hop on a trace.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;DataBuff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI-native OpenTelemetry APM. Metrics, traces, logs, and AI troubleshooting on one stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://demo.databuff.ai" rel="noopener noreferrer"&gt;https://demo.databuff.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>observability</category>
      <category>opentelemetry</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>There's Now an Open-Source Fault Localization Project in Ops</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Thu, 03 Sep 2026 02:06:23 +0000</pubDate>
      <link>https://dev.to/databufflabs/theres-now-an-open-source-fault-localization-project-in-ops-20c1</link>
      <guid>https://dev.to/databufflabs/theres-now-an-open-source-fault-localization-project-in-ops-20c1</guid>
      <description>&lt;p&gt;Ops rarely lacks metrics, topology, traces, or logs. What it lacks is lining those four up when something breaks.&lt;/p&gt;

&lt;p&gt;Take an entry service that returns 200 with a 0% error rate. It looks fine, so the investigation often stops on that page. The real problem is downstream — SQL already threw — and this page never shows it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Classic monitoring · four pages, each does one job, a human joins them
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Metric&lt;/strong&gt; — who is slow, who is erroring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Topology&lt;/strong&gt; — which upstream/downstream node went red&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trace&lt;/strong&gt; — which hop ate the time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log&lt;/strong&gt; — search the original line by call ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You line up the time window yourself, copy the call ID yourself, search again on the next page — the four pages only talk through you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open-source DataBuff · one chat runs the same chain
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Metrics pick the target&lt;/li&gt;
&lt;li&gt;Topology looks downstream&lt;/li&gt;
&lt;li&gt;Trace splits that hop&lt;/li&gt;
&lt;li&gt;Logs match the original line&lt;/li&gt;
&lt;li&gt;→ inspection report&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s called DataBuff. Repo: &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;. Below is that chat on the official demo, watching it line the four pages up.&lt;/p&gt;

&lt;h2&gt;
  
  
  1 · Find the service with the highest response time
&lt;/h2&gt;

&lt;p&gt;In the official demo, service-a / service-b are hitting &lt;code&gt;GET /demo/checkout&lt;/code&gt;. The chat starts with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;找出最近 1 小时平均响应时间最高的服务，对它进行故障定位
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the service with the highest average response time in the last hour, then localize the fault on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 · The AI brain hands the job to metric query
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It splits the sentence into two steps: find the slowest service in the last hour, then localize the fault on it.&lt;/li&gt;
&lt;li&gt;The first cut goes to metric query, time window pinned to the last hour, pull the service list first.&lt;/li&gt;
&lt;/ul&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%2Fcmct9qtl3ry07h9s69of.jpg" 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%2Fcmct9qtl3ry07h9s69of.jpg" alt="01-plan-time-services" width="799" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 1 · The brain sets the time window, then metric query pulls the service list.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 · Metric query names service-a
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;On the table, service-a averages 240ms, the highest in this batch.&lt;/li&gt;
&lt;li&gt;service-b is 70ms; service-a is about 3.4× that. Fault localization stays on service-a.&lt;/li&gt;
&lt;li&gt;Both Java entries show 0% error rate — looks fine at a glance. MySQL error rate is 33.33%, which is high, but it isn’t the slowest, so it isn’t the main target yet.&lt;/li&gt;
&lt;/ul&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%2Fdqpuwj7dzfzlcfgxu6jp.jpg" 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%2Fdqpuwj7dzfzlcfgxu6jp.jpg" alt="02-metric-who-slowest" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 2 · Metric query names service-a; the rest of the localization stays on it.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2 · Inspect its own health, then downstream and the call chain
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 3 · Hand fault localization to the inspection expert
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;service-a itself: entry error rate 0%, no ERROR, no failed traces, 240ms is a flat line, not a sudden blast.&lt;/li&gt;
&lt;li&gt;The red dot is downstream &lt;code&gt;[mysql]demo_apm&lt;/code&gt;, with 60 “entry error rate too high” alerts.&lt;/li&gt;
&lt;li&gt;Itself is green, the database keeps ringing, the two pages don’t match.&lt;/li&gt;
&lt;/ul&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%2Fc6tnxj6ce5pajiq3hrrd.jpg" 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%2Fc6tnxj6ce5pajiq3hrrd.jpg" alt="03-inspect-topology" width="799" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 3 · Itself is still green; downstream MySQL keeps alerting.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 · Read traces, then check the alerts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sampled traces are all &lt;code&gt;GET /demo/checkout&lt;/code&gt;, status 200, duration pinned at 240ms. The entry hop shows nothing wrong.&lt;/li&gt;
&lt;li&gt;The database still has 60 alerts, but dependency stats write MySQL errors as 0.&lt;/li&gt;
&lt;li&gt;The two sentences don’t match. The only move left is to split one chain.&lt;/li&gt;
&lt;/ul&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%2F031v60d9u3806ryyqxv0.jpg" 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%2F031v60d9u3806ryyqxv0.jpg" alt="04-trace-samples-alarm" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 4 · checkout is all 200; the database keeps ringing; the two sentences don’t match.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3 · Split one call, match the logs, write the report
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 5 · Split one trace, pull the same log line
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The hop that blew up is &lt;code&gt;SELECT demo_inventory&lt;/code&gt;, throwing &lt;code&gt;InsufficientStockException&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The entry still returns 200. The same log line matches SKU &lt;code&gt;DEMO-10001&lt;/code&gt;, inventory left at 2.&lt;/li&gt;
&lt;li&gt;service-a recorded that service-b returned 200, so the entry stayed green and never went red.&lt;/li&gt;
&lt;/ul&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%2Fv5xj7kw0ps05tx2q6dlx.jpg" 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%2Fv5xj7kw0ps05tx2q6dlx.jpg" alt="05-sql-exception-logs" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 5 · Insufficient stock swallowed into a 200; the entry looks fine.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6 · Write the inspection report
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The chat ends with an HTML inspection report, not just “done.”&lt;/li&gt;
&lt;li&gt;Verdict, trends, call tree, advice — the next section reads the report’s own chapters. This step doesn’t copy them first.&lt;/li&gt;
&lt;/ul&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%2Fposx2lcg68eekjwjf3xj.jpg" 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%2Fposx2lcg68eekjwjf3xj.jpg" alt="06-report-call-tree" width="799" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 6 · The report is out; the next section reads it by its own chapters.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4 · Open the report: verdict, trends, call tree
&lt;/h2&gt;

&lt;p&gt;Start with the verdict. The report says “watch,” meaning this chain is worth looking at, not that the service is already down. 240ms is written as serial inherent latency, not a sudden spike.&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%2Foils2ykdvgecvgfz4axd.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%2Foils2ykdvgecvgfz4axd.png" alt="15-report" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You can preview this HTML report at the bottom of the chat.&lt;/em&gt;&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%2F6lgag7eyjoihljdo97c5.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%2F6lgag7eyjoihljdo97c5.png" alt="16-report-verdict" width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Verdict “watch.” 240ms, 75%, 60 alerts, and the SKU sit on one screen.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then the trends. All three charts are flat lines. Response time is pinned at 240ms; request rate is about 7–8/min, also flat; MySQL error rate 33.33%, also flat. This is not a one-off jitter — it was slow for the whole hour, and the alerts kept firing.&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%2Fpf2f9deq906qkt3k37eg.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%2Fpf2f9deq906qkt3k37eg.png" alt="17-report-charts" width="799" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Left: 240ms flat. Right: request rate steady. Bottom: MySQL 33.33% flat.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then the call tree. HTTP to service-b is about 100ms, the Dubbo hop about 80ms; together they are about 75% of the 240ms. The red dot lands on &lt;code&gt;SELECT demo_inventory&lt;/code&gt;. Sum the hops and you get about 246ms, which matches the 240ms at the entry — nothing else is missing from the picture.&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%2F6g0o92tjryyoubmxf6u2.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%2F6g0o92tjryyoubmxf6u2.png" alt="18-report-trace-tree" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;240ms is a serial sum; the red dot is the inventory SQL.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then the advice. On latency, the bottleneck is two calls to service-b plus two slow SELECTs, 45ms and 30ms. On alerts, the cause is insufficient stock swallowed: SKU &lt;code&gt;DEMO-10001&lt;/code&gt;, inventory 2. The entry returned 200 and hid it.&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%2Ftt47b631mt406534h2xc.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%2Ftt47b631mt406534h2xc.png" alt="19-report-advice" width="799" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P0: look at the slow queries and inventory first. P1: consider parallel or merge. P2: don’t silently turn this into a 200.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Priority&lt;/th&gt;
&lt;th&gt;What the report wrote&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Check why two SELECTs take 45ms / 30ms; whether inventory 2 is demo data or a real stockout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Consider parallelizing or merging the two calls to service-b. This is advice; nothing was measured on how much faster it would be&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;Don’t silently turn insufficient stock into a 200&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  5 · Same job: how long a human takes vs DataBuff’s AI analysis
&lt;/h2&gt;

&lt;p&gt;The comparison is the same job: find the slowest service in the last hour, then localize the insufficient stock swallowed into a 200. Not two different incidents — one job, done twice.&lt;/p&gt;

&lt;p&gt;The “about 3 minutes” on the right is wall-clock from this chat’s question to the report, measured. The “about 40 minutes” on the left is an estimate for a practiced human chaining the five items. There was no second stopwatch on a human run.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;What a human does&lt;/th&gt;
&lt;th&gt;Practiced estimate&lt;/th&gt;
&lt;th&gt;This AI chat&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Metric&lt;/td&gt;
&lt;td&gt;Open the service list, sort by latency, pick the slowest&lt;/td&gt;
&lt;td&gt;~5 min&lt;/td&gt;
&lt;td&gt;~30 sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Topology&lt;/td&gt;
&lt;td&gt;Open the relationship map, line downstream alerts to this service&lt;/td&gt;
&lt;td&gt;~5 min&lt;/td&gt;
&lt;td&gt;~30 sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Call chain&lt;/td&gt;
&lt;td&gt;Entry is already 200; open the waterfall and find the stuck hop&lt;/td&gt;
&lt;td&gt;~10 min&lt;/td&gt;
&lt;td&gt;~1 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logs&lt;/td&gt;
&lt;td&gt;Copy the call ID, search the original line on another page&lt;/td&gt;
&lt;td&gt;~8 min&lt;/td&gt;
&lt;td&gt;~30 sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write the report&lt;/td&gt;
&lt;td&gt;Turn what the four pages lined up into a conclusion&lt;/td&gt;
&lt;td&gt;~12 min&lt;/td&gt;
&lt;td&gt;~20 sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;td&gt;Chain the five, still lining up the time window&lt;/td&gt;
&lt;td&gt;~40 min&lt;/td&gt;
&lt;td&gt;~3 min&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;About 40 minutes vs about 3 minutes — roughly 13× faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  6 · After the AI analysis, inventory, 200, and slow queries still need a human call
&lt;/h2&gt;

&lt;p&gt;This chat took about 3 minutes. The slowest service is service-a, the red dot is on the database, insufficient stock was swallowed into a 200. Metrics, topology, traces, and logs lined up. Nobody had to copy a call ID across four pages.&lt;/p&gt;

&lt;p&gt;Lined up is not closed. Whether to restock the 2 units, whether that 200 should keep swallowing this, whether those two SELECTs need a change — the report wrote advice. The call is still a human’s.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;DataBuff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI-native OpenTelemetry APM. Metrics, traces, logs, and AI troubleshooting on one stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://demo.databuff.ai" rel="noopener noreferrer"&gt;https://demo.databuff.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>observability</category>
      <category>devops</category>
      <category>opensource</category>
      <category>opentelemetry</category>
    </item>
    <item>
      <title>There's a Hidden Gem in Ops You Probably Missed</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Mon, 31 Aug 2026 02:21:48 +0000</pubDate>
      <link>https://dev.to/databufflabs/theres-a-hidden-gem-in-ops-you-probably-missed-3g5i</link>
      <guid>https://dev.to/databufflabs/theres-a-hidden-gem-in-ops-you-probably-missed-3g5i</guid>
      <description>&lt;p&gt;If you work in ops, you rarely lack a stack for monitoring, APM, logs, or alerts. When something breaks and you ask “who’s on fire,” you still stitch those stacks together yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can just ask what’s broken.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s called DataBuff, and it’s open source. Repo: &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;. Once data is in, dashboards, alerts, and questions share one stack. The UI goes down to endpoints and slow SQL.&lt;/p&gt;

&lt;p&gt;This is not a how-to for one integration. It’s a walk through what you can use today.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ingest&lt;/strong&gt;: where the data comes from, which collectors, which backend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store&lt;/strong&gt;: where it lives, how many components you keep.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;See&lt;/strong&gt;: how far the UI can drill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alert&lt;/strong&gt;: how it fires, where you write the rule.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analyze&lt;/strong&gt;: whether you can ask instead of flipping charts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operate&lt;/strong&gt;: what you do when the platform itself is stuck or dropping data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Help&lt;/strong&gt;: who answers when you don’t know how to use it or wire it up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start with how data gets in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ingest: language agents, eBPF, RUM, SkyWalking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Change language or collector, keep the same backend. Four paths into one Ingest.&lt;/p&gt;

&lt;p&gt;Language agents cover Java, Python, Node, Go, .NET, PHP, Ruby. Point the official exporter at 4317 (gRPC) or 4318 (HTTP). The Nginx module uses the same OTLP path. Don’t want a process probe? Use eBPF — Grafana’s OBI. Browser OTel traffic is accepted too. If you still run SkyWalking, the report port is 11800. You don’t have to swap old probes right away.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Language agent&lt;/strong&gt; (OpenTelemetry) Java / Python / Node / Go and more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;eBPF&lt;/strong&gt; (OpenTelemetry) OBI · no in-process probe&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RUM&lt;/strong&gt; (browser) page OTLP in&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SkyWalking&lt;/strong&gt; (legacy probes) port 11800&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All four land in &lt;strong&gt;DataBuff Ingest&lt;/strong&gt;: 4317 gRPC · 4318 HTTP · SkyWalking 11800 · traces / metrics / logs.&lt;/p&gt;

&lt;p&gt;The install “data access” page already has the official start commands per language. Point the endpoint over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Store: three containers, where others often assemble a kit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Data is in. Next question: where it lives, and how many pieces you maintain. DataBuff is Ingest to receive, Doris to store, Web to see and ask. No extra Kafka or Elasticsearch in the middle. Topology, golden metrics, alerts, and AI queries read the same store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A common Grafana LGTM kit&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collect · Alloy / Agent&lt;/li&gt;
&lt;li&gt;Metrics · Prometheus&lt;/li&gt;
&lt;li&gt;Traces · Tempo&lt;/li&gt;
&lt;li&gt;Logs · Loki&lt;/li&gt;
&lt;li&gt;Dashboards · Grafana&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;DataBuff’s three core pieces&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ingest receives&lt;/li&gt;
&lt;li&gt;Doris stores · one copy of the data&lt;/li&gt;
&lt;li&gt;Web sees / alerts / AI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ve installed and used that Grafana kit on the same machine. The kit is fine. You just switch entries to look things up, and you keep more moving parts. With a small team that’s louder: one less stack is one less late night. 8G RAM is enough to stand it up on a single box.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See: the UI goes down to endpoints and SQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open global topology. Besides apps you also get bracket nodes — &lt;code&gt;[mysql]…&lt;/code&gt;, &lt;code&gt;[kafka]…&lt;/code&gt;. Most of those middlewares never got a probe; they come from outbound spans on the caller.&lt;/p&gt;

&lt;p&gt;When the entry turns red, look downstream. The cause often isn’t the first red dot. From a service you can reach endpoints, a single trace, slow SQL. Trace detail has a flame graph. Logs line up on the same Trace ID.&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%2Fbr0xnoeake7dglh2kx9c.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%2Fbr0xnoeake7dglh2kx9c.png" alt="see-topology" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Global topology. Red means unhealthy, not decoration.&lt;/em&gt;&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%2F5bztqg2zeg3b15z47s24.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%2F5bztqg2zeg3b15z47s24.png" alt="see-api-call" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Endpoint calls, then down into a trace.&lt;/em&gt;&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%2F3cyvs3y1cvg97akyjqg7.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%2F3cyvs3y1cvg97akyjqg7.png" alt="see-trace" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One trace: call order and time.&lt;/em&gt;&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%2Fpjy170n35wim8y6l1hgd.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%2Fpjy170n35wim8y6l1hgd.png" alt="see-slow-sql" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Slow SQL on the database page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alerts: rules on the numbers you’re already looking at&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You don’t bolt on another monitoring product. Golden metrics are already in the store. In the alert center you set a threshold or a spike. Rules look at recent minutes; over the line becomes an event, back to normal is recovery. Events hang on a service or middleware; you can jump back into APM. Related rules also show on the service page. No config-file hunt.&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%2Ful4atagryekect0cypht.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%2Ful4atagryekect0cypht.png" alt="alarm-list" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Rules live in the product. A lot of SkyWalking setups still edit OAP config files.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analyze: ask, inspect, capacity calls&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you can’t flip another chart and only want to ask “who’s on fire,” open the chat. It queries the same data above. Ask which services showed up in the last hour, who talks to whom, how error rates moved — it looks it up and answers.&lt;/p&gt;

&lt;p&gt;Ask it to inspect a service and it walks a checklist: entry, OOM / timeout in logs, alerts, downstream, whether instances are still there, and it can produce a report with evidence. Not the model guessing. Behind the chat it hands work to ask and inspect experts that query the store.&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%2F10f8lgr43i5k31j98ytl.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%2F10f8lgr43i5k31j98ytl.png" alt="analyze-ask" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ask: services, topology, trends.&lt;/em&gt;&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%2F8hr50me98rnwilnlqor6.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%2F8hr50me98rnwilnlqor6.png" alt="analyze-inspect" width="800" height="1026"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Inspection report, not small talk.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The home page also has capacity. Ask it to look at historical QPS and latency, whether you need to scale next — it draws a chart and gives a call.&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%2F35fw60uc8rid5z9polz5.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%2F35fw60uc8rid5z9polz5.png" alt="analyze-predict" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Capacity calls from historical QPS / latency.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You bring your own model key. Kimi, DeepSeek, OpenAI, Ollama are on the list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operate: when the platform itself is the problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If ingest is stuck, writes are dropping, or disk is full, open deploy status. Processes and SSH on business hosts are a different expert. Not this page.&lt;/p&gt;

&lt;p&gt;The overview is four cards: inbound, write failures, Doris disk, query failures. Click a chart title for a note: how the number is computed, when it counts as bad, which env var to touch. When writes start dropping, look at the queue and timeouts first. Don’t blame the app for not reporting.&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%2Frnwnn1qgu3xovai6y04d.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%2Frnwnn1qgu3xovai6y04d.png" alt="ops-overview" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Check whether the platform itself is stuck.&lt;/em&gt;&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%2F9y5cc9sm4oo3ma23dd8i.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%2F9y5cc9sm4oo3ma23dd8i.png" alt="ops-help" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Click the title. The note sits beside it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can also tell the AI: inspect the DataBuff platform, find why data is dropping. It reads the platform’s own metrics. Say “fix” and it changes &lt;code&gt;INGEST_*&lt;/code&gt;-style settings, restarts in-stack services, then checks again.&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%2Faq7643o0esnvsr4gnsgn.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%2Faq7643o0esnvsr4gnsgn.png" alt="ops-inspect" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Inspect the platform, find drops; it only changes settings when you say fix.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Help: how to use it, how to connect, how to wire MCP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you’re stuck, ask: how the product works, how to connect OpenTelemetry, how to set up MCP. The Q&amp;amp;A expert reads the install docs and access notes. It can walk OTLP endpoints, hanging a Java agent, then checking the service list.&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%2Fkmn1cuqtmciwjotbt5ff.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%2Fkmn1cuqtmciwjotbt5ff.png" alt="qa-expert" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ask “how do I connect OpenTelemetry” and it gives the endpoint and the check steps.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To hang an external MCP on an expert: AI platform → tool admin → new MCP, fill the URL and SSE / Streamable HTTP, then tick that tool on the digital expert. Chat can call it after that.&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%2F9meb5stloz3ztwi6o318.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%2F9meb5stloz3ztwi6o318.png" alt="qa-mcp-create" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;New MCP: URL + transport.&lt;/em&gt;&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%2F3yyuapo8kjs0invg84fd.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%2F3yyuapo8kjs0invg84fd.png" alt="qa-mcp-bind" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The expert only calls it after you tick it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The other way works too: an external agent like Cursor talks to DataBuff over POST /mcp. Point it at the URL and ask.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Put them on one table&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Grafana’s kit, SkyWalking, and DataBuff. Differences show up when they sit side by side.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Grafana kit&lt;/th&gt;
&lt;th&gt;SkyWalking&lt;/th&gt;
&lt;th&gt;DataBuff&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Components you keep&lt;/td&gt;
&lt;td&gt;Collect + Prom + Tempo + Loki + Grafana&lt;/td&gt;
&lt;td&gt;OAP + store + UI&lt;/td&gt;
&lt;td&gt;Ingest + Doris + Web&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Single-box standup&lt;/td&gt;
&lt;td&gt;Five pieces stacked, heavy&lt;/td&gt;
&lt;td&gt;OAP cluster&lt;/td&gt;
&lt;td&gt;Runs on 8G RAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Looking up data&lt;/td&gt;
&lt;td&gt;Metrics, traces, logs on different entries&lt;/td&gt;
&lt;td&gt;OAP queries&lt;/td&gt;
&lt;td&gt;One UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alert rules&lt;/td&gt;
&lt;td&gt;Hand-written PromQL&lt;/td&gt;
&lt;td&gt;Edit OAP config files&lt;/td&gt;
&lt;td&gt;Point at this data in the product&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI troubleshooting&lt;/td&gt;
&lt;td&gt;Another plugin&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Ask, inspect, capacity, same data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;When the platform itself breaks&lt;/td&gt;
&lt;td&gt;Wire your own monitoring&lt;/td&gt;
&lt;td&gt;Figure it out&lt;/td&gt;
&lt;td&gt;Self-monitor + notes; it only “fixes” when you say so&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On a small team, fewer stacks and fewer entry switches is something you feel.&lt;/p&gt;

&lt;p&gt;Don’t turn everything on at once. Hang an agent on one non-core service, see it on topology, add one alert, then ask “how has this service been lately.” One command brings the stack up.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;DataBuff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI-native OpenTelemetry APM. Metrics, traces, logs, and AI troubleshooting on one stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://demo.databuff.ai" rel="noopener noreferrer"&gt;https://demo.databuff.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>observability</category>
      <category>devops</category>
      <category>opensource</category>
      <category>opentelemetry</category>
    </item>
    <item>
      <title>LangGraph: Orchestrate a Swarm of AI Agents with One Graph</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Mon, 24 Aug 2026 02:18:12 +0000</pubDate>
      <link>https://dev.to/databufflabs/langgraph-orchestrate-a-swarm-of-ai-agents-with-one-graph-4b1f</link>
      <guid>https://dev.to/databufflabs/langgraph-orchestrate-a-swarm-of-ai-agents-with-one-graph-4b1f</guid>
      <description>&lt;p&gt;A single AI assistant is already standard in many teams: ask a question, get an answer, like chatting with a seasoned hand. But the moment you want several AIs to work together — &lt;strong&gt;one checks metrics, one digs through logs, one draws the conclusion&lt;/strong&gt; — it falls apart: who hands off to whom? Can they run in parallel? Should it stop and ask you midway? If it crashes halfway, is everything before it wasted?&lt;/p&gt;

&lt;p&gt;LangGraph exists to answer those questions. It's LangChain's open-source multi-agent orchestration framework (MIT). But the essence first: &lt;strong&gt;it is, before anything else, a general-purpose graph execution engine&lt;/strong&gt; — nodes, edges, conditional edges, parallelism, checkpointing, waiting on a human are all generic graph capabilities, with no inherent tie to AI; it just so happens that a node can hold an AI, and once it does, you're "orchestrating multiple AI agents." The core is simply: &lt;strong&gt;you draw the graph, it runs the graph.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This article uses a single case — &lt;strong&gt;a 2 a.m. alert: "order-service error rate spiking"&lt;/strong&gt; — to explain it end to end: the graph first, then the code, then the execution model and context passing, and finally a comparison with Dify and Claude Code's dynamic workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A case: 2 a.m., order-service error rate spikes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your on-call phone buzzes. The alert says order-service error rate just hit 12%, and your AI assistant has to walk the whole investigation flow itself. This graph is the entire logic it will execute:&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%2Fn8r1oipgy6o96rdc2i1e.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%2Fn8r1oipgy6o96rdc2i1e.png" alt="langgraph-case-diagram" width="800" height="1158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fig 1 · A late-night investigation: one graph exercises nodes, edges, conditional edges, Send, interrupt, and checkpoint.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A single run goes roughly like this: the AI &lt;strong&gt;diagnoses&lt;/strong&gt; first, finds it's serious, and &lt;strong&gt;fans out 12 parallel subtasks&lt;/strong&gt; to check instances one by one; after checking, it &lt;strong&gt;summarizes&lt;/strong&gt; "these 3 are bad"; then it &lt;strong&gt;stops and asks whether to restart&lt;/strong&gt; — you approve, and only then does it &lt;strong&gt;execute the fix&lt;/strong&gt;, finally &lt;strong&gt;re-checking and reporting&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This graph uses almost every core capability LangGraph has: &lt;strong&gt;nodes&lt;/strong&gt; (each box), &lt;strong&gt;edges&lt;/strong&gt; (arrows), &lt;strong&gt;conditional edges&lt;/strong&gt; (serious?), &lt;strong&gt;Send&lt;/strong&gt; (batch checks), &lt;strong&gt;interrupt&lt;/strong&gt; (await your approval), &lt;strong&gt;checkpoint&lt;/strong&gt; (persist each step). Let's draw it in code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drawing this graph in code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Build a graph, register each box as a node, connect arrows as edges:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;diagnose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;   &lt;span class="c1"&gt;# 1 diagnose: check error rate, pull Trace, return severity
&lt;/span&gt;    &lt;span class="n"&gt;error_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;query_error_rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&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&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="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;abnormal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;error_rate&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&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;fan_out&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;    &lt;span class="c1"&gt;# 3 batch check: Send dispatches 12 subtasks at once
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hosts&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;check_host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="c1"&gt;# 4 check one instance (each Send is its own small task)
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;host&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: ok&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;ask_human&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# 5 await your approval
&lt;/span&gt;    &lt;span class="n"&gt;decision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;interrupt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3 bad instances found — auto-restart?&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="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;decision&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;decision&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;fix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;        &lt;span class="c1"&gt;# 6 execute the fix
&lt;/span&gt;    &lt;span class="nf"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hosts&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="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;     &lt;span class="c1"&gt;# 7 produce the report
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;report&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;handled&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;diagnose&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;diagnose&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c1"&gt;# register nodes
&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fan_out&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fan_out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;check_host&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ask_human&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ask_human&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fix&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;report&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;diagnose&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;             &lt;span class="c1"&gt;# start -&amp;gt; diagnose
&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;diagnose&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;# 2 conditional edge: serious? -&amp;gt; fan_out or report
&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fan_out&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fan_out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 3 Send fan-out
&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_host&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;ask_human&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;# checked -&amp;gt; await approval
&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ask_human&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;fix&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="c1"&gt;# approved -&amp;gt; fix
&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fix&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;report&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;               &lt;span class="c1"&gt;# fixed -&amp;gt; report
&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;report&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;InMemorySaver&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;   &lt;span class="c1"&gt;# compile + enable persistence
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few key points, one by one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1 · A node is just a plain function.&lt;/strong&gt; &lt;code&gt;diagnose&lt;/code&gt;, &lt;code&gt;check_host&lt;/code&gt;, &lt;code&gt;fix&lt;/code&gt; are ordinary Python functions. Whether to call an LLM is entirely up to the function body — &lt;code&gt;diagnose&lt;/code&gt; can call a model, &lt;code&gt;check_host&lt;/code&gt; can be pure computation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2 · A conditional edge picks the path.&lt;/strong&gt; &lt;code&gt;route&lt;/code&gt; returns &lt;code&gt;"fan_out"&lt;/code&gt; or &lt;code&gt;"report"&lt;/code&gt;, and the graph walks to the matching node:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fan_out&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;abnormal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;report&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3 · Send = dispatch in bulk.&lt;/strong&gt; &lt;code&gt;fan_out&lt;/code&gt; returns 12 &lt;code&gt;Send("check_host", {...})&lt;/code&gt;, executed in parallel within the same superstep, results auto-merged:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fan_out&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hosts&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;&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%2Fb2miqh1x3xcqcxdsgk9m.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%2Fb2miqh1x3xcqcxdsgk9m.png" alt="langgraph-send-fanout" width="799" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fig 2 · Send zoomed: dispatch N independent subtasks in one superstep, then merge.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 · interrupt = stop and wait for a human.&lt;/strong&gt; Call &lt;code&gt;interrupt()&lt;/code&gt; inside a node and the graph halts, surfacing the question to you; after you approve and resume with an answer, the graph resumes from its checkpoint:&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;decision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;interrupt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3 bad instances found — auto-restart?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# after you approve:
&lt;/span&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resume&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;configurable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;thread_id&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;t1&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;&lt;strong&gt;5 · checkpoint = persist every step.&lt;/strong&gt; The graph stores progress after each step (the &lt;code&gt;thread_id&lt;/code&gt; acts as a ticket id). If it crashes midway, re-invoke with the same &lt;code&gt;thread_id&lt;/code&gt; and it resumes from the breakpoint — officially called durable execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does LangGraph actually execute this graph?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Running the graph isn't a headlong dash from start to end; it moves forward &lt;strong&gt;round by round&lt;/strong&gt;. The official term is superstep, and each round does four things:&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%2F3ygrzfhng7vuohl2od7f.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%2F3ygrzfhng7vuohl2od7f.png" alt="langgraph-superstep" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fig 3 · One superstep: figure out who runs -&amp;gt; run in parallel -&amp;gt; refresh the board -&amp;gt; persist.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Nodes don't pass messages to each other. Everyone faces the same whiteboard: this round only reads what's already on the board, and writes are set aside — &lt;strong&gt;only after the whole round finishes does the board refresh&lt;/strong&gt;. The source comment is one line: what step N writes, step N+1 sees.&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%2F920xq6121ou7vypq6y6s.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%2F920xq6121ou7vypq6y6s.png" alt="langgraph-whiteboard" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fig 4 · How context passes: no talking between nodes, just read/write the same whiteboard.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Walk the Fig 1 on-call case through it, and the rhythm is:&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%2Fxdna4mlovzwr7al6hxrt.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%2Fxdna4mlovzwr7al6hxrt.png" alt="langgraph-case-supersteps" width="800" height="772"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fig 5 · The on-call case unrolled by superstep: writes land on the board next round.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Chat history works the same way: put messages on the board, and the next step sees them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compared to other options — where's the difference?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dify and Claude Code are both often called "multi-agent," but set beside LangGraph, one table each is enough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dify: visual platform vs code library.&lt;/strong&gt; Dify is a web canvas where you drag nodes; LangGraph is a graph you draw in Python code.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Dify&lt;/th&gt;
&lt;th&gt;LangGraph&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Form&lt;/td&gt;
&lt;td&gt;Web canvas, drag nodes&lt;/td&gt;
&lt;td&gt;Draw the graph in Python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Who it's for&lt;/td&gt;
&lt;td&gt;Non-developers / quick prototypes&lt;/td&gt;
&lt;td&gt;Developers / fine control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;Apache 2.0 modified (commercial conditions apply)&lt;/td&gt;
&lt;td&gt;MIT (commercial use OK)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Claude Code dynamic workflow: the AI writes a LangGraph on the spot.&lt;/strong&gt; You just say what to do; in the background it auto-decomposes the task and spins up tens to hundreds of agents in parallel.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Claude Code dynamic workflow&lt;/th&gt;
&lt;th&gt;LangGraph&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Who orchestrates&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;The AI itself&lt;/strong&gt;: reads the request, decomposes dynamically&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;You&lt;/strong&gt;: draw a fixed graph in code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orchestration artifact&lt;/td&gt;
&lt;td&gt;An agent tree in memory, gone after the run&lt;/td&gt;
&lt;td&gt;A compilable, replayable graph definition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Predictability&lt;/td&gt;
&lt;td&gt;Same input may produce different graphs&lt;/td&gt;
&lt;td&gt;Graph fixed, behavior predictable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One line to remember: &lt;strong&gt;Dify hands you a ready-made car, Claude Code has the AI write the orchestration on the spot, LangGraph hands you the engine and the blueprint&lt;/strong&gt; — the most freedom, and the most work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our open-source DataBuff — how do its agents collaborate?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our open-source DataBuff (AI-native APM, GitHub: &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;) also does multi-agent collaboration. You talk to a single entry point; an AI brain dispatches the work to experts — query, inspection, ops, Q&amp;amp;A — in parallel, then assembles their findings into a conclusion with an evidence chain:&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%2F3n2ay4rlmxwj3oypxjzd.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%2F3n2ay4rlmxwj3oypxjzd.png" alt="databuff-multi-agent" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fig 6 · You face one entry point; the complex collaboration happens behind it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The core purpose&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LangGraph's core purpose isn't "to hand you a ready-made multi-agent solution," but &lt;strong&gt;to provide a controllable runtime for agent flows that need to run long, hold state, persist, and loop in a human&lt;/strong&gt; — it turns the low-level dirty work — parallelism, checkpointing, waiting, recovery — into primitives, so you only worry about the business flow itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt; copy those 6 functions and the graph structure from the case and run them locally, and you'll understand what multi-agent orchestration is about.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;DataBuff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open-source AI-native OpenTelemetry APM — metrics, traces, logs, and AI troubleshooting in one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://demo.databuff.ai" rel="noopener noreferrer"&gt;https://demo.databuff.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>observability</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Grafana's LGTM Stack — Tempo and Loki Are Starting to Feel Dated</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Wed, 19 Aug 2026 02:45:11 +0000</pubDate>
      <link>https://dev.to/databufflabs/grafanas-lgtm-stack-tempo-and-loki-are-starting-to-feel-dated-5b94</link>
      <guid>https://dev.to/databufflabs/grafanas-lgtm-stack-tempo-and-loki-are-starting-to-feel-dated-5b94</guid>
      <description>&lt;p&gt;Same slow checkout: four hops from metrics to Tempo to Loki. DataBuff drills down from the service list, then you can ask the AI and check the platform itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DataBuff&lt;/strong&gt; is an AI-native APM. It ingests OpenTelemetry and SkyWalking, and ships seven AI capabilities. GitHub: &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same slow checkout: Grafana needs three systems. DataBuff finishes the path in one.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you check&lt;/th&gt;
&lt;th&gt;Grafana: 3 systems / 3 separate pages&lt;/th&gt;
&lt;th&gt;DataBuff: 1 system / 3 linked pages&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Metric: who is slow&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Grafana&lt;/strong&gt;: Service Map&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Service list&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trace: which hop&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Tempo&lt;/strong&gt;: trace list, waterfall&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Tracing&lt;/strong&gt;: drill down from the service page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Log: what happened then&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Loki&lt;/strong&gt;: query by traceId&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Logs&lt;/strong&gt;: open Trace and jump back&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On-call, whether those three sit on one path matters more than whether you have all three pillars.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This LGTM: Metric / Trace / Log on three lines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The scene is &lt;code&gt;service-a&lt;/code&gt; &lt;code&gt;GET /demo/checkout&lt;/code&gt; getting slow. Find who is slow in &lt;strong&gt;Metric&lt;/strong&gt;, then the request and span in &lt;strong&gt;Trace&lt;/strong&gt;, then context in &lt;strong&gt;Log&lt;/strong&gt;. In this stack the three entries are different datasources, with different filters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metric · ① Who is slow: metrics-generator → metrics store → Service Map&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tempo stores spans. To draw a service map, metrics-generator aggregates spans into time series, writes them to a &lt;strong&gt;separate metrics store&lt;/strong&gt;, then Grafana can paint the Service Map.&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%2Fvh17o4eczl1g0yfeyro0.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%2Fvh17o4eczl1g0yfeyro0.png" alt="gf-service-map" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Metric · Service Map (from metrics-generator, not Tempo itself)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trace · ② Find the request: Explore → Tempo, search the list&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Leave Service Map, switch Explore to the Tempo datasource, filter by service / operation for the slow checkout, and copy the &lt;strong&gt;traceId&lt;/strong&gt;.&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%2Frpx50l10w2aotnnydmjm.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%2Frpx50l10w2aotnnydmjm.png" alt="lgtm-step2-tempo-search" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Trace · Explore → Tempo: different query box, different syntax&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trace · ③ Waterfall: where the time went&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the trace. See which hop of service-a → service-b → service-c is slow. Still in Tempo. Logs not touched yet.&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%2Fxet2zfkj9buv28ftgduk.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%2Fxet2zfkj9buv28ftgduk.png" alt="lgtm-step3-tempo-waterfall" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Trace · Tempo waterfall: find the slow span&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log · ④ Logs: Explore → Loki, paste the traceId&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log&lt;/strong&gt; is another line: Explore → Loki, put the traceId into LogQL. If tracesToLogs is not wired, this hop is manual.&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%2Fauucdenq4xuymiqb1ub8.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%2Fauucdenq4xuymiqb1ub8.png" alt="lgtm-step4-loki-traceid" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Log · Explore → Loki: LogQL, paste the traceId yourself&lt;/em&gt;&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%2Fihlfcb4q5smac99o9yif.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%2Fihlfcb4q5smac99o9yif.png" alt="gf-datasources" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In this stack, Metric, Trace, and Log are separate datasources&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This run:&lt;/strong&gt; four hops, and logs still needed a hand-copied traceId.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DataBuff: same incident, drill down from the service list&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Same slow checkout. After OTLP lands in DataBuff, &lt;strong&gt;Metric / Trace / Log&lt;/strong&gt; are already joined. Stay in one product. You do not paste a traceId into a new query language to open logs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metric · ① App performance → service list&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The service list shows &lt;code&gt;service-a&lt;/code&gt; latency, errors, and traffic. Click the name. Metrics and traces share one store — no extra extract from spans.&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%2F9xcgbgco3ealgta3ti3o.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%2F9xcgbgco3ealgta3ti3o.png" alt="db-step1-services" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Metric · service health: latency / errors / traffic&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trace · ② Tracing: open the slow waterfall&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From the service page, open the 240ms checkout. Middleware spans sit on the same picture. No system switch.&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%2F3dvmr5ya8zwjljgyv9bc.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%2F3dvmr5ya8zwjljgyv9bc.png" alt="db-step2-trace" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Trace · waterfall + call chain&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log · ③ Logs: Trace on the row, one click back&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each log row has a &lt;strong&gt;Trace&lt;/strong&gt; button. That is the on-call step you skip: copy the id, change the query.&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%2Fmedc09qdx5jjokbx5beh.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%2Fmedc09qdx5jjokbx5beh.png" alt="db-step3-logs" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Log · logs → trace, same product&lt;/em&gt;&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%2Fmy2pearfdhddvut0gjlo.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%2Fmy2pearfdhddvut0gjlo.png" alt="db-topology" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Topology, service health, and waterfall share one dataset — no extra metrics-generator layer&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;By here the gap is no longer “can you see the data.” DataBuff still has ask-the-AI and platform health. This LGTM stack did not expose those two entries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After that path: AI and self-monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After services, traces, and logs, two more things sit on the same menu: &lt;strong&gt;ask the data in natural language&lt;/strong&gt;, and &lt;strong&gt;see the platform's own health&lt;/strong&gt;. Those were the biggest feel differences on this run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI · Q&amp;amp;A / inspect / docs — same data you just drilled&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the AI platform. You do not pick Tempo or Loki first, and you do not write TraceQL / LogQL. The page already has ask-data, inspect, product Q&amp;amp;A, and an ops expert. Sample prompts are concrete: last-hour service list, &lt;code&gt;service-b&lt;/code&gt; upstream/downstream, request and error trends.&lt;/p&gt;

&lt;p&gt;You still bring your own model. This lab used DeepSeek. The difference is the experts and tools are already in the product, so you do not assemble three datasource contexts first.&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%2F011iycn1577iechgc4fc.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%2F011iycn1577iechgc4fc.png" alt="db-ai-chat" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AI platform · ask, inspect, Q&amp;amp;A, ops expert — same menu as Metric / Trace / Log&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This Grafana 11.5 does not ship that as a chat entry. To ask the same way you add an LLM plugin, then wire Tempo, Loki, and the metrics store into the model context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-monitoring · deploy status: treat the platform as a business system&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install → Deploy status. One page: ingest TPS, write failures, Doris disk, query failures; legend split by &lt;strong&gt;trace / metric / log&lt;/strong&gt;. Inbound requests, bytes, latency, and outbound drops share one timeline.&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%2Fabkrkzpnezn4drer6azw.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%2Fabkrkzpnezn4drer6azw.png" alt="db-selfmonitor" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Deploy status · ingest overview: 32.9/s in, Doris disk 49%; trace / metric / log on one page&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At 2 a.m., “is the app slow, or is the platform stuck?”, this page knocks out a batch: are the three lines still rising, did writes fail, is Doris disk full. In this LGTM stack those checks still mean Tempo, Loki, the metrics store, and Grafana, each on its own page.&lt;/p&gt;

&lt;p&gt;LGTM: stop when you can see the data. DataBuff: after that you can still ask, and still see the platform.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you want&lt;/th&gt;
&lt;th&gt;Grafana LGTM&lt;/th&gt;
&lt;th&gt;DataBuff&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ask “who is slow, what does the topology look like”&lt;/td&gt;
&lt;td&gt;Write the query yourself; or add an LLM plugin plus data context&lt;/td&gt;
&lt;td&gt;AI chat: sample prompts are service list / topology / traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;An inspect report you can forward&lt;/td&gt;
&lt;td&gt;Stitch dashboards and alert rules&lt;/td&gt;
&lt;td&gt;Inspect: the expert reads the same metrics and writes the report&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is the platform itself stuck&lt;/td&gt;
&lt;td&gt;Open each component health page&lt;/td&gt;
&lt;td&gt;One deploy-status page: ingest + Doris&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Component bill&lt;/td&gt;
&lt;td&gt;Tempo + metrics-generator + metrics store + Loki + Grafana&lt;/td&gt;
&lt;td&gt;ingest + one engine + Web (AI and deploy status included)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;How to try: OTLP dual-write, no rip-and-replace&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The collector already speaks OTLP. Add a &lt;strong&gt;DataBuff exporter&lt;/strong&gt; in Alloy / Collector, write to Tempo in parallel for a few days, confirm the same spans line up, then drop the Tempo path if you want. The whole thing rolls back.&lt;/p&gt;

&lt;p&gt;Walk it once: service health → trace → logs → &lt;strong&gt;ask the AI for a service list or topology&lt;/strong&gt; → &lt;strong&gt;deploy status, three ingest lines&lt;/strong&gt;. LGTM can stay. Just see if this on-call path feels shorter.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;DataBuff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI-native APM. Ingests OpenTelemetry and SkyWalking. Seven AI capabilities on the same stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://demo.databuff.ai" rel="noopener noreferrer"&gt;https://demo.databuff.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>grafana</category>
      <category>observability</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>DeepSeek Harness Hit 126k Stars — What Self-Evolution Means for Software (and Observability)</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Mon, 17 Aug 2026 01:50:53 +0000</pubDate>
      <link>https://dev.to/databufflabs/deepseek-harness-hit-126k-stars-what-self-evolution-means-for-software-and-observability-506j</link>
      <guid>https://dev.to/databufflabs/deepseek-harness-hit-126k-stars-what-self-evolution-means-for-software-and-observability-506j</guid>
      <description>&lt;p&gt;A repo on GitHub has been exploding lately. DeepSeek open-sourced an agent framework called &lt;strong&gt;deepseek-harness&lt;/strong&gt; (often shortened to &lt;strong&gt;dsh&lt;/strong&gt;). It went public on August 13; when I took this screenshot, it was already at &lt;strong&gt;126k stars&lt;/strong&gt;.&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%2Fnf3agx47l95xhqw5qyg8.jpg" 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%2Fnf3agx47l95xhqw5qyg8.jpg" alt="dsh-github-stars" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;GitHub repo page, captured 2026-08-16. Top-right shows 126k stars; About lists 125.9k.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/deepseek-ai/deepseek-harness" rel="noopener noreferrer"&gt;https://github.com/deepseek-ai/deepseek-harness&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Its one-line pitch: &lt;strong&gt;Everything is a Plugin&lt;/strong&gt;. You're not stuck with whatever shipped in the box. The AI can see what it already has, and when something is missing it can add it to itself. They call that &lt;strong&gt;self-evolution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With stars climbing that fast, I wanted to see what it actually does. So I opened the web UI and typed one request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I asked it to add a sidebar item&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Roughly: build a plugin, inject it into yourself. Change the left menu — add a &lt;strong&gt;Workflow&lt;/strong&gt; item above Workspace. Click it and show a complex flow chart; click a node and open a drawer on the right.&lt;/p&gt;

&lt;p&gt;It actually did it. Bottom-left showed Cordis Plugin: 1 running. The three screenshots below are from the live page.&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%2Fuz27m8ib0c23x7wjf2s8.jpg" 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%2Fuz27m8ib0c23x7wjf2s8.jpg" alt="shot-1-ask-inject-plugin" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Red box is the original prompt. It inspected its own sidebar first — didn't jump straight to editing files.&lt;/em&gt;&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%2Fw1hnp96w8cvi0lgq78co.jpg" 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%2Fw1hnp96w8cvi0lgq78co.jpg" alt="shot-2-workflow-canvas" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The left **Workflow&lt;/em&gt;* item is live. This ticket canvas wasn't built-in — the plugin it just wrote drew it.*&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%2Fic6bpa80rwbjkyx6k8qr.jpg" 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%2Fic6bpa80rwbjkyx6k8qr.jpg" alt="shot-3-node-drawer" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Clicking the red **External API Query&lt;/em&gt;* node: timeout and retry 3/5 in the drawer.*&lt;/p&gt;

&lt;p&gt;That extra &lt;strong&gt;Workflow&lt;/strong&gt; entry wasn't in a release. It wrote a plugin on the spot and mounted it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That made me think about on-call pages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The troubleshooting pages you open on shift are usually fixed at ship time. How topology switches, which metrics sit where, what the drawer shows first — often one team's playbook baked into the UI. Banks want ledger latency; e-commerce wants checkout funnels; one layout rarely fits both.&lt;/p&gt;

&lt;p&gt;Changing that in traditional software is hard: tweak a page, wait for the next release. Low-code is better — drag and drop — but you're still picking from the vendor's blocks; step outside and you're stuck.&lt;/p&gt;

&lt;p&gt;dsh is different. You say what you need; it adds a piece to itself right then. The block is fabricated on site, not chosen from a catalog.&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%2F62xxg4ed95id9ls01cgf.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%2F62xxg4ed95id9ls01cgf.png" alt="dia-1-compare" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fig 1 · Traditional software, low-code, and dsh in one glance&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three capabilities — we've shipped two&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We've been thinking about this for a while. Software that takes care of itself, in my view, comes down to three things: &lt;strong&gt;self-ops&lt;/strong&gt;, &lt;strong&gt;self-Q&amp;amp;A&lt;/strong&gt;, and &lt;strong&gt;self-evolution&lt;/strong&gt;. DataBuff already has the first two in product.&lt;/p&gt;

&lt;p&gt;Project on GitHub: &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-ops isn't just flashing a red chart.&lt;/strong&gt; In our demo, logs were dropping — thousands to fifteen thousand per minute. A human said two things: let it investigate, then allow it on the box. It checked its own self-monitoring, found the write queue capped at 16 batches, bumped it to 32, restarted ingest. After that, write drops went to zero.&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%2Ftyxly1fx0z9j1pb3bgzq.jpg" 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%2Ftyxly1fx0z9j1pb3bgzq.jpg" alt="db-selfops-ssh" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Self-ops · SSH to change params and restart ingest; write drops back to zero. It fixed itself.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-Q&amp;amp;A: installed but don't know where to click?&lt;/strong&gt; You used to hunt external docs. In DataBuff, switch to product support and ask: how do I wire OpenTelemetry, where do I set alert thresholds? It answers with menu paths and fields from in-product docs.&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%2Fpy0kf4xf7l5eo9yphohh.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%2Fpy0kf4xf7l5eo9yphohh.png" alt="db-selfqa-howto" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Self-Q&amp;amp;A · Ask how to onboard OTel and configure alerts — get paths, not a link dump.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Both are visible the moment you open the product. Self-evolution we haven't built yet. dsh just demonstrated the third.&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%2F4n6romyu0x7h6erjqe6l.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%2F4n6romyu0x7h6erjqe6l.png" alt="dia-2-three" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fig 2 · Three capabilities — DataBuff has the first two&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-evolution in observability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Observability isn't a chat window. Collection, storage, query — touch the wrong layer and your data is dirty. dsh can rewrite sidebars and canvases because almost everything lives in plugins. Observability can't copy that wholesale. The ingest/store/query pipeline must not be edited live.&lt;/p&gt;

&lt;p&gt;What &lt;em&gt;can&lt;/em&gt; grow on demand is the human-facing layer. "Show me UnionPay transactions first" — add a troubleshooting panel or drawer on the spot. The pipeline underneath stays the same.&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%2Fwwmwociqfq6ffx7fnryg.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%2Fwwmwociqfq6ffx7fnryg.png" alt="dia-3-obs-layers" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fig 3 · Observability: lock the base, extend the pages&lt;/em&gt;&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%2Fvf146qylqlfkghm2yza3.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%2Fvf146qylqlfkghm2yza3.png" alt="dia-4-house" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fig 4 · dsh can change the whole building; observability only the room users see&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Same telemetry as before. Pages can be tailored per customer on the spot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beyond the hype — still those three&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most of dsh's star rush is probably about "AI adding features to itself."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Self-ops&lt;/strong&gt; — when it breaks, it fixes itself. Not just a red dashboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-Q&amp;amp;A&lt;/strong&gt; — don't know how to use it? Ask; get menu paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-evolution&lt;/strong&gt; — not enough? Add a piece for your request on the spot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We've shipped the first two in DataBuff. The third — for observability — we're not there yet.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;DataBuff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open-source AI-native OpenTelemetry APM — metrics, traces, logs and AI troubleshooting in one platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://demo.databuff.ai" rel="noopener noreferrer"&gt;https://demo.databuff.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>observability</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Troubleshooting Stuck at Nginx? Instrument It with OpenTelemetry Too</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Wed, 12 Aug 2026 01:42:13 +0000</pubDate>
      <link>https://dev.to/databufflabs/troubleshooting-stuck-at-nginx-instrument-it-with-opentelemetry-too-164c</link>
      <guid>https://dev.to/databufflabs/troubleshooting-stuck-at-nginx-instrument-it-with-opentelemetry-too-164c</guid>
      <description>&lt;p&gt;The page is slow, APIs time out randomly, and you've already checked Java logs and slow SQL — still nothing. The gap is often the Nginx in front: it proxy-passes the request, but classic access logs won't tell you whether the hop succeeded, how long it took, or where it stalled.&lt;/p&gt;

&lt;p&gt;OpenTelemetry turns that into "load a module, write a few lines of config." This post walks a Demo we actually ran: instrument Nginx and Java with OpenTelemetry, then open one Trace in &lt;strong&gt;&lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;DataBuff&lt;/a&gt;&lt;/strong&gt; that spans &lt;strong&gt;Nginx → Java → Redis&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What OpenTelemetry is doing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenTelemetry stitches each service hop into one call chain.&lt;/strong&gt; A full request is a Trace; each processing segment is a Span. Nginx uses the official module, Java uses the official agent — each records its hop, exports with the same TraceID, and the platform merges the fragments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl / browser
   │   GET /hello
   ▼
[ Nginx  nginx:1.27-alpine-otel ]   ngx_otel_module   → OTLP gRPC 4317
   │   reverse proxy proxy_pass
   ▼
[ Java   JDK HttpServer + Jedis ]   opentelemetry-javaagent → OTLP HTTP 4318
   │   set + get
   ▼
[ Redis  192.168.50.120:16379 ]     Jedis auto-instrumented
   ▼
[ DataBuff ]  ← gRPC 4317 + HTTP 4318, merged under one TraceID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Hop 1 · Nginx — two install paths&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The official OTel module needs a recent Nginx (1.21+). Our host still runs 1.20.1, so &lt;strong&gt;path A&lt;/strong&gt; uses the official image that already ships the module; &lt;strong&gt;path B&lt;/strong&gt; installs the module package on an existing Nginx and adds one &lt;code&gt;load_module&lt;/code&gt; line. OTel directives are the same either way.&lt;/p&gt;

&lt;p&gt;Path A — official image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; nginx-otel &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 8090:80 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--add-host&lt;/span&gt; host.docker.internal:host-gateway &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; /path/to/nginx.conf:/etc/nginx/nginx.conf:ro &lt;span class="se"&gt;\&lt;/span&gt;
  nginx:1.27-alpine-otel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Path B — Alpine example: &lt;code&gt;apk add --repository https://nginx.org/packages/mainline/alpine/v3.21/main nginx-module-otel&lt;/code&gt;, then &lt;code&gt;load_module /usr/lib/nginx/modules/ngx_otel_module.so;&lt;/code&gt; and &lt;code&gt;nginx -s reload&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Config points that matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Export over &lt;strong&gt;gRPC&lt;/strong&gt; &lt;code&gt;host.docker.internal:4317&lt;/code&gt; (HTTP 4318 fails with &lt;code&gt;OTel export failure ... Socket closed&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;otel_service_name nginx-otel-demo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;otel_trace on&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The line people miss: &lt;code&gt;otel_trace_context propagate;&lt;/code&gt;.&lt;/strong&gt; By default the module receives upstream context but does not inject it downstream. Without this line Nginx reports its own Span, but Java never sees the TraceID — you get two unrelated Traces. After adding &lt;code&gt;propagate&lt;/code&gt;, they joined immediately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;otel_exporter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;endpoint&lt;/span&gt; &lt;span class="nf"&gt;host.docker.internal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4317&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;# gRPC&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;otel_service_name&lt;/span&gt; &lt;span class="s"&gt;nginx-otel-demo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;otel_trace_context&lt;/span&gt; &lt;span class="s"&gt;propagate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;# required: inject traceparent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Hop 2 · Java agent, zero code changes&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-javaagent&lt;/span&gt;:opentelemetry-javaagent.jar &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-Dotel&lt;/span&gt;.service.name&lt;span class="o"&gt;=&lt;/span&gt;java-redis-demo &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-Dotel&lt;/span&gt;.exporter.otlp.endpoint&lt;span class="o"&gt;=&lt;/span&gt;http://127.0.0.1:4318 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-cp&lt;/span&gt; &lt;span class="s2"&gt;"libs/*:classes"&lt;/span&gt; OtelDemoServer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Java uses HTTP OTLP (4318), Nginx uses gRPC (4317)&lt;/strong&gt; — two protocols, one DataBuff, one Trace later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hop 3 · Two exporters, one Trace&lt;/strong&gt;&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%2F3e00x2i3ju2fktuj20u4.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%2F3e00x2i3ju2fktuj20u4.png" alt="service-list" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both &lt;code&gt;nginx-otel-demo&lt;/code&gt; and &lt;code&gt;java-redis-demo&lt;/code&gt; show up with volume, error rate, and latency.&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%2Ffiqsh8til4ykk0a8okyt.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%2Ffiqsh8til4ykk0a8okyt.png" alt="topology" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Topology draws &lt;code&gt;nginx-otel-demo&lt;/code&gt; → &lt;code&gt;java-redis-demo&lt;/code&gt; → Redis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/epov100r6v9hxqllxlv9.png" rel="noopener noreferrer"&gt;https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/epov100r6v9hxqllxlv9.png&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Waterfall: &lt;code&gt;/hello&lt;/code&gt; (nginx) → &lt;code&gt;GET /hello&lt;/code&gt; (java) → &lt;code&gt;AUTH/SET/GET&lt;/code&gt; (redis), total &lt;strong&gt;975ms&lt;/strong&gt;, TraceID &lt;code&gt;7dff87e865b7fe975877a506db26a2ab&lt;/code&gt;. The Demo sleeps about one second in Java on purpose — nginx Span (975ms) and Java Span (974.75ms) rise together, so &lt;strong&gt;Nginx duration really covers the whole request&lt;/strong&gt;. Redis even records &lt;code&gt;AUTH&lt;/code&gt; as its own Span when the connection uses a password.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't trust the UI alone — check Doris&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;span_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parent_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;is_parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;trace_dc_span&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;trace_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'7dff87e865b7fe975877a506db26a2ab'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nginx-otel-demo  /hello      (empty, root)  975000000
java-redis-demo  GET /hello  &amp;lt;nginx span&amp;gt;   974745285
[redis]…:16379   AUTH        &amp;lt;java span&amp;gt;     638593
[redis]…:16379   SET         &amp;lt;java span&amp;gt;     361212
[redis]…:16379   GET         &amp;lt;java span&amp;gt;     164941
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F5bw939dn1ye9gq0tqpun.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%2F5bw939dn1ye9gq0tqpun.png" alt="trace-list" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Filter the trace list by nginx / java when you're hunting edge issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it tonight — three steps&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;docker run&lt;/code&gt; &lt;code&gt;nginx:1.27-alpine-otel&lt;/code&gt; with &lt;code&gt;otel_trace_context propagate;&lt;/code&gt;, expose &lt;code&gt;http://&amp;lt;host&amp;gt;:8090/hello&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Start Java with &lt;code&gt;-javaagent:opentelemetry-javaagent.jar&lt;/code&gt; pointing at &lt;code&gt;http://127.0.0.1:4318&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;curl http://192.168.50.140:8090/hello&lt;/code&gt; a few times, wait ~30s for batch export, open DataBuff Traces, filter &lt;code&gt;nginx-otel-demo&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&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%2Foyzeji4561744fknw8t5.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%2Foyzeji4561744fknw8t5.png" alt="login-page" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Self-check: nginx root Span present; Java under nginx (not a sibling Trace); Redis SET/GET under Java. If you see two Traces, you almost certainly forgot &lt;code&gt;propagate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Fifteen minutes on the Nginx module and the Java agent turns the first hop from a blind spot into a span you can scroll.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;DataBuff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open-source AI-native OpenTelemetry APM — metrics, traces, logs and AI troubleshooting in one platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://demo.databuff.ai" rel="noopener noreferrer"&gt;https://demo.databuff.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opentelemetry</category>
      <category>nginx</category>
      <category>devops</category>
      <category>observability</category>
    </item>
    <item>
      <title>What Does a Self-Caring Software Look Like? (DataBuff Self-Monitoring &amp; Self-Troubleshooting)</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Mon, 10 Aug 2026 01:22:18 +0000</pubDate>
      <link>https://dev.to/databufflabs/what-does-a-self-caring-software-look-like-databuff-self-monitoring-self-troubleshooting-4nie</link>
      <guid>https://dev.to/databufflabs/what-does-a-self-caring-software-look-like-databuff-self-monitoring-self-troubleshooting-4nie</guid>
      <description>&lt;p&gt;When you're on call, the worst thing isn't that your business went down — it's that &lt;strong&gt;your monitoring platform itself broke and you had no idea&lt;/strong&gt;. Log volume suddenly drops, a chunk of data silently disappears — and after hours of searching you realize it was never the business at fault: the collection pipeline choked on itself. To make it worse, traditional monitoring software is always watching "everything else," while being a black box itself: CPU spikes, memory full, queues blocked — it never says a single word.&lt;/p&gt;

&lt;p&gt;First, what is DataBuff: an open-source AI-native APM where the AI lives directly on top of your OpenTelemetry data — asking questions and troubleshooting are done by AI experts calling tools against real data. Project on GitHub (&lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;github.com/databufflabs/databuff&lt;/a&gt;). Its approach is different: &lt;strong&gt;it treats itself as a business system being monitored&lt;/strong&gt;. Once installed, you can see whether it's healthy, why it's abnormal, which parameter to tune — you can even say one sentence and it will run an inspection on itself. This article walks through a real case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. It watches itself: the platform's self-monitoring page&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DataBuff's "Deployment Status" page exposes metrics for all three core components: &lt;strong&gt;ingest&lt;/strong&gt; (collects data), &lt;strong&gt;web&lt;/strong&gt; (queries data), and &lt;strong&gt;Doris&lt;/strong&gt; (stores data). The overview opens with four cards that state the conclusion up front: inbound events per second, any write failures, Doris disk remaining, any query errors.&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%2Fesr4a8g27yqvwc60qoyk.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%2Fesr4a8g27yqvwc60qoyk.png" alt="Deployment Status overview: inbound TPS, write failures, Doris disk usage, query failures" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scrolling down gets more granular: every signal path in ingest — trace / metric / log — is tracked individually with "how many, how big, how slow, any dropped"; Doris disk and CPU are broken out too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It understands itself: every metric ships with its own manual&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;More metrics isn't the point — &lt;strong&gt;every metric comes with an explanation and its tuning parameters&lt;/strong&gt;. Click the title of any chart and a drawer pops up: how this metric is computed, whether you should worry, &lt;strong&gt;which env var to tune when it goes wrong, and the default value&lt;/strong&gt;. All explained at once.&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%2Fm18kde410xo1mo5ry6ct.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%2Fm18kde410xo1mo5ry6ct.png" alt="Clicking " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take the "Write Drop" metric: the drawer tells you it only occurs in two situations — the queue is full and a whole batch is dropped, or writes fail consecutively and are discarded; it reminds you that "any sustained drop means data loss — check queue depth, write failures, and Doris liveness first"; and finally it lists the tunable parameters directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. It does health checkups: one sentence, AI inspects the whole platform&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't want to flip through page after page? Just tell the AI platform "&lt;strong&gt;inspect the DataBuff platform and produce an HTML inspection report&lt;/strong&gt;". The product support expert reads the metric catalog, queries the platform's own self-monitoring metrics, picks out the anomalies, and produces an HTML report you can forward directly.&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%2Fx5r0fi1ewf2laskgyw4l.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%2Fx5r0fi1ewf2laskgyw4l.png" alt="Platform inspection report triggered by one sentence (live): overall healthy, zero inbound/write failures, Doris all green, two follow-ups auto-flagged" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We ran it live: within minutes it automatically checked ingest, writes, pipeline, query domain, Doris, and process resources. The conclusion matched manual troubleshooting — one query-domain failure was still ongoing, and it flagged it as-is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. It diagnoses: logs are dropping, and it finds the cause itself&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This data loss isn't made up — it actually happened and was actually fixed in our demo environment. The "Write Drop" metric on the Deployment Status page went red — only the &lt;strong&gt;log&lt;/strong&gt; signal was dropping continuously, thousands to fifteen thousand per minute:&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%2Fkg5hgqq04q2ijxbj3i0c.jpg" 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%2Fkg5hgqq04q2ijxbj3i0c.jpg" alt="Write Drop self-monitoring chart (live): the log line keeps dropping, thousands to 15k/min, Ready queue 16/16 full" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, no one needs to flip through pages. Just say the word in the AI platform and let the expert investigate. It first rules out two "non-issues": the business side is normal — not the app's fault; Doris storage is alive and writes are fast — not the storage's fault. The real cause lands in ingest. Logs are batched and pushed into a write queue — &lt;strong&gt;this environment's queue holds only 16 batches, normally 32&lt;/strong&gt;. Sudden bursts don't fit, and the overflow gets dropped as whole batches. The log shows &lt;code&gt;Doris ready queue full (16/16)&lt;/code&gt; every minute — confirmed.&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%2Fekme2tj7g01hanhpaz7l.jpg" 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%2Fekme2tj7g01hanhpaz7l.jpg" alt="AI troubleshooting explains the drop chain (live): batching → 16-batch write queue → queue full, whole batch dropped → Doris storage, each step backed by a metric" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It packages "why it dropped, where it dropped, which param to tune, and to what value" into a conclusion with evidence, and hands over the fix suggestion:&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%2Fqrcmjptbvyi5pky8l4wd.jpg" 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%2Fqrcmjptbvyi5pky8l4wd.jpg" alt="The fix suggestion from troubleshooting (live): which param to tune, the default, and the suggested value, all written in the conclusion" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. It fixes itself: changing params and restarting, all on its own&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The suggested fix is exactly this group of &lt;code&gt;INGEST_DORIS_*&lt;/code&gt; parameters — the core problem is a too-small queue, just make it bigger:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;INGEST_DORIS_MAX_READY_BATCHES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;Write queue too small for bursts; double it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;INGEST_DORIS_FLUSH_TIMEOUT_MS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;30s&lt;/td&gt;
&lt;td&gt;60s&lt;/td&gt;
&lt;td&gt;Restore default write timeout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;INGEST_DORIS_FLUSH_BATCH_BYTES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;50 MiB&lt;/td&gt;
&lt;td&gt;50 MiB (unchanged)&lt;/td&gt;
&lt;td&gt;Not touched this time&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And you don't change the params or restart by hand. The product support expert &lt;strong&gt;SSHs in, edits the config, and restarts ingest&lt;/strong&gt; per the suggestion, then re-checks to confirm:&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%2Fljstdb9fudjlz422qe3p.jpg" 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%2Fljstdb9fudjlz422qe3p.jpg" alt="Product support expert executes the operation (live): SSH → backup config → change params → restart ingest → verify" width="800" height="389"&gt;&lt;/a&gt;&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%2Fm5wgcqsllxcunk2j9lqq.jpg" 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%2Fm5wgcqsllxcunk2j9lqq.jpg" alt="Post-fix recheck (live): query the platform's self-monitoring again, confirm drops back to zero" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the restart takes effect, drops return to zero — before the fix, thousands dropped per minute; after the restart, several consecutive minutes at 0, the curve back to normal:&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%2Frhb2pe3k7ybw25toburi.jpg" 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%2Frhb2pe3k7ybw25toburi.jpg" alt="Self-monitoring chart after the fix (live): Write Drop back to zero, curve recovered" width="799" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All a human did: ask it to diagnose, then ask it to fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting started — you can use it the same way&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After install, check &lt;strong&gt;Deployment Config → Deployment Status&lt;/strong&gt;; scan the four overview cards for health at a glance&lt;/li&gt;
&lt;li&gt;To confirm whether data is being lost: ingest page → "Write Drop", click the title for the explanation&lt;/li&gt;
&lt;li&gt;Add "how to fix dropping data" to your on-call runbook: trigger troubleshooting in the AI platform for a fix suggestion, let the product support expert SSH in to change &lt;code&gt;INGEST_DORIS_*&lt;/code&gt; and restart ingest&lt;/li&gt;
&lt;li&gt;Periodically have the support expert run a platform inspection and forward the report to the team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Closing — the self-discipline software should have&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Software used to be done the moment it shipped; problems were handled by people watching, investigating, and restarting. What DataBuff does isn't complicated: it builds the operational work into the software itself, using the same methods you already use to watch your business.&lt;/p&gt;

&lt;p&gt;This data loss — from discovery to on-box fix — nobody opened a runbook or guessed a direction even once.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;DataBuff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open-source AI-native OpenTelemetry APM — metrics, traces, logs and AI troubleshooting in one platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;https://github.com/databufflabs/databuff&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://demo.databuff.ai" rel="noopener noreferrer"&gt;https://demo.databuff.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apm</category>
      <category>opentelemetry</category>
      <category>devops</category>
      <category>observability</category>
    </item>
    <item>
      <title>The OpenTelemetry Ecosystem Is Strong — DataBuff Can Plug Into Its eBPF Trace Path</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Thu, 06 Aug 2026 01:24:44 +0000</pubDate>
      <link>https://dev.to/databufflabs/the-opentelemetry-ecosystem-is-strong-databuff-can-plug-into-its-ebpf-trace-path-1kb5</link>
      <guid>https://dev.to/databufflabs/the-opentelemetry-ecosystem-is-strong-databuff-can-plug-into-its-ebpf-trace-path-1kb5</guid>
      <description>&lt;p&gt;The OpenTelemetry community packaged eBPF trace collection as &lt;strong&gt;OBI&lt;/strong&gt; (OpenTelemetry eBPF Instrumentation). On Kubernetes you run a DaemonSet per node; eBPF watches HTTP calls between local services, assembles traces, and exports them — &lt;strong&gt;app Pods stay unchanged&lt;/strong&gt;. Image: &lt;code&gt;otel/ebpf-instrument&lt;/code&gt;. Project: &lt;a href="https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation" rel="noopener noreferrer"&gt;opentelemetry-ebpf-instrumentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Where do traces land? &lt;strong&gt;&lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;DataBuff&lt;/a&gt;&lt;/strong&gt; is an open-source APM platform for services, topology, and call chains. Point OBI at DataBuff and you're done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One DaemonSet, one collector Pod per node&lt;/strong&gt; — ns &lt;code&gt;obi&lt;/code&gt;, app Pods untouched, eBPF on local HTTP → export to DataBuff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 · Install DataBuff
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://databuff.ai/databuff/ai-apm-k8s-install.sh | bash
kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; databuff get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All Pods Running and the UI opens — you're good.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 · Check eBPF readiness on app nodes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; /sys/kernel/btf/vmlinux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kernel &lt;strong&gt;5.8+&lt;/strong&gt; recommended; the second command must list a file. Without BTF, collector Pods won't capture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 · Image
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;otel/ebpf-instrument:latest&lt;/code&gt; (worked in our test; &lt;strong&gt;pin a version in production&lt;/strong&gt;). Skip if the cluster can pull; offline clusters need &lt;code&gt;docker load&lt;/code&gt; on nodes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 · Apply the DaemonSet
&lt;/h2&gt;

&lt;p&gt;Replace &lt;code&gt;YOUR_APP_NAMESPACE&lt;/code&gt; and &lt;code&gt;YOUR_DATABUFF_HOST&lt;/code&gt; (&lt;code&gt;ai-apm-ingest.databuff.svc&lt;/code&gt;). &lt;code&gt;hostPID&lt;/code&gt; + &lt;code&gt;privileged&lt;/code&gt; are required.&lt;/p&gt;

&lt;p&gt;Key config:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;discovery.instrument.k8s_namespace&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ebpf.context_propagation: headers&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;otel_traces_export.endpoint: http://YOUR_DATABUFF_HOST:4318&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; obi.yaml
kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; obi get ds,pods &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DESIRED / READY should match node count.&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%2F2302r5nv29dzauyvtlxj.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%2F2302r5nv29dzauyvtlxj.png" alt="DaemonSet READY 5/5" width="800" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 · Logs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; obi logs &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;obi &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;80 | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"instrumenting|process|error"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for &lt;code&gt;instrumenting process&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 · Traffic
&lt;/h2&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="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 80&lt;span class="si"&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;-sS&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 2 &lt;span class="s2"&gt;"http://your-app-url/"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true
  sleep &lt;/span&gt;0.2
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7 · Verify in DataBuff
&lt;/h2&gt;

&lt;p&gt;Open &lt;strong&gt;APM → Services&lt;/strong&gt;, then topology and trace detail.&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%2Fvo3xqsz7x9q1u40cgute.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%2Fvo3xqsz7x9q1u40cgute.png" alt="Service list" width="800" height="500"&gt;&lt;/a&gt;&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%2Fx45e0ul255uxwfvyxher.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%2Fx45e0ul255uxwfvyxher.png" alt="Topology" width="800" height="500"&gt;&lt;/a&gt;&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%2F0p9k11415fnnozj4lcug.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%2F0p9k11415fnnozj4lcug.png" alt="Trace list" width="800" height="500"&gt;&lt;/a&gt;&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%2F3qtrc38lktsvdvl1cdw4.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%2F3qtrc38lktsvdvl1cdw4.png" alt="Trace waterfall" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  eBPF vs language Agent
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Better when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;eBPF + DaemonSet&lt;/td&gt;
&lt;td&gt;No injection/restart; HTTP-first; polyglot quick layer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language Agent&lt;/td&gt;
&lt;td&gt;Dubbo, slow SQL, method stacks; kernel &amp;lt; 5.8 / no BTF&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt; no Dubbo RPC yet; no method stacks or custom business spans; privileged Pod + BTF required.&lt;/p&gt;

&lt;h2&gt;
  
  
  How multi-hop traces connect
&lt;/h2&gt;

&lt;p&gt;With &lt;code&gt;context_propagation: headers&lt;/code&gt; and no app code changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ingress&lt;/strong&gt; — read &lt;code&gt;Traceparent:&lt;/code&gt; on incoming HTTP; attach or create trace context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local correlate&lt;/strong&gt; — match outbound HTTP to the inbound request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Egress&lt;/strong&gt; — sockmap &lt;code&gt;sk_msg&lt;/code&gt; inserts this hop's &lt;code&gt;Traceparent&lt;/code&gt; after the request line.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;HTTPS uses a separate TCP Option path upstream; this walkthrough is plain HTTP + headers.&lt;/p&gt;

&lt;p&gt;Full bilingual post (with more YAML detail): &lt;a href="https://databuff.ai/blog/en/databuff-obi-ebpf-traces" rel="noopener noreferrer"&gt;databuff.ai/blog/en/databuff-obi-ebpf-traces&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opentelemetry</category>
      <category>ebpf</category>
      <category>kubernetes</category>
      <category>devops</category>
    </item>
    <item>
      <title>Palantir Made Ontology Hot — Can APM Troubleshooting Stop at Ontology Alone?</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Fri, 31 Jul 2026 08:25:28 +0000</pubDate>
      <link>https://dev.to/databufflabs/palantir-made-ontology-hot-can-apm-troubleshooting-stop-at-ontology-alone-5dg5</link>
      <guid>https://dev.to/databufflabs/palantir-made-ontology-hot-can-apm-troubleshooting-stop-at-ontology-alone-5dg5</guid>
      <description>&lt;p&gt;"Ontology" is back in fashion. Palantir Foundry is not pitched as yet another data warehouse — it builds an &lt;strong&gt;ontology&lt;/strong&gt; for the enterprise: tables, streams, and sensors become "Customer," "Order," and "Device," with relationships and actions defined so data becomes a world model programs can reason over. LLMs made the pitch louder — models still need to know what exists in the world.&lt;/p&gt;

&lt;p&gt;For our field: &lt;strong&gt;what is the APM ontology? And if you build it, does incident triage just work?&lt;/strong&gt; Two separate questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q1 · How to build an APM ontology&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An APM ontology is two steps: &lt;strong&gt;extract&lt;/strong&gt; entities and relationships from traces, then &lt;strong&gt;materialize&lt;/strong&gt; them into metric tables.&lt;/p&gt;

&lt;p&gt;Setup: service A has instances A-1 and A-2; two endpoints; both call database DB and run the same SQL1. Four traces:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;service&lt;/th&gt;
&lt;th&gt;instance&lt;/th&gt;
&lt;th&gt;endpoint&lt;/th&gt;
&lt;th&gt;call&lt;/th&gt;
&lt;th&gt;sql&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;T1&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;A-1&lt;/td&gt;
&lt;td&gt;ep1&lt;/td&gt;
&lt;td&gt;DB&lt;/td&gt;
&lt;td&gt;SQL1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T2&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;A-1&lt;/td&gt;
&lt;td&gt;ep2&lt;/td&gt;
&lt;td&gt;DB&lt;/td&gt;
&lt;td&gt;SQL1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T3&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;A-2&lt;/td&gt;
&lt;td&gt;ep1&lt;/td&gt;
&lt;td&gt;DB&lt;/td&gt;
&lt;td&gt;SQL1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T4&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;A-2&lt;/td&gt;
&lt;td&gt;ep2&lt;/td&gt;
&lt;td&gt;DB&lt;/td&gt;
&lt;td&gt;SQL1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — extract.&lt;/strong&gt; From T1: entities are service A, instance A-1, endpoint ep1, database DB, SQL1. Relationships: A has instance A-1; A exposes ep1; A-1 serves requests on ep1; ep1 calls DB; ep1 executes SQL1; DB has statement SQL1. P99, latency, and call count are &lt;em&gt;not&lt;/em&gt; entities — they are observations attached to entities.&lt;/p&gt;

&lt;p&gt;All four traces together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Service hasInstance Instance&lt;/strong&gt;: A → A-1, A-2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service exposes Endpoint&lt;/strong&gt;: A → ep1, ep2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instance serves request on Endpoint&lt;/strong&gt;: A-1 / A-2 both serve ep1 and ep2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint calls DB&lt;/strong&gt;: ep1 → DB; ep2 → DB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint executes SQL&lt;/strong&gt;: ep1 → SQL1; ep2 → SQL1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DB hasStatement SQL&lt;/strong&gt;: DB → SQL1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — materialize.&lt;/strong&gt; Extracted entities become queryable metric tables. In &lt;a href="https://github.com/databufflabs/databuff" rel="noopener noreferrer"&gt;DataBuff&lt;/a&gt;'s Doris layer (schema is open source), dimension columns are entities; call_count / resp_time are observations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table&lt;/th&gt;
&lt;th&gt;Dimensions&lt;/th&gt;
&lt;th&gt;Observations&lt;/th&gt;
&lt;th&gt;Entities&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;metric_service&lt;/td&gt;
&lt;td&gt;service&lt;/td&gt;
&lt;td&gt;call_count / resp_time / error_count&lt;/td&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;metric_service_instance&lt;/td&gt;
&lt;td&gt;service + instance&lt;/td&gt;
&lt;td&gt;same&lt;/td&gt;
&lt;td&gt;Service, Instance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;metric_service_http&lt;/td&gt;
&lt;td&gt;service + instance + endpoint&lt;/td&gt;
&lt;td&gt;same&lt;/td&gt;
&lt;td&gt;Service, Instance, Endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;metric_service_db&lt;/td&gt;
&lt;td&gt;service + instance + db + sql&lt;/td&gt;
&lt;td&gt;db calls / db latency&lt;/td&gt;
&lt;td&gt;Service, Instance, DB, SQL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Aggregating the four traces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;metric_service&lt;/strong&gt;: service A → 1 row, 4 entry calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;metric_service_instance&lt;/strong&gt;: by instance → 2 rows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;metric_service_http&lt;/strong&gt;: by instance + endpoint → 4 rows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;metric_service_db&lt;/strong&gt;: by instance + DB + SQL → 2 rows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ontology done: traces tell you what exists and what connects; metric tables materialize those entities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q2 · Is ontology enough?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Entities and relationships complete — is troubleshooting solved? Consider how a connection pool actually behaves:&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%2Fdatabuff.ai%2Fblog%2Fapm-ontology-model%2Fassets%2Fconnection-pool-logic.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%2Fdatabuff.ai%2Fblog%2Fapm-ontology-model%2Fassets%2Fconnection-pool-logic.png" alt="Connection pool branches an ER diagram cannot capture" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even if you add ConnectionPool as Service → ConnectionPool → Database, you only label the big boxes. The branches and states in between &lt;strong&gt;cannot be covered by adding one more entity&lt;/strong&gt; — that layer is &lt;strong&gt;logic&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;a) &lt;strong&gt;Acquire&lt;/strong&gt;: idle → return; can grow → create; pool full → lock wait; timeout → error&lt;br&gt;
b) &lt;strong&gt;Use / return&lt;/strong&gt;: run SQL → return → wake waiters&lt;br&gt;
c) &lt;strong&gt;Background maintenance&lt;/strong&gt;: heartbeat, evict stale connections&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entity-only reasoning fails when an endpoint slows down:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Ontology only&lt;/th&gt;
&lt;th&gt;With logic&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reasoning&lt;/td&gt;
&lt;td&gt;endpoint → DB, slow ⇒ DB slow&lt;/td&gt;
&lt;td&gt;stuck in lock wait, SQL never ran&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Symptom&lt;/td&gt;
&lt;td&gt;endpoint latency up&lt;/td&gt;
&lt;td&gt;DB execution may be fine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conclusion&lt;/td&gt;
&lt;td&gt;root cause is DB&lt;/td&gt;
&lt;td&gt;root cause is &lt;strong&gt;waiting for a connection&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;First principles: &lt;strong&gt;program = data + logic&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Ontology&lt;/th&gt;
&lt;th&gt;Logic&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Manages&lt;/td&gt;
&lt;td&gt;what exists, who connects&lt;/td&gt;
&lt;td&gt;how requests flow, where they stall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Locks onto&lt;/td&gt;
&lt;td&gt;target entities&lt;/td&gt;
&lt;td&gt;last-mile root cause&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Without it&lt;/td&gt;
&lt;td&gt;no drill-down target&lt;/td&gt;
&lt;td&gt;stuck at "something is wrong"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Connection pool is one slice — it shows entity-only is not enough. See how DataBuff breaks down latency for one endpoint:&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%2Fdatabuff.ai%2Fblog%2Fapm-ontology-model%2Fassets%2Fendpoint-latency-logic-breakdown.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%2Fdatabuff.ai%2Fblog%2Fapm-ontology-model%2Fassets%2Fendpoint-latency-logic-breakdown.png" alt="DataBuff endpoint latency breakdown" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entry average ~240ms; breakdown shows HTTP service-b ~100ms, RPC service-b ~80ms, remainder in MySQL, ES, Redis, Kafka. That is &lt;strong&gt;logic modeling for one entry&lt;/strong&gt; — track entry latency and state, then each operation type after the entry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q3 · How to model logic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Scale to a real app: track latency and state for &lt;strong&gt;every entry&lt;/strong&gt;, and for &lt;strong&gt;each operation type&lt;/strong&gt; after every entry. Entries include RPC, HTTP, MQ consumers, scheduled jobs, and more.&lt;/p&gt;

&lt;p&gt;After a request enters, it typically lands in &lt;strong&gt;5 operation types + 1 behavior&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Key dimensions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DB remote operation&lt;/td&gt;
&lt;td&gt;dal group / table / operation / sql&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redis remote operation&lt;/td&gt;
&lt;td&gt;command&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MQ remote operation&lt;/td&gt;
&lt;td&gt;exchange / routingKey / vhost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RPC remote operation&lt;/td&gt;
&lt;td&gt;downstream service / remote method&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local operation&lt;/td&gt;
&lt;td&gt;no extra attributes yet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thrown exception&lt;/td&gt;
&lt;td&gt;exception name&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For remote operations, split latency into three parts:&lt;/p&gt;

&lt;p&gt;a) &lt;strong&gt;Client&lt;/strong&gt;: connect, send, receive&lt;br&gt;
b) &lt;strong&gt;Network&lt;/strong&gt;: transport&lt;br&gt;
c) &lt;strong&gt;Server&lt;/strong&gt;: peer execution&lt;/p&gt;

&lt;p&gt;Pool-full lock wait accrues on the &lt;strong&gt;client&lt;/strong&gt; — &lt;strong&gt;waiting for a connection ≠ slow SQL&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Incidents then follow one chain: which entries → local ops → remote ops (down to SQL/method) → network vs server → exceptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ontology locks entities; logic locks root cause.&lt;/strong&gt; Logic models entry → operation → remote three-part latency → exception, with latency and state at each layer. For AI to separate "waiting for a connection" from "slow SQL," it must land on entities via ontology, then walk this logic chain to the actual reason.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>apm</category>
      <category>devops</category>
      <category>observability</category>
    </item>
    <item>
      <title>Install Failed but the Page Still Opens — Ops Expert Restores Doris</title>
      <dc:creator>databufflabs</dc:creator>
      <pubDate>Tue, 28 Jul 2026 01:27:27 +0000</pubDate>
      <link>https://dev.to/databufflabs/install-failed-but-the-page-still-opens-ops-expert-restores-doris-16p</link>
      <guid>https://dev.to/databufflabs/install-failed-but-the-page-still-opens-ops-expert-restores-doris-16p</guid>
      <description>&lt;p&gt;Almost every product hits two kinds of user pain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Can't use it:&lt;/strong&gt; install fails, won't start, or dies in production — errors only, then humans grep logs and guess commands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't know how:&lt;/strong&gt; docs elsewhere, menus buried — ask a helper and get "see the official documentation."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Self-healing ops&lt;/strong&gt; fixes the first: when storage is down the product stays usable, SSH for evidence, change config, restart, verify.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In-product Q&amp;amp;A&lt;/strong&gt; fixes the second: ask the product in natural language; answers come from in-product docs and your deployment.&lt;/p&gt;

&lt;p&gt;DataBuff is an &lt;strong&gt;open-source, AI-native OpenTelemetry APM&lt;/strong&gt; — metrics, traces, logs first; AI on the same telemetry. Three pieces: &lt;strong&gt;Ingest&lt;/strong&gt;, &lt;strong&gt;Doris&lt;/strong&gt;, &lt;strong&gt;AI platform / Web&lt;/strong&gt;.&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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F00-simple-architecture.jpg" 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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F00-simple-architecture.jpg" alt="DataBuff minimal architecture" width="800" height="400"&gt;&lt;/a&gt;&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;-fsSL&lt;/span&gt; https://databuff.ai/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Self-healing in practice:&lt;/strong&gt; Doris breaks during install. Many products go dark; you SSH and guess. We inject &lt;code&gt;mem_limit: 256m&lt;/code&gt; on Doris BE so &lt;code&gt;start.sh&lt;/code&gt; exits non-zero. &lt;strong&gt;Troubleshooting mode&lt;/strong&gt; keeps Web up while Doris is unhealthy.&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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F01-start-fail-terminal.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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F01-start-fail-terminal.png" alt="start.sh non-zero troubleshooting banner" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configure an LLM, open AI chat, pick &lt;strong&gt;Ops Expert&lt;/strong&gt;, grant SSH, ask for locate-and-fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I installed DataBuff on 192.168.50.140 (dir /opt/databuff-ai-apm-failover).
install/start failed but Web opens.
SSH to root@192.168.50.140 (password Databuff@123)
Find why Doris FE/BE is not ready; fix root cause and report results.
Install dir: /opt/databuff-ai-apm-failover
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F04-ops-prompt.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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F04-ops-prompt.png" alt="Ops Expert prompt" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the host: BE Restarting → &lt;code&gt;mem_limit: 256m&lt;/code&gt; OOM → &lt;strong&gt;memory raised to 4g, config persisted, ingest restarted, full-stack Healthy&lt;/strong&gt;.&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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F05-ops-final-conclusion.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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F05-ops-final-conclusion.png" alt="Ops Expert fix summary" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Terminal matches: four containers healthy, Doris &lt;code&gt;SELECT 1&lt;/code&gt; passes. Troubleshooting mode exits automatically.&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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F07-recovery-terminal.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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F07-recovery-terminal.png" alt="Recovery terminal" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In-product Q&amp;amp;A&lt;/strong&gt; on the same AI entry — OTel ingest and alert thresholds:&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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F08a-qa-prompt.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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F08a-qa-prompt.png" alt="Product Q&amp;amp;A prompt" width="800" height="400"&gt;&lt;/a&gt;&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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F08-qa-expert.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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F08-qa-expert.png" alt="OTel ingest and alerts answer" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then LLM setup — menu paths, required fields, common pitfalls:&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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F09a-qa2-prompt.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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F09a-qa2-prompt.png" alt="LLM config question" width="800" height="400"&gt;&lt;/a&gt;&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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F09-qa2-answer.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%2Fdatabuff.ai%2Fblog%2Fdatabuff-ops-expert-install-troubleshoot%2Fassets%2F09-qa2-answer.png" alt="LLM config answer" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In one line:&lt;/strong&gt; self-healing fixes "can't use it"; in-product Q&amp;amp;A fixes "don't know how."&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>devops</category>
      <category>apm</category>
      <category>opentelemetry</category>
    </item>
  </channel>
</rss>
