<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Machine Learning - Elastic Observability Labs]]></title>
    <description><![CDATA[Trusted security news & research from the team at Elastic.]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Machine Learning - Elastic Observability Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltad972c1c27dbefc6/6a88d9782904ea5e8511d473/observability-labs-thumbnail.png</url>
      <link>https://www.elastic.co/observability-labs/blog/category/machine-learning</link>
    </image>
    <link>https://www.elastic.co/observability-labs/blog/category/machine-learning</link>
    <atom:link href="https://www.elastic.co/observability-labs/rss/category/machine-learning.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[en]]></language>
    <lastBuildDate>Sat, 24 Oct 2026 10:12:02 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Kubernetes node pressure: Catching the memory drop 7 minutes before the first pod eviction]]></title>
    <description><![CDATA[The pod you lose is rarely the pod that grew. This walkthrough follows a per-node anomaly detection alert all the way to the pod whose working set moved.]]></description>
    <content:encoded><![CDATA[<p>In a staged load test, an<a href="https://www.elastic.co/docs/explore-analyze/machine-learning/anomaly-detection"> Elastic anomaly detection</a> job opened an alert 2 minutes 31 seconds before the kubelet set <code>MemoryPressure </code>and 7 minutes 29 seconds before the first failed HTTP request. By the time <code>MemoryPressure</code> turns true, the kubelet is already choosing which pods to evict, and it doesn’t choose the pod that used the memory. In this run, it evicted an NGINX pod using under 9 MiB and took the service down with it.</p><p>Kubernetes node pressure starts when available memory or disk on a node crosses the kubelet's eviction thresholds and an alert on that condition arrives with little time left to act. Anomaly detection learns what normal available memory looks like for each node and flags the drop while the node still has headroom, though not every drop. A second run, where the same total load arrived at once, scored 4.2 and opened no alert at all. So this walk-through runs the <code>low_mean</code> job alongside a headroom rule and the [Kubernetes OTel] pressure rule templates. Node metrics come from the<a href="https://www.elastic.co/docs/reference/opentelemetry"> Elastic Distribution of OpenTelemetry (EDOT) Collector</a>, and the triage path follows whichever alert opens to the pod that changed.</p><h2>Prerequisites: Elastic, Kubernetes, and EDOT versions</h2><ul><li><p>An Elastic deployment with machine learning (ML) enabled and the <a href="https://www.elastic.co/docs/explore-analyze/machine-learning/setting-up-machine-learning">privileges and subscription for anomaly detection</a>. This walk-through uses Elastic Cloud Hosted 9.5.4.</p></li><li><p>A Kubernetes cluster where you can install a Helm chart. The examples use EDOT Collector 9.5.4 with the kube-stack chart 0.16.0.</p></li><li><p>The Kubernetes OpenTelemetry Assets integration (2.6.0 here), which supplies the dashboards and alerting rule templates used below.</p></li></ul><p>You can find the companion notebook <a href="https://github.com/elastic/elastic-labs/blob/main/supporting-blog-content/observability-labs/kubernetes-node-pressure-anomaly-detection/kubernetes-node-pressure-anomaly-detection.ipynb">here</a>. It reproduces the whole lab from this article, including the anomaly detection job and the eviction check, and the steps in between, and it cleans up at the end.</p><h2>How Kubernetes node pressure triggers eviction</h2><p>The kubelet compares eviction signals, such as <code>memory.available</code> and <code>nodefs.available</code>, against thresholds. On Linux, the default hard thresholds are <code>memory.available&lt;100Mi</code> and <code>nodefs.available&lt;10%</code>. A hard threshold evicts pods immediately, and a soft threshold starts a grace period first. When either one is crossed, the kubelet sets the MemoryPressure or <code>DiskPressure</code> node condition.</p><p>The kubelet <a href="https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/#pod-selection-for-kubelet-eviction">ranks pods for eviction</a> by whether their usage exceeds their requests, then by pod priority, and then by how far usage exceeds requests. The pod that gets evicted can be a different pod from the one that consumed the memory.</p><p>The following table shows the three signals that this walk-through uses, from earliest to latest, what each one tells you, and what to do when it fires:</p><p></p><p><strong>Signal</strong></p><p><strong>What it tells you</strong></p><p><strong>What to do next</strong></p><p>Low available-memory anomaly</p><p>The node has less headroom than its own baseline predicts</p><p>Find what changed</p><p>Available memory below your warning level</p><p>Remaining capacity is close to the eviction threshold</p><p>Agree on a mitigation with the workload owner</p><p><code>MemoryPressure</code> or <code>DiskPressure</code></p><p>The kubelet has crossed an eviction threshold</p><p>Check for evictions and escalate</p><h2>Staged memory growth on one worker node</h2><p>The test cluster is a two-node <a href="https://kind.sigs.k8s.io/">kind</a> cluster on a Docker virtual machine (VM) with about 8 GiB of memory. The worker's kubelet uses a soft eviction threshold sized for that VM, set through a kubeadm configuration patch in the kind cluster config:</p>kubeletExtraArgs:
  eviction-soft: "memory.available&lt;6Gi"
  eviction-soft-grace-period: "memory.available=5m"<p>Three workloads run on the worker:</p><ol><li><p>A single-replica NGINX deployment with no memory request and a low pod priority. A k6 probe requests it about once per second and exports the results through OpenTelemetry (OTel).</p></li><li><p>A stress pod that allocates 256 MiB after two hours of normal baseline.</p></li><li><p>A second stress pod that allocates 1 GiB about four and a half minutes later.</p></li></ol><p>These memory thresholds fit a laptop-sized lab. Set your own from node capacity and your kubelet configuration.</p><h2>Step 1: Collect Kubernetes node metrics with the EDOT Collector</h2><p>Follow the <a href="https://www.elastic.co/docs/solutions/observability/get-started/opentelemetry/quickstart/ech/k8s">Kubernetes quickstart</a> to install the EDOT Collector through the Managed OpenTelemetry Protocol (mOTLP) endpoint. Add this override to the documented Helm installation:</p>clusterName: node-pressure-v2
collectors:
  cluster:
    config:
      receivers:
        k8s_cluster:
          collection_interval: 10s
          node_conditions_to_report: [Ready, MemoryPressure, DiskPressure]
  daemon:
    config:
      receivers:
        kubeletstats:
          collection_interval: 10s<p>The override adds <code>DiskPressure</code> to the reported node conditions and samples every 10 seconds. Replace <code>node-pressure-v2</code> with your cluster name here and in every later example.</p><p>In <strong>Discover</strong>, confirm two data streams:</p><ol><li><p><code>metrics-kubeletstatsreceiver.otel-*</code> has fresh <code>k8s.node.memory.available</code> values for <code>each k8s.node.name</code>.</p></li><li><p><code>metrics-k8sclusterreceiver.otel-*</code> has <code>k8s.node.condition_memory_pressure</code> and <code>k8s.node.condition_disk_pressure</code>, where 0 is false and 1 is true.</p></li></ol><p>Run this Elasticsearch Query Language (ES|QL) query in <strong>Discover</strong> to see the latest value of both conditions per node in the selected time range:</p><p></p><p></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcf1a3c1ad5bc48ad/6accc77d75da6135083d3232/image6.png" alt="ES|QL query results showing Kubernetes node pressure conditions, memory and disk, for two nodes in Discover" /><p><code>k8s.node.memory.available</code> tracks the value that the kubelet acts on. In the test, the metric read 6,093,116 KiB one second before the kubelet logged an eviction with <code>available: 6092844Ki</code>.</p><h2>Step 2: Create a per-node anomaly detection job for node memory</h2><p>Create the job and its datafeed in <strong>Dev Tools</strong> &gt; <strong>Console</strong>:</p>PUT _ml/anomaly_detectors/node-pressure-memory-v2
{
  "analysis_config": {
    "bucket_span": "1m",
    "detectors": [{
      "function": "low_mean",
      "field_name": "k8s.node.memory.available",
      "partition_field_name": "k8s.node.name"
    }],
    "influencers": ["k8s.node.name"]
  },
  "analysis_limits": {"model_memory_limit": "32mb"},
  "data_description": {"time_field": "@timestamp"},
  "model_plot_config": {"enabled": true},
  "datafeed_config": {
    "datafeed_id": "datafeed-node-pressure-memory-v2",
    "indices": ["metrics-kubeletstatsreceiver.otel-*"],
    "query_delay": "20s",
    "frequency": "10s",
    "query": {"bool": {"filter": [
      {"term": {"k8s.cluster.name": "node-pressure-v2"}},
      {"exists": {"field": "k8s.node.memory.available"}}
    ]}}
  }
}<p>The following settings matter most:</p><ul><li><p><code>low_mean</code> scores only buckets where the average is unusually low, so a node that frees memory never raises an anomaly.</p></li><li><p><code>partition_field_name</code> gives every node its own baseline. A 64 GiB node and an 8 GiB node never share a model.</p></li><li><p><code>bucket_span</code> of 1m suits 10-second sampling in a small cluster. A span of 5m or 15m costs less and smooths noisy nodes, and the alert arrives later.</p></li><li><p><code>query_delay</code> of 20s leaves time for metrics to arrive before a bucket is analyzed.</p></li><li><p><code>model_plot_config </code>stores the model bounds, which <strong>Single Metric Viewer</strong> draws as the expected range.</p></li></ul><p>Open the job, and start the datafeed from the beginning of your node history. Replace the start value with the timestamp of your first kubeletstats document:</p>POST _ml/anomaly_detectors/node-pressure-memory-v2/_open
POST _ml/datafeeds/datafeed-node-pressure-memory-v2/_start
{"start":"2026-09-19T18:53:00Z"}<p>In <strong>Machine Learning</strong> &gt; <strong>Manage jobs</strong>, confirm that the processed record count increases. If a job created through the API is missing from the list, select <strong>Synchronize saved objects</strong>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt92b6285f139a0a7e/6accc73d6f7ed1925fbf3fef/image3.png" alt="Elastic machine learning job config for the per-node low_mean anomaly detection job on node memory available" /><p>A mean detector needs at least <a href="https://www.elastic.co/docs/explore-analyze/machine-learning/anomaly-detection/ml-ad-troubleshooting">eight non-empty buckets or two hours of data</a>, whichever is greater. For production, let the model see full workload cycles, including the busy periods that you expect.</p><h2>Step 3: Create an alerting rule on the anomaly score</h2><p>Open <strong>Stack Management</strong> &gt; <strong>Rules</strong> &gt; <strong>Create rule</strong>, select <strong>Anomaly detection</strong>, name the rule Node pressure v2 as "unusual memory headroom", and choose the job. Use the following settings:</p><p></p><p><strong>Setting</strong></p><p><strong>Value</strong></p><p><strong>Why</strong></p><p><strong>Result type</strong></p><p>Record</p><p>Evaluates each node's own anomaly</p><p><strong>Severity threshold</strong></p><p>25</p><p>Lower edge of the 25–50 band in Anomaly Explorer</p><p><strong>Include interim results</strong></p><p>Off</p><p>Evaluates finalized buckets only</p><p><strong>Check interval</strong></p><p>1 minute</p><p>Matches the job's bucket span</p><p>The anomaly score is a 0–100 measure of how unusual a bucket is for that node. Tune the threshold against routine changes in your cluster.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc84f6476d5d71ac8/6accc7291e82a680e3124e23/image1.png" alt="Elastic anomaly detection rule setup with Record result type and severity threshold 25 for node memory alerts" /><p>Add a <a href="https://www.elastic.co/docs/deploy-manage/manage-connectors">connector</a> and an action so the alert reaches Slack, email, or PagerDuty. Include <code>{{context.anomalyExplorerUrl}}</code> and <code>{{context.topRecords}}</code> from the <a href="https://www.elastic.co/docs/explore-analyze/machine-learning/anomaly-detection/ml-configuring-alerts">anomaly detection action variables</a> in the message, so the notification links straight to the affected node.</p><h2>Step 4: Add Kubernetes alerting rules for headroom and pressure conditions</h2><p>A workload that grows at its usual pace can exhaust a node without producing a high anomaly score. Cover that case with an <a href="https://www.elastic.co/docs/explore-analyze/alerts-cases/alerts/rule-type-es-query">Elasticsearch query rule</a> that uses this ES|QL query:</p><p>Name the rule Node pressure v2: memory headroom warning, set the time field to <code>@timestamp</code>, select <strong>Create an alert for each row</strong>, and use a two-minute window with one-minute checks. The 6.5 GiB level sits 0.5 GiB above the scenario's soft eviction threshold. Size your own margin to how fast memory can fall between two rule runs.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt145547d5b932bd65/6accc711ca19d581fdc5698b/image9.png" alt="Elasticsearch query rule using ES|QL to alert when Kubernetes node memory headroom falls below 6.5 GiB" /><p>Then create the condition rules from <strong>Create rule</strong> &gt; <strong>Templates</strong>: [Kubernetes OTel] Node memory pressure and [Kubernetes OTel] Node disk pressure. Add this line after each template's TS source line, so the rule only evaluates your cluster:</p><p></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt212e8694e0a2faa0/6accc6ecca19d508e9c56987/image10.png" alt="Kubernetes OTel alerting rule templates for node memory pressure, disk pressure and node not ready" /><p>The templates wait for three consecutive matches by default. This walk-through sets the alert delay to one match, because a soft eviction grace period can be shorter than three rule runs. <a href="https://www.elastic.co/observability-labs/blog/alerting-rule-templates-elastic-integrations">Alerting rule templates in Elastic integrations</a> covers the window, schedule, and alert delay settings in more detail.</p><h2>Step 5: Triage a Kubernetes node pressure warning before the eviction</h2><p>When the anomaly alert or the headroom alert opens, work through this loop:</p><ol><li><p>Read the anomaly to identify the node and the size of the drop.</p></li><li><p>Find the pod whose memory changed.</p></li><li><p>Check which pods the kubelet would evict first.</p></li><li><p>Mitigate with the workload owner.</p></li><li><p>Verify recovery from the node and from the service.</p></li></ol><h3>Read the anomaly record to find the affected node</h3><p>Open <strong>Machine Learning</strong> &gt; <strong>Anomaly Explorer</strong>, and select the job and the alert's time range. Then find the <code>k8s.node.name</code> in the anomaly record. Compare the <strong>Actual</strong> and <strong>Typical</strong> columns. Set the table interval to <strong>Show all</strong> to see one row per bucket.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0c4095b5ed269a45/6accc6d5ea4732830630ebba/image7.png" alt="Anomaly Explorer showing low_mean anomaly records per Kubernetes node with actual and typical memory values" /><p>In the scenario, the 20:56 bucket averaged 6.76 GiB against a typical 7.02 GiB, and the rule evaluated a score of 30 for it. MemoryPressure was still false, and the node was above the 6.5 GiB headroom level. Every HTTP request succeeded.</p><p>The <strong>Score</strong> column in this screenshot, taken after the run, reads <strong>2</strong> for the same bucket. Anomaly scores are renormalized as the model sees more data, which the results section covers.</p><h3>Which pod caused the Kubernetes node pressure?</h3><p>Open the [Kubernetes OTel] Node Detail dashboard, and filter to the alert's cluster and node. Then sort the pod table by <strong>Avg memory working set</strong>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt317df0a5cd64603c/6accc6b8f87eb76ef1b43625/image8.png" alt="Kubernetes OTel Node Detail dashboard listing pods on the worker node sorted by average memory working set" /><p></p><p>The largest pod and the one that changed can be different pods. This query compares each pod's last five minutes with its earlier baseline:</p><p>The 10-minute gap between the two windows keeps a new pod's first minutes out of its baseline. Two minutes after the scenario's alert, the query returns <code>memory-change</code> with a <code>change_mib</code> of 246.8 and every other pod on the node within 1 MiB of its baseline.</p><p>Next, list the pods on the node with their Quality of Service (QoS) class and priority:</p>kubectl get pods -A --field-selector spec.nodeName=node-pressure-v2-worker \
  -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,QOS:.status.qosClass,PRIORITY:.spec.priority<p><code>BestEffort</code> pods and low-priority pods that exceed their requests are evicted first. If one of them is a single-replica service, you lose that service when the grace period ends.</p><h3>Mitigate with the workload owner, and verify recovery</h3><p>If headroom is stable and the change is expected, keep watching the node and review the alert threshold. If memory keeps falling toward the eviction threshold, agree on one of these with the workload owner:</p><ul><li><p>Stop or scale down an optional workload.</p></li><li><p>Roll back the deployment change that increased memory use.</p></li><li><p>Add node capacity and move the workload in a controlled way.</p></li></ul><p>Then confirm recovery from both sides. Available memory returns to its typical range, and service requests succeed. Plus, no pods were evicted during the response. This query reads eviction events collected by the <code>k8s_events</code> receiver:</p><p></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcff80299199a6876/6accc69f7a4b457368dc9a53/image5.png" alt="ES|QL query returning two Kubernetes pod eviction events after the node crossed its memory threshold" /><p>When the scenario runs without intervention, the kubelet evicts the NGINX pod first, with the message <code>Container nginx was using 8884Ki, request is 0</code>. The 1 GiB memory-escalation pod follows one second later. The evicted NGINX pod used under 9 MiB, and its eviction took the service down</p><p>The pressure condition clears later than the memory recovers. The kubelet holds <code>MemoryPressure</code> for its <code>eviction-pressure-transition-period</code>, five minutes by default, after the signal returns above the threshold.</p><h2>How much warning does anomaly detection give before a pod eviction?</h2><p>The anomaly alert opened 2 minutes 31 seconds before <code>MemoryPressure</code> and 7 minutes 29 seconds before the first failed request, but only when memory grew gradually. The scenario ran twice. In Run 1, the load continued until the kubelet evicted pods. In Run 2, both allocations started together and the load was removed after the headroom alert, because Run 2 raised no anomaly alert.</p><p></p><p><strong>Event</strong></p><p><strong>Run 1: Load continues</strong></p><p><strong>Run 2: Load removed</strong></p><p>Load starts</p><p>20:56:03 (256 MiB), 21:00:29 (1 GiB)</p><p>21:12:35 (both)</p><p>First finalized anomaly score</p><p>30.1</p><p>4.2</p><p>Anomaly alert</p><p>20:58:09</p><p>None</p><p>MemoryPressure true</p><p>21:00:40</p><p>21:12:45</p><p>Headroom alert</p><p>21:01:21</p><p>21:13:21</p><p>First eviction and failed request</p><p>21:05:38</p><p>None</p><p>Load removed</p><p>21:06:54</p><p>21:15:52</p><p>MemoryPressure clears</p><p>21:10:53</p><p>21:20:45</p><p></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc37585916ff8341f/6accc67698f3c897cab797d0/image2.png" alt="Dashboard showing available memory, MemoryPressure, failed requests and pods evicted during the node pressure test" /><p>The same dashboard embeds the Single Metric Viewer of the anomaly detection job, with the model bounds and the anomaly markers for both runs. The companion notebook imports this dashboard, so you can read your own run the same way.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt74b5a4c7c1848d17/6accc65e98f3c87fa3b797cc/image4.png" alt="Single Metric Viewer with model bounds and anomaly markers for available memory on the Kubernetes worker node" /><p>Three results stand out:</p><ol><li><p>The anomaly alert led <code>MemoryPressure</code> by 2 minutes 31 seconds. It flagged the 256 MiB change, before the 1 GiB allocation that pushed the node over its threshold. Five of the 7 minutes 29 seconds before the first failed request are the configured soft grace period.</p></li><li><p>The headroom alert trailed <code>MemoryPressure</code> in both runs, by 41 and 36 seconds. A 1 GiB step crosses a 0.5 GiB margin and the eviction threshold in the same rule interval. In Run 2, the grace period provided the time to act.</p></li><li><p>The anomaly score depends on how memory changes. The same total load arriving at once scored 4.2 and opened no anomaly alert.</p></li></ol><p>Anomaly scores are renormalized as the model sees more data. The Run 1 record dropped from 30 to 2.7 in Anomaly Explorer after the 1 GiB step, while its <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-ml-get-records"><code>initial_record_score</code></a> kept the value that the rule evaluated. A flat two-hour baseline makes a 3.7% drop stand out. Expect lower scores for the same change on nodes with days of varied history.</p><h2>What the three signals cover together</h2><p>This walk-through modeled available memory per node with a <code>low_mean</code> anomaly detection job and alerted on a record score of 25. A headroom rule and the [Kubernetes OTel] pressure templates covered the changes that the model scored low. The triage loop went from the anomaly record to the pod whose working set changed, the pods first in line for eviction, and a recovery check that includes the service.</p><p></p><p>In the staged test, the anomaly alert arrived first, and only for gradual change. Keep all three signals active, and size the soft eviction grace period as the time your team needs to respond.</p><h2>Where to take the Kubernetes monitoring setup next</h2><p>The following resources extend the lab and give the background for each piece:</p><ul><li><p>Add a second <code>low_mean</code> detector on <code>k8s.node.filesystem.available</code> to the same job to model disk headroom per node.</p></li><li><p><a href="https://www.elastic.co/observability-labs/blog/esql-kubernetes-monitoring">Common ES|QL queries for Kubernetes monitoring</a>, including container memory utilization before an OOM kill</p></li><li><p><a href="https://www.elastic.co/observability-labs/blog/alerting-rule-templates-elastic-integrations">Alerting rule templates in Elastic integrations</a></p></li><li><p><a href="https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/">Node-pressure eviction</a> in the Kubernetes documentation</p></li><li><p><a href="https://www.elastic.co/docs/explore-analyze/machine-learning/anomaly-detection/ml-configuring-alerts">Generating alerts for anomaly detection jobs</a></p></li><li><p><a href="https://www.elastic.co/docs/reference/opentelemetry/use-cases/kubernetes">EDOT Kubernetes guide</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/observability-labs/blog/kubernetes-node-pressure-anomaly-detection</link>
    <guid isPermaLink="false">kubernetes-node-pressure-anomaly-detection</guid>
    <category><![CDATA[Kubernetes]]></category>
    <category><![CDATA[OpenTelemetry]]></category>
    <category><![CDATA[Machine Learning]]></category>
    <dc:creator><![CDATA[Jeffrey Rengifo]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0c209e72a9ea2c83/6accc45f2b0ddf40a8870941/image11.png" length="0" type="image/png"/>
    <pubDate>Mon, 12 Oct 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[From raw logs to system knowledge: the AI context layer observability is missing]]></title>
    <description><![CDATA[A self-updating knowledge base built from your logs: services, dependencies, and failure modes, so your AI agents always know what they are looking at.]]></description>
    <content:encoded><![CDATA[<p>Your monitoring system sees everything, but understands almost nothing.</p>
<p>Before you can rely on most tools to trigger a meaningful alert, you have to do the heavy lifting of telling them exactly what to watch. You have to write the rules, specify what a "normal" baseline looks like, and manually define your service catalog. We're working to change that dynamic at Elastic, and the first major building block is now in place: a system designed to simply read your logs and figure out what's inside them on its own.</p>
<p>Consider what happens when an alert fires today. Your on-call engineer opens an investigation, and the first few minutes are inevitably burned reconstructing basic facts. They have to figure out which services are involved, how those services connect to one another, what error patterns are typical, and which queries they actually need to run to dig deeper. An AI agent faces this exact same cold start problem. Without prior knowledge of your system's architecture, an agent has to read through hundreds of log lines just to establish baseline context that really should already be available.</p>
<p>This blank slate is the default state of most observability setups. You only know what you've explicitly configured. When new services spin up and start writing logs, they sit there without rules until someone takes the time to write them. When architectural dependencies shift, your topology map quietly goes stale unless you've done an exceptional job instrumenting all your services. If an error pattern fires every day but nobody wrote a specific rule to catch it, it remains invisible.</p>
<p>Knowledge Indicators (KI) are our way of closing this gap. When you run extraction against a log stream, Elastic analyzes the raw data and returns structured facts about your environment. It identifies which services are running, the underlying infrastructure they rely on, how they depend on each other, and the log schemas they're using. It even generates a set of ES|QL queries for conditions that might be worth alerting on. Rather than a static configuration, this knowledge accumulates over time, automatically expires when a service disappears, and feeds directly into downstream capabilities like Rules, topology maps, AI agent investigations, and dashboards.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltff3305086ef2e39b/6a7f07c3bdcff054f3c42c2f/topology-graph@2x.png" alt="Knowledge Indicators graph: service nodes (claim-intake, fraud-check, policy-lookup, payment-processor, kafka, notification-dispatch, kubernetes) connected by labeled dependency edges (connection refused, ECONNREFUSED, gRPC UNAVAILABLE, pool exhausted, pod sync)" />
<em>Topology graph generated from dependency KIs: service nodes, dependency edges, and detected error conditions.</em></p>
<h2 id="theextractionpipeline">The Extraction Pipeline</h2>
<p>When designing this system, our primary goal was to eliminate the need for prior context. There should be no mandatory schemas, no service catalogs tied to specific properties, and no predefined static assets that would need to be maintained. We asked ourselves a simple question: if you handed a sample of raw logs to an engineer who had never seen the system before, what could they deduce just by looking?</p>
<p>That thought experiment became our core approach. The system samples a small batch of logs from a stream, processes them through a combination of LLM analysis and deterministic code generators, and accumulates its findings across multiple rounds, entirely configuration-free.</p>
<p>Imagine hiring a room full of junior SREs with one specific job: read these log lines and report their observations, not to fix anything or trigger alarms, just to notice things. "This looks like an nginx server," or "This database is PostgreSQL," or "Service A is calling Service B over HTTP." That's essentially what our extraction job is doing continuously across your streams.</p>
<p>To see how this works in practice, take a look at this single line from an nginx access log:</p>
<pre><code>192.168.1.45 - - [31/Mar/2026:14:23:01 +0000] "POST /api/v2/claims HTTP/1.1" 200 1247 "-" "claim-intake/1.4.2"
</code></pre>
<p>From just this string, the pipeline extracts three distinct facts:</p>
<ul>
<li><strong>Entity</strong>: <code>claim-intake</code> (identifiable as a service from the User-Agent)</li>
<li><strong>Version</strong>: <code>1.4.2</code> (extracted from the User-Agent string)</li>
<li><strong>Technology</strong>: nginx (the web server fielding the request)</li>
<li><strong>Schema</strong>: Combined Log Format</li>
</ul>
<p>Similarly, consider this Java service log:</p>
<pre><code>2026-03-31T14:23:03.412Z INFO fraud-check --- [nio-8080-exec-3] c.e.FraudCheckService : Calling upstream POST http://policy-lookup:8081/v1/policy latency=142ms status=200
</code></pre>
<p>Here, the extraction identifies:</p>
<ul>
<li><strong>Entity</strong>: <code>fraud-check</code> (a Spring Boot service)</li>
<li><strong>Dependency</strong>: <code>fraud-check</code> → <code>policy-lookup</code> (via an outbound HTTP call)</li>
<li><strong>Technology</strong>: Java, Spring Boot</li>
</ul>
<p>Pull twenty lines like these from across your stream, and you quickly build a working, accurate picture of your system architecture.</p>
<p>To ensure this process never blocks ingestion, extraction runs entirely as a background task. You can trigger it on demand from the stream detail view or the Significant Events Discovery UI, but the goal is to have it running by default without requiring attention.</p>
<p>The pipeline itself runs multiple iterations, each time fetching a small sample of documents. We use a mix of random and already-excluded documents to ensure we discover the full scope of the system. KIs found in one iteration are fed back as exclusions into the next, so each round focuses on what the previous one missed—ensuring quieter, less-represented services aren't crowded out by noisier ones.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdfa9e57d3cb5b3bc/6a7f07c6b43770fb324d6a9d/ki-extraction-pipeline@2x.png" alt="KI extraction pipeline: raw logs → three-pool biased sampling (entity-filtered / diverse / random) → LLM finalize_features and 4 computed generators in parallel → merge and dedup → 84 KIs stored" />
<em>Extraction pipeline: biased document sampling feeds a parallel LLM pass and four deterministic generators. Results are merged and deduplicated before storage.</em></p>
<p>Once sampled, the documents are sent to an LLM. We use a system prompt that instructs the model to identify a few specific types of features, which we plan to extend over time:</p>
<p>| Type | What it captures |
|------|------------------|
| Entity | Distinct system components: services, applications, jobs |
| Infrastructure | Environment context: Kubernetes, cloud provider, OS |
| Technology | Languages, frameworks, libraries, databases |
| Dependency | Relationships between components |
| Schema | Log format conventions: ECS, OTel, custom |</p>
<p>The LLM returns its findings, delivering newly identified traits alongside any intentionally ignored ones (like user-excluded false positives). To be accepted, every feature must include stable identifying properties and cite direct evidence from the sampled logs. The LLM also assigns a confidence score from 0–100 for each KI, so any downstream use of that KI knows how much to trust it.</p>
<p>In parallel, a set of deterministic code-based generators independently analyze the data to produce statistical summaries, log samples, pattern clusters, and error-specific features. Because these are computed rather than inferred, they always receive a confidence score of 100.</p>
<p>Finally, the LLM results and computed features are merged and deduplicated. Known KIs reuse their existing UUIDs, new discoveries get fresh ones, and any user-excluded features are quietly dropped server-side. Surviving KIs are saved with an active status and an expiration date set for seven days out.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1aefe63628f536ce/6a7f07c9fc63ab916364ca61/kis.png" alt="Knowledge Indicators tab showing 84 KIs across streams, with type, confidence (1–5 stars), and stream columns visible" />
<em>Knowledge Indicators tab showing 84 KIs across streams, with type, confidence (1–5 stars), and stream columns.</em></p>
<h2 id="whataknowledgeindicatorcontains">What a Knowledge Indicator Contains</h2>
<p>Knowledge Indicators fall into two categories: Feature KIs and Query KIs.</p>
<p>Feature KIs are descriptive. They explain the contents of the stream: what services are running, the infrastructure housing them, their dependencies, and the active tech stack.</p>
<p>Query KIs are actionable. They are ready-to-run ES|QL queries targeting notable conditions like connection exhaustion, out-of-memory errors, or fatal exceptions. Each comes with a severity score from 0 to 100, and when promoted to Rules, they fire Events.</p>
<p>Feature KIs carry a full data model:</p>
<ul>
<li><strong><code>type</code> / <code>subtype</code></strong>: the category of the fact (Entity, Infrastructure, Technology, Dependency, Schema)</li>
<li><strong><code>title</code> / <code>description</code></strong>: a human-readable summary</li>
<li><strong><code>properties</code></strong>: stable key-value pairs used to deduplicate findings across multiple runs</li>
<li><strong><code>confidence</code></strong>: 0–100. LLM-identified KIs score based on evidence quality. Deterministic KIs always score 100.</li>
<li><strong><code>evidence</code></strong>: 2–5 supporting log excerpts that justify the KI's existence</li>
<li><strong><code>filter</code></strong>: an optional StreamLang condition scoping the KI to specific documents</li>
</ul>
<p>A dependency KI looks like this:</p>
<pre><code>{
  "type": "dependency",
  "subtype": "service_dependency",
  "title": "api_gateway → inference_service",
  "description": "Service-to-service HTTP dependency from api_gateway to inference_service, observed in request logs",
  "properties": {
    "source": "api_gateway",
    "target": "inference_service",
    "protocol": "http"
  },
  "confidence": 85,
  "evidence": [
    "service.name=api_gateway http.url=/v1/inference peer.service=inference_service",
    "upstream=inference_service:8080 request=POST /v1/inference 200"
  ],
  "filter": { "field": "service.name", "eq": "api_gateway" },
  "status": "active",
  "expires_at": "2026-04-09T00:00:00Z"
}
</code></pre>
<p>Query KIs take a simpler shape, focusing solely on the title, severity score, and the executable query:</p>
<pre><code>{
  "kind": "query",
  "title": "PostgreSQL connection slot exhaustion",
  "description": "Fires when Postgres runs out of available connection slots",
  "severity_score": 90,
  "esql": {
    "query": "FROM logs-* | WHERE service.name == \"postgres\" AND message : \"remaining connection slots\""
  }
}
</code></pre>
<p>The <code>properties</code> field is what keeps Feature KIs stable across multiple pipeline runs. The dependency KI for <code>api_gateway → inference_service</code> records the source, target, and protocol as fixed pairs. The next time extraction runs, Elastic recognizes this existing relationship and updates the KI's <code>last_seen</code> timestamp rather than creating a duplicate.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcf99c981e914aefc/6a7f07cc6693f89c62663d5b/ki-detail.png" alt="KI detail panel for api_gateway → inference_service showing type, subtype, properties, confidence, evidence, and expiry date" />
<em>KI detail panel showing type, subtype, properties, confidence, evidence, and expiry date for a service dependency.</em></p>
<h2 id="thefoundationforintelligentobservability">The Foundation for Intelligent Observability</h2>
<p>So what can we do with all of this? These KIs serve as the contextual foundation for Elastic's more advanced capabilities. From just these extracted KIs, we can automatically generate active Rules to surface interesting signals, without a human engineer writing a single line of configuration. More on this particular capability in the next post in this series.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2ab47e653ddc6683/6a7f07d01967eada7c330527/queries.png" alt="85 auto-generated Rules from KIs with impact ratings (Critical/High) and event occurrence sparklines" />
<em>85 auto-generated Rules from 84 KIs, with impact ratings and event occurrence sparklines.</em></p>
<p>As a user or an agent, the dependency KIs automatically construct an infrastructure graph—inferred entirely from log data, not from distributed tracing or any manual configuration. During an incident, this graph is invaluable for assessing blast radius. If a specific database goes down, the topology map immediately shows you exactly which upstream services are about to fail, without maintaining a manual service catalog.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb87332c1b105dd39/6a7f07d373d9bd5d0b29d946/topology-dependencies@2x.png" alt="Topology graph showing service dependencies: claim-intake connects to claim-intake-db (PostgreSQL), fraud-check, policy-lookup; fraud-check connects to fraud-check-db (MongoDB); policy-lookup connects to policy-lookup-db (PostgreSQL); payment-processor and kafka grouped separately; notification-dispatch and kubernetes at bottom" />
<em>Service dependency graph extracted from KIs, showing services, databases, and infrastructure components.</em></p>
<p>This context changes how an AI agent handles an incident. Instead of starting from scratch, the agent initiates its investigation using your system's actual topology and known failure modes. Based on the KIs, it identifies the relevant streams, runs the applicable queries, and formulates a specific hypothesis. In our example, it already knows that <code>api_gateway</code> relies on <code>inference_service</code>, and it knows that connection slot exhaustion is a high-severity failure mode for your Postgres instance.</p>
<p>This extracted knowledge doesn't have to be perfect to be useful. Because LLMs are inherently non-deterministic, a KI might occasionally be slightly off, but it still gives the agent a significant head start. The agent can cross-reference the KI against live logs and self-correct on the fly. The real benefit is simply not having to reconstruct basic facts during a critical outage. KIs also drive AI-generated dashboard suggestions and inform Grok pattern generation whenever you introduce new streams.</p>
<h2 id="selfcleaningandscalable">Self-Cleaning and Scalable</h2>
<p>Maintaining this knowledge base is entirely hands-off. KIs auto-expire after 7 days if they aren't observed in subsequent extraction runs. If you decommission a service, its associated KIs simply fade away without any manual cleanup. If the service comes back online later, the KIs are re-extracted. Users can also mark individual feature KIs as false positives, and the system carries those exclusions forward into future runs to prevent re-identification.</p>
<p>Because we scoped KI extraction as a specific classification task, looking at around 20 log samples to identify services, infrastructure, and dependencies, it doesn't require a large frontier model to run. A fast, cost-effective model handles this without multi-step reasoning.</p>
<h2 id="youshouldnthavetotellyourtoolswhattowatch">You Shouldn't Have to Tell Your Tools What to Watch</h2>
<p>The fundamental promise of observability is to help you understand your systems. For far too long, the burden of teaching the tool how those systems actually work has fallen on the engineers operating them.</p>
<p>The next post in this series looks at what agents do with that context: why every agent that investigates your system without KIs re-learns the same things from scratch on every incident, and what changes when it doesn't have to.</p>
<p><strong>NOTE:</strong> These capabilities are available behind a feature flag in Serverless Observability projects. Turn on <code>observability:streamsEnableSignificantEvents</code> by searching for it in the Kibana advanced settings page. </p>
<h2 id="frequentlyaskedquestions">Frequently asked questions</h2>
<p><strong>What are Knowledge Indicators in Elasticsearch Streams?</strong>
Knowledge Indicators (KIs) are structured facts extracted from raw log streams: service names, infrastructure components, service-to-service dependencies, and tech stack details. Elastic extracts them automatically by sampling log lines, without requiring schemas, service catalogs, or manual configuration.</p>
<p><strong>How does Elastic build a service topology map from logs alone?</strong>
The extraction pipeline samples log lines and identifies dependency relationships, such as an outbound HTTP call from one service to another. These dependency KIs are used to construct a topology graph that shows which services depend on which, entirely inferred from log data, without distributed tracing or any manual input.</p>
<p><strong>Why does an AI agent need Knowledge Indicators before investigating an incident?</strong>
Without KIs, an AI agent starts every investigation from scratch: it has to read hundreds of log lines just to establish which services exist and how they relate. KIs give the agent a pre-built map of your system, including services, known failure modes, and relevant queries, so it can begin reasoning about the actual incident immediately.</p>
<p><strong>Do I need to configure anything for Knowledge Indicator extraction to work?</strong>
No. The pipeline requires no schema definitions, no service catalog, and no predefined rules. It samples a small set of log lines from a stream, analyzes them through a combination of LLM inference and deterministic generators, and accumulates findings automatically.</p>
<p><strong>How accurate are LLM-extracted KIs compared to computed ones?</strong>
Computed (deterministic) KIs always receive a confidence score of 100 because they are derived from statistical analysis rather than inference. LLM-extracted KIs receive scores from 0 to 100 based on the quality of evidence found in the sampled logs. Rules, agent investigations, and topology maps can all use this score to weight their decisions.</p>
<p><strong>What happens when a service is decommissioned?</strong>
KIs carry a 7-day expiration. If a service stops appearing in subsequent extraction runs, its KIs expire and are removed automatically. No manual cleanup required. If the service comes back, the KIs are re-extracted on the next run.</p>
<p><strong>How does this compare to service discovery via distributed tracing?</strong>
Distributed tracing requires instrumented services and a trace collector. Knowledge Indicator extraction requires nothing beyond existing log streams: no SDK, no agent, no schema. For environments with partial or no tracing coverage, KI extraction provides topology and dependency information that tracing would otherwise miss.</p>]]></content:encoded>
    <link>https://www.elastic.co/observability-labs/blog/elastic-knowledge-indicators-log-extraction</link>
    <guid isPermaLink="false">elastic-knowledge-indicators-log-extraction</guid>
    <category><![CDATA[Machine Learning]]></category>
    <category><![CDATA[Logs Analytics]]></category>
    <dc:creator><![CDATA[Luca Wintergerst]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4563c156c7dfcd41/6a7f07d66c6eac3466f13f0b/cover.png" length="0" type="image/png"/>
    <pubDate>Tue, 05 May 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[The next evolution of observability: unifying data with OpenTelemetry and generative AI]]></title>
    <description><![CDATA[Generative AI and machine learning are revolutionizing observability, but siloed data hinders their true potential. This article explores how to break down data silos by unifying logs, metrics, and traces with OpenTelemetry, unlocking the full power of GenAI for natural language investigations, automated root cause analysis, and proactive issue resolution.]]></description>
    <content:encoded><![CDATA[<p>The Observability industry today stands at a critical juncture. While our applications generate more telemetry data than ever before, this wealth of information typically exists in siloed tools, separate systems for logs, metrics, and traces. Meanwhile, Generative AI is hurtling toward us like an asteroid about to make a tremendous impact on our industry.</p>
<p>As SREs, we've grown accustomed to jumping between dashboards, log aggregators, and trace visualizers when troubleshooting issues. But what if there was a better way? What if AI could analyze all your observability data holistically, answering complex questions in natural language, and identifying root causes automatically?</p>
<p>This is the next evolution of observability. But to harness this power, we need to rethink how we collect, store, and analyze our telemetry data.</p>
<h2 id="theproblemsiloeddatalimitsaieffectiveness">The problem: siloed data limits AI effectiveness</h2>
<p>Traditional observability setups separate data into distinct types:</p>
<ul>
<li>Metrics: Numeric measurements over time (CPU, memory, request rates)</li>
<li>Logs: Detailed event records with timestamps and context</li>
<li>Traces: Request journeys through distributed systems</li>
<li>Profiles: Code-level execution patterns showing resource consumption and performance bottlenecks at the function/line level</li>
</ul>
<p>This separation made sense historically due to the way the industry evolved. Different data types have traditionally had different cardinality, structure, access patterns and volume characteristics. However, this approach creates significant challenges for AI-powered analysis:</p>
<pre><code>Metrics (Prometheus) → "CPU spiked at 09:17:00"
Logs (ELK) → "Exception in checkout service at 09:17:32" 
Traces (Jaeger) → "Slow DB queries in order-service at 09:17:28"
Profiles (pyroscope) -&gt; "calculate_discount() is taking 75% of CPU time"
</code></pre>
<p>When these data sources live in separate systems, AI tools must either:</p>
<ol>
<li>Work with an incomplete picture (seeing only metrics but not the related logs)</li>
<li>Rely on complex, brittle integrations that often introduce timing skew</li>
<li>Force developers to manually correlate information across tools</li>
</ol>
<p>Imagine asking an AI, "Why did checkout latency spike at 09:17?" To answer comprehensively, it needs access to logs (to see the stack trace), traces (to understand the service path), and metrics (to identify resource strain). With siloed tools, the AI either sees only fragments of the story or requires complex ETL jobs that are slower than the incident itself.</p>
<h2 id="whytraditionalmachinelearningmlfallsshort">Why traditional machine learning (ML) falls short</h2>
<p>Traditional machine learning for observability typically focuses on anomaly detection within a single data dimension. It can tell you when metrics deviate from normal patterns, but struggles to provide context or root cause.</p>
<p>ML models trained on metrics alone might flag a latency spike, but can't connect it to a recent deployment (found in logs) or identify that it only affects requests to a specific database endpoint (found in traces). They behave like humans with extreme tunnel vision, seeing only a fraction of the relevant information and only the information that a specific vendor has given you an opinionated view into.</p>
<p>This limitation becomes particularly problematic in modern microservice architectures where problems frequently cascade across services. Without a unified view, traditional ML can detect symptoms but struggles to identify the underlying cause.</p>
<h2 id="thesolutionunifieddatawithenrichedlogs">The solution: unified data with enriched logs</h2>
<p>The solution is conceptually simple but transformative: unify metrics, logs, and traces into a single data store, ideally with enriched logs that contain all signals about a request in a single JSON document. We're about to see a merging of signals.</p>
<p>Think of traditional logs as simple text lines:</p>
<pre><code>[2025-05-19 09:17:32] ERROR OrderService - Failed to process checkout for user 12345
</code></pre>
<p>Now imagine an enriched log that contains not just the error message, but also:</p>
<ul>
<li>The complete distributed trace context</li>
<li>Related metrics at that moment</li>
<li>System environment details</li>
<li>Business context (user ID, cart value, etc.)</li>
</ul>
<p>This approach creates a holistic view where every signal about the same event sits side-by-side, perfect for AI analysis.</p>
<h2 id="howgenerativeaichangesthings">How generative AI changes things</h2>
<p>Generative AI differs fundamentally from traditional ML in its ability to:</p>
<ol>
<li>Process unstructured data: Understanding free-form log messages and error text</li>
<li>Maintain context: Connecting related events across time and services</li>
<li>Answer natural language queries: Translating human questions into complex data analysis</li>
<li>Generate explanations: Providing reasoning alongside conclusions</li>
<li>Surface hidden patterns: Discovering correlations and anomalies in log data that would be impractical to find through manual analysis or traditional querying</li>
</ol>
<p>With access to unified observability data, GenAI can analyze complete system behavior patterns and correlate across previously disconnected signals.</p>
<p>For example, when asked "Why is our checkout service slow?" a GenAI model with access to unified data can:</p>
<ul>
<li>Analyze unified enriched logs to identify which specific operations are slow and to find errors or warnings in those components</li>
<li>Check attached metrics to understand resource utilization</li>
<li>Correlate all these signals with deployment events or configuration changes</li>
<li>Present a coherent explanation in natural language with supporting graphs and visualizations</li>
</ul>
<h2 id="implementingunifiedobservabilitywithopentelemetry">Implementing unified observability with OpenTelemetry</h2>
<p>OpenTelemetry provides the perfect foundation for unified observability with its consistent schema across metrics, logs, and traces. Here's how to implement enriched logs in a Java application:</p>
<pre><code>import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;

public class OrderProcessor {
    private static final Logger logger = LoggerFactory.getLogger(OrderProcessor.class);
    private final Tracer tracer;
    private final DoubleHistogram cpuUsageHistogram;
    private final OperatingSystemMXBean osBean;

    public OrderProcessor(OpenTelemetry openTelemetry) {
        this.tracer = openTelemetry.getTracer("order-processor");
        Meter meter = openTelemetry.getMeter("order-processor");
        this.cpuUsageHistogram = meter.histogramBuilder("system.cpu.load")
                                      .setDescription("System CPU load")
                                      .setUnit("1")
                                      .build();
        this.osBean = ManagementFactory.getOperatingSystemMXBean();
    }

    public void processOrder(String orderId, double amount, String userId) {
        Span span = tracer.spanBuilder("processOrder").startSpan();
        try (Scope scope = span.makeCurrent()) {
            // Add attributes to the span
            span.setAttribute("order.id", orderId);
            span.setAttribute("order.amount", amount);
            span.setAttribute("user.id", userId);
            // Populate MDC for structured logging
            MDC.put("trace_id", span.getSpanContext().getTraceId());
            MDC.put("span_id", span.getSpanContext().getSpanId());
            MDC.put("order_id", orderId);
            MDC.put("order_amount", String.valueOf(amount));
            MDC.put("user_id", userId);
            // Record CPU usage metric associated with the current trace context
            double cpuLoad = osBean.getSystemLoadAverage();
            if (cpuLoad &gt;= 0) {
                cpuUsageHistogram.record(cpuLoad);
                MDC.put("cpu_load", String.valueOf(cpuLoad));
            }
            // Log a structured message
            logger.info("Processing order");
            // Simulate business logic
            // ...
            span.setAttribute("order.status", "completed");
            logger.info("Order processed successfully");
        } catch (Exception e) {
            span.recordException(e);
            span.setAttribute("order.status", "failed");
            logger.error("Order processing failed", e);
        } finally {
            MDC.clear();
            span.end();
        }
    }
}
</code></pre>
<p>This code demonstrates how to:</p>
<ol>
<li>Create a span for the operation</li>
<li>Add business attributes</li>
<li>Add current CPU usage</li>
<li>Link everything with consistent IDs</li>
<li>Record exceptions and outcomes in the backend system</li>
</ol>
<p>When configured with an appropriate exporter, this creates enriched logs that contain both application events and their complete context.</p>
<h2 id="powerfulqueriesacrosspreviouslyseparatedata">Powerful queries across previously separate data</h2>
<p>With data that has not yet been enriched, there is still hope. Firstly with GenAI powered ingestion it is possible to extract key fields to help correlate data such as a session id's. This will help you enrich your logs so they get the structure they need to behave like other signals. Below we can see Elastic's Auto Import mechanism that will automatically generate ingest pipelines and pull unstructured information from logs into a structured format perfect for analytics.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt49ea53cd2cb13c82/6a7f1b8cea068d2deaf0a2df/image4.png" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt51470fc777215fdd/6a7f1b8f6c6eac7075f145bd/image2.png" alt="" /></p>
<p>Once you have this data in the same data store, you can perform powerful join queries that were previously impossible. For example, finding slow database queries that affected specific API endpoints:</p>
<pre><code>FROM logs-nginx.access-default 
| LOOKUP JOIN .ds-logs-mysql.slowlog-default-2025.05.01-000002 ON request_id 
| KEEP request_id, mysql.slowlog.query, url.query 
| WHERE mysql.slowlog.query IS NOT NULL
</code></pre>
<p>This query joins web server logs with database slow query logs, allowing you to directly correlate user-facing performance with database operations.</p>
<p>For GenAI interfaces, these complex queries can be generated automatically from natural language questions:</p>
<p>"Show me all checkout failures that coincided with slow database queries"</p>
<p>The AI translates this into appropriate queries across your unified data store, correlating application errors with database performance.</p>
<h2 id="realworldapplicationsandusecases">Real-world applications and use cases</h2>
<h3 id="naturallanguageinvestigation">Natural language investigation</h3>
<p>Imagine asking your observability system:</p>
<p>"Why did checkout latency spike at 09:17 yesterday?"</p>
<p>A GenAI-powered system with unified data could respond:</p>
<p>"Checkout latency increased by 230% at 09:17:32 following deployment v2.4.1 at 09:15. The root cause appears to be increased MySQL query times in the inventory-service. Specifically, queries to the 'product_availability' table are taking an average of 2300ms compared to the normal 95ms. This coincides with a CPU spike on database host db-03 and 24 'Lock wait timeout' errors in the inventory service logs."</p>
<p>Here's an example of Claude Desktop connected to <a href="https://github.com/elastic/mcp-server-elasticsearch">Elastic's MCP (Model Context Protocol) Server</a> which demonstrates how powerful natural language investigations can be. Here we ask Claude "analyze my web traffic patterns" and as you can see it has correctly identified that this is in our demo environment.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5f22b476cc3e5cb4/6a7f1b9263e959e91b73e281/image3.png" alt="" /></p>
<h3 id="unknownproblemdetection">Unknown problem detection</h3>
<p>GenAI can identify subtle patterns by correlating signals that would be missed in siloed systems. For example, it might notice that a specific customer ID appears in error logs only when a particular network path is taken through your microservices—indicating a data corruption issue affecting only certain user flows.</p>
<h3 id="predictivemaintenance">Predictive maintenance</h3>
<p>By analyzing the unified historical patterns leading up to previous incidents, GenAI can identify emerging problems before they cause outages:</p>
<p>"Warning: Current load pattern on authentication-service combined with increasing error rates in user-profile-service matches 87% of the signature that preceded the April 3rd outage. Recommend scaling user-profile-service pods immediately."</p>
<h2 id="thefutureagenticaiforobservability">The future: agentic AI for observability</h2>
<p>The next frontier is agentic AI, systems that not only analyze but take action automatically.</p>
<p>These AI agents could:</p>
<ol>
<li>Continuously monitor all observability signals</li>
<li>Autonomously investigate anomalies</li>
<li>Implement fixes for known patterns</li>
<li>Learn from the effectiveness of previous interventions</li>
</ol>
<p>For example, an observability agent might:</p>
<ul>
<li>Detect increased error rates in a service</li>
<li>Analyze logs and traces to identify a memory leak</li>
<li>Correlate with recent code changes</li>
<li>Increase the memory limit temporarily</li>
<li>Create a detailed ticket with the root cause analysis</li>
<li>Monitor the fix effectiveness</li>
</ul>
<p>This is about creating systems that understand your application's behavior patterns deeply enough to maintain them proactively. See how this works in Elastic Observability, in the screenshot at the end of the RCA we are sending an email summary but this could trigger any action.  </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7066e2bb8f06113/6a7f1b959090b0011b84ee37/image1.png" alt="" /></p>
<h2 id="businessoutcomes">Business outcomes</h2>
<p>Unifying observability data for GenAI analysis delivers concrete benefits:</p>
<ul>
<li>Faster resolution times: Problems that previously required hours of manual correlation can be diagnosed in seconds</li>
<li>Fewer escalations: Junior engineers can leverage AI to investigate complex issues before involving specialists</li>
<li>Improved system reliability: Earlier detection and resolution of emerging issues</li>
<li>Better developer experience: Less time spent context-switching between tools</li>
<li>Enhanced capacity planning: More accurate prediction of resource needs</li>
</ul>
<h2 id="implementationsteps">Implementation steps</h2>
<p>Ready to start your observability transformation? Here's a practical roadmap:</p>
<ol>
<li>Adopt OpenTelemetry: Standardize on OpenTelemetry for all telemetry data collection and use it to generate enriched logs.</li>
<li>Choose a unified storage solution: Select a platform that can efficiently store and query metrics, logs, traces and enriched logs together</li>
<li>Enrich your telemetry: Update application instrumentation to include relevant context</li>
<li>Create correlation IDs: Ensure every request has identifiers</li>
<li>Implement semantic conventions: Follow consistent naming patterns across your telemetry data</li>
<li>Start with focused use cases: Begin with high-value scenarios like checkout flows or critical APIs</li>
<li>Leverage GenAI tools: Integrate tools that can analyze your unified data and respond to natural language queries</li>
</ol>
<p>Remember, AI can only be as smart as the data you feed it. The quality and completeness of your telemetry data will determine the effectiveness of your AI-powered observability.</p>
<h2 id="generativeaianevolutionarycatalystforobservability">Generative AI: an evolutionary catalyst for observability</h2>
<p>The unification of observability data for GenAI analysis represents an evolutionary leap forward comparable to the transition from Internet 1.0 to 2.0. Early adopters will gain a significant competitive advantage through faster problem resolution, improved system reliability, and more efficient operations. GAI is a huge step for increasing observability maturity and moving your team to a more proactive stance.</p>
<p>Think of traditional observability as a doctor trying to diagnose a patient while only able to see their heart rate. Unified observability with GenAI is like giving that doctor a complete health picture, vital signs, lab results, medical history, and genetic data all accessible through natural conversation.</p>
<p>As SREs, we stand at the threshold of a new era in system observability. The asteroid of GenAI isn't a threat to be feared, it's an opportunity to evolve our practices and tools to build more reliable, understandable systems. The question isn't whether this transformation will happen, but who will lead it.</p>
<p>Will you?</p>]]></content:encoded>
    <link>https://www.elastic.co/observability-labs/blog/the-next-evolution-of-observability-unifying-data-with-opentelemetry-and-generative-ai</link>
    <guid isPermaLink="false">the-next-evolution-of-observability-unifying-data-with-opentelemetry-and-generative-ai</guid>
    <category><![CDATA[OpenTelemetry]]></category>
    <category><![CDATA[Agentic Observability]]></category>
    <category><![CDATA[Machine Learning]]></category>
    <dc:creator><![CDATA[David Hope]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltccc14cece0d58b74/6a7f1b99bdcff0587cc432c3/title.png" length="0" type="image/png"/>
    <pubDate>Wed, 11 Jun 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[How to remove PII from your Elastic data in 3 easy steps]]></title>
    <description><![CDATA[Personally Identifiable Information compliance is an ever increasing challenge for any organization. With Elastic's intuitive ML interface and parsing capabilities, sensitive data may be easily redacted from unstructured data with ease.]]></description>
    <content:encoded><![CDATA[<p>Personally identifiable information (PII) compliance is an ever-increasing challenge for any organization. Whether you’re in ecommerce, banking, healthcare, or other fields where data is sensitive, PII may inadvertently be captured and stored. Having structured logs enables quick identification, removal, and protection of sensitive data fields easily; but what about unstructured messages? Or perhaps call center transcriptions?</p>
<p>Elasticsearch, with its long experience in <a href="https://www.elastic.co/what-is/elasticsearch-machine-learning">machine learning</a>, provides various options to bring in custom models, such as large language models (LLMs), and provides its own models. These models will help implement PII redaction.</p>
<p>If you would like to learn more about natural language processing, machine learning, and Elastic, please be sure to check out these related articles:</p>
<ul>
<li><a href="https://www.elastic.co/blog/introduction-to-nlp-with-pytorch-models">Introduction to modern natural language processing with PyTorch in Elasticsearch</a></li>
<li><a href="https://www.elastic.co/blog/how-to-deploy-natural-language-processing-nlp-getting-started">How to deploy natural language processing (NLP): Getting started</a></li>
<li><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/redact-processor.html">Elastic Redact Processor Documentation</a></li>
<li><a href="https://www.elastic.co/blog/may-2023-launch-sparse-encoder-ai-model">Introducing Elastic Learned Sparse Encoder: Elastic’s AI model for semantic search</a></li>
<li><a href="https://www.elastic.co/blog/may-2023-launch-machine-learning-models">Accessing machine learning models in Elastic</a></li>
</ul>
<p>In this blog, we will show you how to set up PII redaction through the use of Elasticsearch’s ability to load a trained model within machine learning and the flexibility of Elastic’s ingest pipelines.</p>
<p>Specifically, we’ll walk through setting up a <a href="https://www.elastic.co/blog/how-to-deploy-nlp-named-entity-recognition-ner-example">named entity recognition (NER)</a> model for person and location identification, as well as deploying the redact processor for custom data identification and removal. All of this will then be combined with an ingest pipeline where we can use Elastic machine learning and data transformations capabilities to remove sensitive information from your data.</p>
<h2 id="loadingthetrainedmodel">Loading the trained model</h2>
<p>Before we begin, we must load our NER model into our Elasticsearch cluster. This may be easily accomplished with Docker and the Elastic Eland client. From a command line, let’s install the Eland client via git:</p>
<pre><code>git clone https://github.com/elastic/eland.git
</code></pre>
<p>Navigate into the recently downloaded client:</p>
<pre><code>cd eland/
</code></pre>
<p>Now let’s build the client:</p>
<pre><code>docker build -t elastic/eland .
</code></pre>
<p>From here, you’re ready to deploy the trained model to an Elastic machine learning node! Be sure to replace your username, password, es-cluster-hostname, and esport.</p>
<p>If you’re using the Elastic Cloud or have signed certificates, simply run this command:</p>
<pre><code>docker run -it --rm --network host elastic/eland eland_import_hub_model --url https://&lt;username&gt;:&lt;password&gt;@&lt;es-cluster-hostname&gt;:&lt;esport&gt;/ --hub-model-id dslim/bert-base-NER --task-type ner --start
</code></pre>
<p>If you’re using self-signed certificates, run this command:</p>
<pre><code>docker run -it --rm --network host elastic/eland eland_import_hub_model --url https://&lt;username&gt;:&lt;password&gt;@&lt;es-cluster-hostname&gt;:&lt;esport&gt;/ --insecure --hub-model-id dslim/bert-base-NER --task-type ner --start
</code></pre>
<p>From here you’ll witness the Eland client in action downloading the trained model from <a href="https://huggingface.co/dslim/bert-base-NER">HuggingFace</a> and automatically deploying it into your cluster!</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc3119d4a20e0f93b/6a85cbd42d64d567c3081d56/blog-elastic-huggingface.png" alt="huggingface code" /></p>
<p>Synchronize your newly loaded trained model by clicking on the blue hyperlink via your Machine Learning Overview UI “Synchronize your jobs and trained models.”</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt256411b1a03cb158/6a85cbd79bf99435330a058b/blog-elastic-Machine-Learning-Overview-UI.png" alt="Machine Learning Overview UI" /></p>
<p>Now click the Synchronize button.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt64d1464700830d19/6a85cbdaf5f1a0f0572ec913/blog-elastic-Synchronize-button.png" alt="Synchronize button" /></p>
<p>That’s it! Congratulations, you just loaded your first trained model into Elastic!</p>
<h2 id="createtheredactprocessorandingestpipeline">Create the redact processor and ingest pipeline</h2>
<p>From DevTools, let’s configure the redact processor along with our inference processor to take advantage of Elastic’s trained model we just loaded. This will create an ingest pipeline named “redact” that we can then use to remove sensitive data from any field we wish. In this example, I’ll be focusing on the “message” field. Note: at the time of this writing, the redact processor is experimental and must be created via DevTools.</p>
<pre><code>PUT _ingest/pipeline/redact
{
  "processors": [
    {
      "set": {
        "field": "redacted",
        "value": "{{{message}}}"
      }
    },
    {
      "inference": {
        "model_id": "dslim__bert-base-ner",
        "field_map": {
          "message": "text_field"
        }
      }
    },
    {
      "script": {
        "lang": "painless",
        "source": "String msg = ctx['message'];\r\n                for (item in ctx['ml']['inference']['entities']) {\r\n                msg = msg.replace(item['entity'], '&lt;' + item['class_name'] + '&gt;')\r\n                }\r\n                ctx['redacted']=msg"
      }
    },
    {
      "redact": {
        "field": "redacted",
        "patterns": [
          "%{EMAILADDRESS:EMAIL}",
          "%{IP:IP_ADDRESS}",
          "%{CREDIT_CARD:CREDIT_CARD}",
          "%{SSN:SSN}",
          "%{PHONE:PHONE}"
        ],
        "pattern_definitions": {
          "CREDIT_CARD": "\d{4}[ -]\d{4}[ -]\d{4}[ -]\d{4}",
          "SSN": "\d{3}-\d{2}-\d{4}",
          "PHONE": "\d{3}-\d{3}-\d{4}"
        }
      }
    },
    {
      "remove": {
        "field": [
          "ml"
        ],
        "ignore_missing": true,
        "ignore_failure": true
      }
    }
  ],
  "on_failure": [
    {
      "set": {
        "field": "failure",
        "value": "pii_script-redact"
      }
    }
  ]
}
</code></pre>
<p>OK, but what does each processor really do? Let’s walk through each processor in detail here:</p>
<ol>
<li><p>The SET processor creates the field “redacted,” which is copied over from the message field and used later on in the pipeline.</p></li>
<li><p>The INFERENCE processor calls the NER model we loaded to be used on the message field for identifying names, locations, and organizations.</p></li>
<li><p>The SCRIPT processor then replaced the detected entities within the redacted field from the message field.</p></li>
<li><p>Our REDACT processor uses Grok patterns to identify any custom set of data we wish to remove from the redacted field (which was copied over from the message field).</p></li>
<li><p>The REMOVE processor deletes the extraneous ml.* fields from being indexed; note we’ll add “message” to this processor once we validate data is being redacted properly.</p></li>
<li><p>The ON_FAILURE / SET processor captures any errors just in case we have them.</p></li>
</ol>
<h2 id="sliceyourpii">Slice your PII</h2>
<p>Now that your ingest pipeline with all the necessary steps has been configured, let’s start testing how well we can remove sensitive data from documents. Navigate over to Stack Management, select Ingest Pipelines and search for “redact”, and then click on the result.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6bd72fd29bb2e13f/6a85cbdd99083fc49740f9e9/blog-elastic-Ingest-Pipelines.png" alt="Ingest Pipelines" /></p>
<p>Click on the Manage button, and then click Edit.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd714b5ef2f5d9084/6a85cbe0d7b2e7851afe84f8/elastic-blog-Manage-button.png" alt="Manage button" /></p>
<p>Here we are going to test our pipeline by adding some documents. Below is a sample you can copy and paste to make sure everything is working correctly.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt69df37d4e0e10869/6a85cbe38c294460d1b89053/elastic-blog-test-pipeline.png" alt="test pipeline" /></p>
<pre><code>{
  "_source":
    {
      "message": "John Smith lives at 123 Main St. Highland Park, CO. His email address is jsmith123@email.com and his phone number is 412-189-9043.  I found his social security number, it is 942-00-1243. Oh btw, his credit card is 1324-8374-0978-2819 and his gateway IP is 192.168.1.2",
    },
}
</code></pre>
<p>Simply press the Run the pipeline button, and you will then see the following output:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7201f608fe3ec634/6a85cbe6e2447a1a268b1416/elastic-blog-pii-output-2.png" alt="pii output code" /></p>
<h2 id="whatsnext">What’s next?</h2>
<p>After you’ve added this ingest pipeline to a data set you’re indexing and validated that it is meeting expectations, you can add the message field to be removed so that no PII data is indexed. Simply update your REMOVE processor to include the message field and simulate again to only see the redacted field.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6d25ef9a7322cf6d/6a85cbe843c0b7af1c2f062c/elastic-blog-manage-processor.png" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt45b3b0c93aec9c67/6a85cbeb43c0b735952f0634/elastic-blog-pii-output.png" alt="pii output code 2" /></p>
<h2 id="conclusion">Conclusion</h2>
<p>With this step-by-step approach, you are now ready and able to detect and redact any sensitive data throughout your indices.</p>
<p>Here’s a quick recap of what we covered:</p>
<ul>
<li>Loading a pre-trained named entity recognition model into an Elastic cluster</li>
<li>Configuring the Redact processor, along with the inference processor, to use the trained model during data ingestion</li>
<li>Testing sample data and modifying the ingest pipeline to safely remove personally identifiable information</li>
</ul>
<p>Ready to get started? Sign up <a href="https://cloud.elastic.co/registration">for Elastic Cloud</a> and try out the features and capabilities I’ve outlined above to get the most value and visibility out of your OpenTelemetry data.</p>
<p><em>The release and timing of any features or functionality described in this post remain at Elastic's sole discretion. Any features or functionality not currently available may not be delivered on time or at all.</em></p>
<p><em>In this blog post, we may have used third party generative AI tools, which are owned and operated by their respective owners. Elastic does not have any control over the third party tools and we have no responsibility or liability for their content, operation or use, nor for any loss or damage that may arise from your use of such tools. Please exercise caution when using AI tools with personal, sensitive or confidential information. Any data you submit may be used for AI training or other purposes. There is no guarantee that information you provide will be kept secure or confidential. You should familiarize yourself with the privacy practices and terms of use of any generative AI tools prior to use.</em></p>
<p><em>Elastic, Elasticsearch and associated marks are trademarks, logos or registered trademarks of Elasticsearch N.V. in the United States and other countries. All other company and product names are trademarks, logos or registered trademarks of their respective owners.</em></p>]]></content:encoded>
    <link>https://www.elastic.co/observability-labs/blog/remove-pii-data</link>
    <guid isPermaLink="false">remove-pii-data</guid>
    <category><![CDATA[Logs Analytics]]></category>
    <category><![CDATA[Machine Learning]]></category>
    <dc:creator><![CDATA[Peter Titov]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt37a52bf6a3c1aab8/6a85cbee0782904fd0321786/blog-post4-ai-search-B.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 20 Jun 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Root cause analysis with logs: Elastic Observability's anomaly detection and log categorization]]></title>
    <description><![CDATA[Elastic Observability provides more than just log aggregation, metrics analysis, APM, and distributed tracing. Elastic’s machine learning capabilities help analyze the root cause of issues, allowing you to focus your time on the most important tasks.]]></description>
    <content:encoded><![CDATA[<p>With more and more applications moving to the cloud, an increasing amount of telemetry data (logs, metrics, traces) is being collected, which can help improve application performance, operational efficiencies, and business KPIs. However, analyzing this data is extremely tedious and time consuming given the tremendous amounts of data being generated. Traditional methods of alerting and simple pattern matching (visual or simple searching etc) are not sufficient for IT Operations teams and SREs. It’s like trying to find a needle in a haystack.</p>
<p>In this blog post, we’ll cover some of Elastic’s artificial intelligence for IT operations (AIOps) and machine learning (ML) capabilities for root cause analysis.</p>
<p>Elastic’s machine learning will help you investigate performance issues by providing anomaly detection and pinpointing potential root causes through time series analysis and log outlier detection. These capabilities will help you reduce time in finding that “needle” in the haystack.</p>
<p>Elastic’s platform enables you to get started on machine learning quickly. You don’t need to have a data science team or design a system architecture. Additionally, there’s no need to move data to a third-party framework for model training.</p>
<p>Preconfigured machine learning models for observability and security are available. If those don't work well enough on your data, in-tool wizards guide you through the few steps needed to configure custom anomaly detection and train your model with supervised learning. To help get you started, there are several key features built into Elastic Observability to aid in analysis, helping bypass the need to run specific ML models. These features help minimize the time and analysis for logs.</p>
<p>Let’s review some of these built-in ML features:</p>
<p><strong>Anomaly detection:</strong> Elastic Observability, when turned on (<a href="https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html">see documentation</a>), automatically detects anomalies by continuously modeling the normal behavior of your time series data — learning trends, periodicity, and more — in real time to identify anomalies, streamline root cause analysis, and reduce false positives. Anomaly detection runs in and scales with Elasticsearch and includes an intuitive UI.</p>
<p><strong>Log categorization:</strong> Using anomaly detection, Elastic also identifies patterns in your log events quickly. Instead of manually identifying similar logs, the logs categorization view lists log events that have been grouped, based on their messages and formats, so that you can take action quicker.</p>
<p><strong>High-latency or erroneous transactions:</strong> Elastic Observability’s APM capability helps you discover which attributes are contributing to increased transaction latency and identifies which attributes are most influential in distinguishing between transaction failures and successes. An overview of this capability is published here: <a href="https://www.elastic.co/blog/apm-correlations-elastic-observability-root-cause-transactions">APM correlations in Elastic Observability: Automatically identifying probable causes of slow or failed transactions</a>.</p>
<p><strong>AIOps Labs:</strong> AIOps Labs provides two main capabilities using advanced statistical methods:</p>
<ul>
<li><strong>Log spike detector</strong> helps identify reasons for increases in log rates. It makes it easy to find and investigate causes of unusual spikes by using the analysis workflow view. Examine the histogram chart of the log rates for a given data view, and find the reason behind a particular change possibly in millions of log events across multiple fields and values.</li>
<li><strong>Log pattern analysis</strong> helps you find patterns in unstructured log messages and makes it easier to examine your data. It performs categorization analysis on a selected field of a data view, creates categories based on the data, and displays them together with a chart that shows the distribution of each category and an example document that matches the category.</li>
</ul>
<p> <strong>In this blog, we will cover anomaly detection and log categorization against the popular “Hipster Shop app” developed by Google, and modified recently by OpenTelemetry.</strong> </p>
<p>Overviews of high-latency capabilities can be found <a href="https://www.elastic.co/blog/apm-correlations-elastic-observability-root-cause-transactions">here</a>, and an overview of AIOps labs can be found <a href="https://www.youtube.com/watch?v=jgHxzUNzfhM&amp;list=PLhLSfisesZItlRZKgd-DtYukNfpThDAv_&amp;index=5">here</a>.</p>
<p>In this blog, we will examine a scenario where we use anomaly detection and log categorization to help identify a root cause of an issue in Hipster Shop.</p>
<h2 id="prerequisitesandconfig">Prerequisites and config</h2>
<p>If you plan on following this blog, here are some of the components and details we used to set up this demonstration:</p>
<ul>
<li>Ensure you have an account on <a href="http://cloud.elastic.co">Elastic Cloud</a> and a deployed stack (<a href="https://www.elastic.co/guide/en/elastic-stack/current/installing-elastic-stack.html">see instructions here</a>) on AWS. Deploying this on AWS is required for Elastic Serverless Forwarder.</li>
<li>Utilize a version of the ever so popular <a href="https://github.com/GoogleCloudPlatform/microservices-demo">Hipster Shop</a> demo application. It was originally written by Google to showcase Kubernetes across a multitude of variants available, such as the <a href="https://github.com/open-telemetry/opentelemetry-demo">OpenTelemetry Demo App</a>. The Elastic version is found <a href="https://github.com/elastic/opentelemetry-demo">here</a>.</li>
<li>Ensure you have configured the app for either Elastic APM agents or OpenTelemetry agents. For more details, please refer to these two blogs: <a href="https://www.elastic.co/blog/opentelemetry-observability">Independence with OTel in Elastic</a> and <a href="https://www.elastic.co/blog/implementing-kubernetes-observability-security-opentelemetry">Observability and security with OTel in Elastic</a>. Additionally, review the <a href="https://www.elastic.co/guide/en/apm/guide/current/open-telemetry.html">OTel documentation in Elastic</a>.</li>
<li>Look through an overview of <a href="https://www.elastic.co/guide/en/observability/current/apm.html">Elastic Observability APM capabilities</a>.</li>
<li>Look through our <a href="https://www.elastic.co/guide/en/observability/8.5/inspect-log-anomalies.html">Anomaly detection documentation</a> for logs and <a href="https://www.elastic.co/guide/en/observability/8.5/categorize-logs.html">log categorization documentation</a>.</li>
</ul>
<p>Once you’ve instrumented your application with APM (Elastic or OTel) agents and are ingesting metrics and logs into Elastic Observability, you should see a service map for the application as follows:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc051b75831308f32/6a7f1a3c77b03453e73ff8f9/blog-elastic-service-map.png" alt="" /></p>
<p>In our example, we’ve introduced issues to help walk you through the root cause analysis features: anomaly detection and log categorization. You might have a different set of anomalies and log categorization depending on how you load the application and/or introduce specific issues.</p>
<p>As part of the walk-through, we’ll assume we are a DevOps or SRE managing this application in production.</p>
<h2 id="rootcauseanalysis">Root cause analysis</h2>
<p>While the application has been running normally for some time, you get a notification that some of the services are unhealthy. This can occur from the notification setting you’ve set up in Elastic or other external notification platforms (including customer related issues). In this instance, we’re assuming that customer support has called in multiple customer complaints about the website.</p>
<p>How do you as a DevOps or SRE investigate this? We will walk through two avenues in Elastic to investigate the issue:</p>
<ul>
<li>Anomaly detection</li>
<li>Log categorization</li>
</ul>
<p>While we show these two paths separately, they can be used in conjunction and are complementary, as they are both tools Elastic Observability provides to help you troubleshoot and identify a root cause.</p>
<h3 id="machinelearningforanomalydetection">Machine learning for anomaly detection</h3>
<p>Elastic will detect anomalies based on historical patterns and identify a probability of these issues.</p>
<p>Starting with the service map, you can see anomalies identified with red circles and as we select them, Elastic will provide a score for the anomaly.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt38b12944fdbdd0e8/6a7f1a40e3a21944b499f8c2/blog-elastic-service-map-anomaly-detection.png" alt="" /></p>
<p>In this example, we can see that there is a score of 96 for a specific anomaly for the productCatalogService in the Hipster Shop application. An anomaly score indicates the significance of the anomaly compared to previously seen anomalies. More information on anomaly detection results can be found here. We can also dive deeper into the anomaly and analyze the details.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf7a1b60a1109fa57/6a7f1a426693f82b89664375/blog-elastic-single-metric-viewer.png" alt="" /></p>
<p>What you will see for the productCatalogService is that there is a severe spike in average transaction latency time, which is the anomaly that was detected in the service map. Elastic’s machine learning has identified a specific metric anomaly (shown in the single metric view). It’s likely that customers are potentially responding to the slowness of the site and that the company is losing potential transactions.</p>
<p>One step to take next is to review all the other potential anomalies that we saw in the service map in a larger picture. Use an anomaly explorer to view all the anomalies that have been identified.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5f8c2653add063e8/6a7f1a456c6eac6dcbf145a0/blog-elastic-anomaly-explorer.png" alt="" /></p>
<p>Elastic is identifying numerous services with anomalies. productCatalogService has the highest score and a good number or others: frontend, checkoutService, advertService, and others, also have high scores. However, this analysis is looking at just one metric.</p>
<p>Elastic can help detect anomalies across all types of data, such as kubernetes data, metrics, and traces. If we analyze across all these types (via individual jobs we’ve created in Elastic machine learning), we will see a more comprehensive view as to what is potentially causing this latency issue.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd958db4183c3832d/6a7f1a483ce8e28c58cf57a7/blog-elastic-anomaly-explorer-job-selection.png" alt="" /></p>
<p>Once all the potential jobs are selected and we’ve sorted by service.name, we can see that productCatalogService is still showing a high anomaly influencer score.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6756a3a0aadd2dbc/6a7f1a4b42a11732ea95c2fd/blog-elastic-anomaly-explorer-timeline.png" alt="" /></p>
<p>In addition to the chart giving us a visual of the anomalies, we can review all the potential anomalies. As you will notice, Elastic has also categorized these anomalies (see category examples column). As we scroll through the results, we notice a potential postgreSQL issue from the categorization, which also has a high 94 score. Machine learning has identified a “rare mlcategory,” meaning that it has rarely occurred, hence pointing to a potential cause of the issue customers are seeing.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt46c0097b09183fa8/6a7f1a4eeab5be957820aaf8/blog-elastic-machine-learning-service-name.png" alt="" /></p>
<p>We also notice that this issue is potentially caused by pgbench , a popular postgreSQL tool to help benchmark the database. pgbench runs the same sequence of SQL commands over and over, possibly in multiple, concurrent database sessions. While pgbench is definitely a useful tool, it should not be used in a production environment as it causes heavy load on the database host, likely causing the higher latency issues on the site.</p>
<p>While this may or may not be the ultimate root cause, we have rather quickly identified a potentially issue that has a high probability of being the root cause. An engineer likely intended to run pgbench against a staging database to evaluate its performance, and not the production environment.</p>
<h3 id="machinelearningforlogcategorization">Machine learning for log categorization</h3>
<p>Elastic Observability’s service map has detected an anomaly, and in this part of the walk-through, we take a different approach by investigating the service details from the service map versus initially exploring the anomaly. When we explore the service details for productCatalogService, we see the following:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6bcfa46b1ba24f70/6a7f1a523ce8e27f3acf57ab/blog-elastic-product-catalog-service.png" alt="" /></p>
<p>The service details are identifying several things:</p>
<ol>
<li>There is an abnormally high latency compared to expected bounds of the service. We see that recently there was a higher than normal (upward of 1s latency) compared to the average to 275ms on average.</li>
<li>There is also a high failure rate for the same time frame as the high latency (lower left chart “ <strong>Failed transaction rate</strong> ”).</li>
<li>Additionally, we can see the transactions and one in particular /ListProduct has an abnormally high latency, in addition to a high failure rate.</li>
<li>We see productCatalogService has a dependency on postgreSQL.</li>
<li>We also see errors all related to postgreSQL.</li>
</ol>
<p>We have an option to dig through the logs and analyze in Elastic or we can use a capability to identify the logs more easily.</p>
<p>If we go to Categories under Logs in Elastic Observability and search for postgresql.logto help identify postgresql logs that could be causing this error, we see that Elastic’s machine learning has automatically categorized the postgresql logs.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7ef998b88afc1e4d/6a7f1a55c2e9149015016fec/blog-elastic-categories.png" alt="" /></p>
<p>We notice two additional items:</p>
<ul>
<li>There is a high count category (message count of 23,797 with a high anomaly of 70) related to pgbench (which is odd to see in production). Hence we search further for all pgbench related logs in Categories .</li>
<li>We see an odd issue regarding terminating the connection (with a low count).</li>
</ul>
<p>While investigating the second error, which is severe, we can see logs from Categories before and after the error.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt208408824fb1cb51/6a7f1a5877b0346da53ff8ff/blog-elastic-timestamp.png" alt="" /></p>
<p>This troubleshooting shows postgreSQL having a FATAL error, the database shutting down prior to the error, and all connections terminating. Given the two immediate issues we identified, we have an idea that someone was running pgbench and this potentially overloaded the database, causing the latency issue that customers are seeing.</p>
<p>The next steps here could be to investigate anomaly detection and/or work with the developers to review the code and identify pgbench as part of the deployed configuration.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I hope you’ve gotten an appreciation for how Elastic Observability can help you further identify and get closer to pinpointing root cause of issues without having to look for a “needle in a haystack.” Here’s a quick recap of lessons and what you learned:</p>
<ul>
<li>Elastic Observability has numerous capabilities to help you reduce your time to find root cause and improve your MTTR (even MTTD). In particular, we reviewed the following two main capabilities in this blog:</li>
</ul>
<ol>
<li><strong>Anomaly detection:</strong> Elastic Observability, when turned on (<a href="https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html">see documentation</a>), automatically detects anomalies by continuously modeling the normal behavior of your time series data — learning trends, periodicity, and more — in real time to identify anomalies, streamline root cause analysis, and reduce false positives. Anomaly detection runs in and scales with Elasticsearch and includes an intuitive UI.</li>
<li><strong>Log categorization:</strong> Using anomaly detection, Elastic also identifies patterns in your log events quickly. Instead of manually identifying similar logs, the logs categorization view lists log events that have been grouped based on their messages and formats so that you can take action quicker.</li>
</ol>
<ul>
<li>You learned how easy and simple it is to use Elastic Observability’s log categorization and anomaly detection capabilities without having to understand machine learning (which help drive these features), nor having to do any lengthy setups.
Ready to get started? <a href="https://cloud.elastic.co/registration">Register for Elastic Cloud</a> and try out the features and capabilities I’ve outlined above.</li>
</ul>
<h3 id="additionalloggingresources">Additional logging resources:</h3>
<ul>
<li><a href="https://www.elastic.co/getting-started/observability/collect-and-analyze-logs">Getting started with logging on Elastic (quickstart)</a></li>
<li><a href="https://www.elastic.co/guide/en/observability/current/logs-metrics-get-started.html">Ingesting common known logs via integrations (compute node example)</a></li>
<li><a href="https://docs.elastic.co/integrations">List of integrations</a></li>
<li><a href="https://www.elastic.co/blog/log-monitoring-management-enterprise">Ingesting custom application logs into Elastic</a></li>
<li><a href="https://www.elastic.co/blog/observability-logs-parsing-schema-read-write">Enriching logs in Elastic</a></li>
<li>Analyzing Logs with <a href="https://www.elastic.co/blog/reduce-mttd-ml-machine-learning-observability">Anomaly Detection (ML)</a> and <a href="https://www.elastic.co/blog/observability-logs-machine-learning-aiops">AIOps</a></li>
</ul>
<h3 id="commonusecaseexampleswithlogs">Common use case examples with logs:</h3>
<ul>
<li><a href="https://youtu.be/ax04ZFWqVCg">Nginx log management</a></li>
<li><a href="https://www.elastic.co/blog/vpc-flow-logs-monitoring-analytics-observability">AWS VPC Flow log management</a></li>
<li><a href="https://www.elastic.co/blog/kubernetes-errors-elastic-observability-logs-openai">Using OpenAI to analyze Kubernetes errors</a></li>
<li><a href="https://youtu.be/Li5TJAWbz8Q">PostgreSQL issue analysis with AIOps</a></li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/observability-labs/blog/reduce-mttd-ml-machine-learning-observability</link>
    <guid isPermaLink="false">reduce-mttd-ml-machine-learning-observability</guid>
    <category><![CDATA[Machine Learning]]></category>
    <category><![CDATA[Logs Analytics]]></category>
    <category><![CDATA[Agentic Observability]]></category>
    <dc:creator><![CDATA[Bahubali Shetti]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcea834289bfca650/6a7f1a5bde23151d7efd809b/illustration-machine-learning-anomaly-1680x980.png" length="0" type="image/png"/>
    <pubDate>Tue, 07 Feb 2023 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>