<?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[Sophia Solomon - 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[Sophia Solomon - 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/author/sophia-solomon</link>
    </image>
    <link>https://www.elastic.co/observability-labs/author/sophia-solomon</link>
    <atom:link href="https://www.elastic.co/observability-labs/rss/author/sophia-solomon.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[en]]></language>
    <lastBuildDate>Tue, 22 Sep 2026 08:06:54 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Developer's Guide to Easy Ops: Demystifying OpenTelemetry's Magic]]></title>
    <description><![CDATA[A Go-based Developer's 101 Guide to Easy Ops with OpenTelemetry and Elastic Observability.]]></description>
    <content:encoded><![CDATA[<h2 id="theintroductionfromcodetodashdemystified">The Introduction: From Code to Dash, Demystified</h2>
<p>Observability for developers has lately been distilled into implementing auto-instrumentation, allowing you to instantly connect your code with the larger observability world. This way of utilizing an upstream SDK is certainly the simplest and most production-ready, and works efficiently with the <a href="https://www.elastic.co/docs/solutions/observability/get-started/quickstart-elastic-cloud-otel-endpoint">Elastic Cloud Managed OTLP Endpoint</a>.</p>
<p>But what if you could not only add powerful tracing to your Go service but also <em>truly</em> understand how the magic works, rather than just copy-pasting configuration files or a line of code? In the same way that you build your knowledge of software development systems, observability, modernized by OpenTelemetry (OTel) standardization, is a rich, broad system that is valuable to understand. Here is an in-depth technical breakdown of every piece of simple OTel instrumentation using the Elastic Distributions of OpenTelemetry (EDOT) and Golang, from the ground up.</p>
<p>Telemetry is the automated collection, transmission and analysis of data from your application, which can apply to any observable distributed system. This data can range from regular health check calls with your application to real-time information about user interactions, requests, and transactions. Using the example application repository <a href="https://github.com/sophia-solo/otel-go-demo">here</a>, we’ll build a strong observability foundation to start observing our applications with confidence.</p>
<h2 id="understandingtheopentelemetryflow">Understanding the OpenTelemetry Flow</h2>
<p>Below, you will see the basic flow of your data when implementing observability with OTel in your system. Before we dive in, let’s explain some of the key terms within OTel. Let’s go over these base key players that we need to implement observability solutions with OTel:</p>
<ul>
<li><p><a href="https://www.elastic.co/docs/solutions/observability/apm/spans"><strong>Span</strong></a>: This is a single, timed unit of a distributed trace that can represent a specific operation, such as a database query or an HTTP handler.</p></li>
<li><p><a href="https://www.elastic.co/docs/solutions/observability/apm/traces"><strong>Trace</strong></a>: This is a detailed record of a single request’s journey through your system, AKA a hierarchy of your spans.</p></li>
<li><p><a href="https://opentelemetry.io/docs/specs/otel/trace/api/#tracer"><strong>Tracer</strong></a>: This is the handle for generating spans. You will typically have one per instrumentation library, for example myapp/http.</p></li>
<li><p><a href="https://opentelemetry.io/docs/specs/otel/trace/api/#tracerprovider"><strong>Tracer Provider</strong></a>: This is the cornerstone of the SDK. This creates Tracer instances, and you can configure it on application start up.</p></li>
<li><p><a href="https://www.elastic.co/docs/reference/apm/agents/go/custom-instrumentation-propagation"><strong>Context Propagation</strong></a>: The mechanism for passing trace context between operations and services, maintaining the relationship between parent and child spans.</p></li>
<li><p><a href="https://www.elastic.co/docs/deploy-manage/monitor/stack-monitoring/es-monitoring-exporters"><strong>Exporter</strong></a>: This is the part that is responsible for sending your telemetry data to a vendor backend, and you can decide if you are sending it to the OTel Collector, EDOT Collector or an OTLP Endpoint.</p></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte6fcb14e0997e272/6a7f05342f00b22f3fefe840/otel-flow.png" alt="Go OpenTelemetry App Flow" /></p>
<h2 id="installingthemagicinstrumentationstyle">Installing the Magic, Instrumentation Style</h2>
<p>OpenTelemetry provides instrumentation libraries that handle much of the tracing complexity for you. These libraries wrap common frameworks and libraries (like <code>net/http/otelhttp</code>) and automatically capture telemetry without requiring you to manually create spans for every operation.</p>
<p>However, before you're able to send any telemetry, OTel needs to know <em>who</em> (which service) is sending that data.</p>
<p>A <a href="https://opentelemetry.io/docs/concepts/resources/">resource</a> represents the specific entity, in this case <code>"simple-go-service"</code>, that is producing your telemetry data. Its identity is recorded as resource attributes, and resource attributes can include pod names, service names or instances, deployment environments; Basically <em>anything</em> important to identifying your resource. This resource is your service's identity card that gets attached to every span and metric that it emits with its attributes. Once your trace arrives, these attributes can answer <em>"what version was running?"</em> or <em>"which service is this from?"</em></p>
<pre><code>func initOTel(ctx context.Context, endpoint string) (func(context.Context) error, error) {
res, err := resource.New(ctx,
        resource.WithAttributes(
            semconv.ServiceName("simple-go-service"),
            semconv.ServiceVersion("1.0.0"),
        ),
    )
    if err != nil {
        return nil, err
    }
</code></pre>
<p>In the code above, <code>resource.New()</code> constructs the "identity card" of our Go service. The attributes that will be attached to it will use semantic conventions(<code>semconv</code>), standardized names for common metadata fields. These <a href="https://opentelemetry.io/docs/concepts/semantic-conventions/">semantic conventions</a> make sure that every single OTel-compatible observability backend knows their meaning.</p>
<p>Now that we've bootstrapped our application with the <code>initOtel</code> function, we can continue to configure everything else!</p>
<p>Let’s begin instrumenting this application by building all the app components that we will need to implement modern observability tools. Below is our instrumentation using <code>otelhttp</code>, which will handle span creation after calling the specified API routes. </p>
<pre><code>http.Handle("/hello", otelhttp.NewHandler(http.HandlerFunc(handleHello), "hello"))
http.Handle("/api/data", otelhttp.NewHandler(http.HandlerFunc(handleData), "data"))
http.HandleFunc("/health", handleHealth)

// Example of a tracer within our handleHello() function
tracer = tp.Tracer("simple-go-service")

ctx, span := tracer.Start(ctx, "process-hello")
defer span.End()
</code></pre>
<p>The key insight here is that <code>otelhttp.NewHandler</code> handles all the span lifecycle management for HTTP requests. You don't need to manually call <code>tracer.Start()</code>or <code>span.End()</code> for basic HTTP tracing since the library does this for you.</p>
<p>On application start up, the SDK will use the tracer provider set up below in order to create Tracer instances. These instances help create and manage the spans contained within traces.</p>
<pre><code>traceExporter, err := otlptracegrpc.New(ctx,
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;otlptracegrpc.WithEndpoint(endpoint),
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;otlptracegrpc.WithInsecure(),
    )

    tp := sdktrace.NewTracerProvider(
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sdktrace.WithBatcher(traceExporter),
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sdktrace.WithResource(res),
    )
    otel.SetTracerProvider(tp)
    tracer = tp.Tracer("simple-go-service")
</code></pre>
<p>Within our <code>initOTel</code> function, we will set up one of our most important signals: logs. First, we initialize the logExporter that will send logs to our OTel Collector using gRPC protocol. Then the <code>LoggerProvider</code> will create the base of the <code>logExporter</code> that batches log entries together before sending those batches to your exporter, attaching metadata about the services along the way. Lastly, the <code>LoggerProvider</code> also creates a standard Go structured logger (slog) that automatically includes trace context (such as span IDs) and batches your log with other logs. These are sent to your observability backend through the exporter along with your metrics and traces. </p>
<pre><code>logExporter, err := otlploggrpc.New(ctx,
        otlploggrpc.WithEndpoint(endpoint),
        otlploggrpc.WithInsecure(),
    )
    if err != nil {
        return nil, err
    }

    lp := sdklog.NewLoggerProvider(
        sdklog.WithProcessor(sdklog.NewBatchProcessor(logExporter)),
        sdklog.WithResource(res),
    )
    logger = slog.New(otelslog.NewHandler("simple-go-service", otelslog.WithLoggerProvider(lp)))
</code></pre>
<p>Below you can see how you can view your logs through Kibana in the APM UI. These logs are also color - coordinated; Coded warnings are in yellow, errors are in red, and regular logs are in green.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte40c8a47ca47ad2e/6a7f0537b4377041fe4d6963/log-viewer.png" alt="Viewing your logs in the APM UI" /></p>
<p><a href="https://www.elastic.co/docs/solutions/observability/apm/metrics">Metrics</a> are set up in the next part of our code. Metrics are telemetry signals that track the quantitative data from your application, such as response times and request counts. The metric exporter is initialized to send metric data to our EDOT Collector then to our observability backend, Elastic Observability in this case, using gRPC. The meter provider in the next portion periodically collects and exports our metrics data and measurements, the same as the tracer provider creates tracers. The only difference between the two providers is that the meter provider works on a timer while the trace provider exports spans as they complete.</p>
<pre><code>metricExporter, err := otlpmetricgrpc.New(ctx,
        otlpmetricgrpc.WithEndpoint(endpoint),
        otlpmetricgrpc.WithInsecure(),
    )
    if err != nil {
        return nil, err
    }

    mp := metric.NewMeterProvider(
        metric.WithReader(metric.NewPeriodicReader(metricExporter)),
        metric.WithResource(res),
    )
    otel.SetMeterProvider(mp)

    meter := mp.Meter("simple-go-service")
    requestCounter,  = meter.Int64Counter("http.requests")
    requestDuration,  = meter.Float64Histogram("http.duration")
</code></pre>
<p>In order to finish initializing OpenTelemetry, we set up our propagators for context propagation. The set text map propagator automatically injects the trace ID and the span ID of your service making an outbound HTTP request to another service, following the <a href="https://www.w3.org/TR/trace-context/">W3C Trace Context</a> standard. In short, this maintains the parent-child relationship between spans.</p>
<pre><code>otel.SetTextMapPropagator(propagation.TraceContext{})

    return func(ctx context.Context) error {
        tp.Shutdown(ctx)
        mp.Shutdown(ctx)
        lp.Shutdown(ctx)
        return nil
    }, nil
</code></pre>
<p>Now that you know how these pieces work together, try to run the repository linked <a href="https://github.com/sophia-solo/otel-go-demo">here</a>, using the readme as your guide.</p>
<h3 id="sidenoteaddingcustomspans">Sidenote: Adding Custom Spans</h3>
<p>For getting an application emitting traces, this instrumentation works great! If you visit localhost:8080/hello after starting the docker containers, the <code>otelhttp</code> middleware automatically creates spans for each HTTP request. However, basic instrumentation only shows essential application telemetry, such as response duration, URL paths, and status codes. You won’t know what happens between the request coming in and request completion. The moment OpenTelemetry truly gains power is when you add custom spans. Unlike auto-instrumentation where spans are created as well as closed automatically, custom spans require you to explicitly start and stop them.</p>
<p>Custom spans can track your application’s logic, such as specific business events or marking expensive operations, using a detailed hierarchy within each trace. In the <a href="https://github.com/sophia-solo/otel-go-demo">application</a> for this article, there are several custom spans that were created to track important operations:</p>
<ul>
<li><p><code>background-work</code>: This traces asynchronous processing that happens with the main request.</p></li>
<li><p><code>computation:</code> This measures computations and then captures those results, and the computation type.</p></li>
</ul>
<p>Custom spans add granular visibility into your application's behavior. For example, in <code>performComputation</code>:</p>
<pre><code>ctx, span := tracer.Start(ctx, "computation")
defer span.End()

result := rand.Float64()
span.SetAttributes(
    attribute.String("comp.type", compType),
    attribute.Float64("comp.result", result),
    )

    logger.InfoContext(ctx, "Computation completed", "type", compType, "result", result)

if result &lt; 0.3 {
span.AddEvent("Low confidence result")
    logger.WarnContext(ctx, "Low confidence computation", "result", result)
}
}
</code></pre>
<p>The attributes set above become searchable and filterable in our Elastic Observability backend, allowing for attribute filtering by <code>attribute.result</code> and <code>attribute.compType</code>. If you query your data with “show me all computations where results are less than 0.3,” then you will notice the span event <code>span.AddEvent(“Low confidence result”)</code> tacked on with a timestamped marker. This appears on your trace timeline as well, adding even more visibility to any unusual events. Below is a small example of the filtering that Kibana can accomplish from custom spans.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta0fe36324e168b50/6a7f053b6c6eac182ef13dc5/computations.png" alt="Filtering attribute.Result to review borderline Low Confidence results" /></p>
<h2 id="thedatapipelinefromcodetoirl">The Data Pipeline: From Code to IRL</h2>
<p>Now that you can export your custom spans and data to OTLP which sends it to the EDOT Collector and then to an observability backend, the best hub for your telemetry data will be the [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/. It is a simple, standalone process that is able to receive, process and export all of your telemetry data. Within this project, we use the Elastic Distributions of OpenTelemetry (<a href="https://www.elastic.co/docs/solutions/observability/get-started/opentelemetry/quickstart/self-managed/docker">EDOT</a>) Collector, an optimized Collector for usage within your Elastic Stack. Since this is a self-managed Elastic instance, this article and connected repository utilize the EDOT Collector through <code>elasticapm</code>, but for Elastic Cloud or Serverless projects, you can use the Elastic Managed OpenTelemetry Protocol (OTLP) Endpoint. As noted in the quickstart documentation <a href="https://www.elastic.co/docs/solutions/observability/get-started/quickstart-elastic-cloud-otel-endpoint">here</a>, the Elastic Cloud Managed OTLP Endpoint endpoint helps get your data quickly and efficiently into your Elastic Stack through OTLP, without schema translation! This means that your telemetry hits Elastic instantly and your telemetry data remains vendor-neutral.</p>
<p>For most developers and SREs, this Collector is an amazing tool. It allows you to decouple your code from the observability backend. Your application does not need to know its final destination, it can just send the data to the Collector. Your observability backend can change constantly without it even touching your code. The OpenTelemetry Collector also acts as a gateway for multiple streams of data, and is able to accept various formats in order to unify them for exportation. Lastly, the OpenTelemetry Collector is able to offload processing power from your application - tasks such as retries, batching and filtering can happen in the Collector, not your application.</p>
<p>After trying out this article’s repository, try auto-instrumenting your application with <a href="https://www.elastic.co/docs/reference/opentelemetry">Elastic Distributions of OpenTelemetry</a> (EDOT) so that you can utilize the APM UI to its full potential! With the latest version of Elasticsearch and Kibana <a href="https://github.com/elastic/start-local"><code>start-local</code></a>, you can use <a href="https://www.docker.com/">Docker</a> to install and run the services and instantly start monitoring your application. </p>
<h3 id="understandingthecollectorconfiguration">Understanding the Collector Configuration</h3>
<p>The Collector's behavior is defined in a configuration file (<code>otel-collector-config.yaml</code>). Let's break down each component.</p>
<p><strong>Receivers</strong> define how the Collector accepts telemetry data. Here, we're listening for both gRPC and HTTP traffic.</p>
<pre><code>receivers:
&amp;nbsp;&amp;nbsp;# Receives data from other Collectors in Agent mode
&amp;nbsp;&amp;nbsp;otlp:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;protocols:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;grpc:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;endpoint: 0.0.0.0:4317
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;http:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;endpoint: 0.0.0.0:4318
</code></pre>
<p><strong>Connectors</strong> are specialized components that sit in between pipelines, and in this case, we are using the <code>elasticapm</code> Connector. This APM Connector exports our metrics, logs, and traces, while simultaneously acting as a receiver for the metrics/aggregated-otel-metrics pipeline (see below). Without it, your raw OTLP data lands in Elasticsearch, but the APM UI has nothing to build its views from.</p>
<pre><code>connectors:
  elasticapm: {} # Elastic APM Connector
</code></pre>
<p><strong>Processors</strong> transform, filter, or enrich data as it passes through the EDOT Collector. The batch processor aggregates spans before export, reducing network overhead and improving efficiency, as well as limiting batch sizes. The batch/metrics processor does this as well, but for APM metrics. Lastly, there is the Elastic APM processor. This processor ensures that your spans fields are aligned, your traces views are complete, and  it overall bridges the gap between Elastic's expectations and OpenTelemetry's formatting of your traces.</p>
<pre><code>processors:
  batch:
    send_batch_size: 1000
    timeout: 1s
    send_batch_max_size: 1500
  batch/metrics:
    send_batch_max_size: 0 # Explicitly set to 0 to avoid splitting metrics requests
    timeout: 1s
  elasticapm: {} # Elastic APM Processor
</code></pre>
<p>As mentioned previously in the article, <strong>exporters</strong> send data to your observability backend. The debug exporter logs telemetry to the console (useful for development), while the Elasticsearch exporter sends traces to your Elastic stack.</p>
<pre><code>exporters:
  debug: {}
  elasticsearch/otel:
    endpoints:
      - ${ELASTIC_ENDPOINT} # Will be populated from environment variable
    user: elastic
    password: ${ELASTIC_PASSWORD}
    tls:
      ca_file: /config/certs/ca/ca.crt
    mapping:
      mode: otel
</code></pre>
<p><strong>Pipelines</strong> connect receivers, processors, and exporters into a data flow. These EDOT Collector pipelines receive OTLP traces, batches them, and exports to the <code>debug</code>, <code>elasticapm</code> and <code>elasticsearch/otel</code> exporters. It also exports metrics to the <code>debug</code> and <code>elasticsearch/otel</code> exporters.</p>
<pre><code>service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [batch/metrics]
      exporters: [debug, elasticsearch/otel]
    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [debug, elasticapm, elasticsearch/otel]
    traces:
      receivers: [otlp]
      processors: [batch, elasticapm]
      exporters: [debug, elasticapm, elasticsearch/otel]
    metrics/aggregated-otel-metrics:
      receivers:
        - elasticapm
      processors: [] # No processors defined in the original for this pipeline
      exporters:
        - debug
        - elasticsearch/otel
</code></pre>
<h2 id="debuggingyourcodewithconfidenceinkibana">Debugging Your Code with Confidence in Kibana</h2>
<p>Elastic Observability, utilizing Kibana and Streams, has native support for the OTLP Endpoint through the EDOT Collector, which was used in this project. Below, you can see that your data is automatically connected to Streams from the beginning, requiring no extra leg work! You can add conditions or any Grok processors as your data is streaming in, and you'll be able to instantly see your data's schema and data quality.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7f0d96abddaada00/6a7f053dde23158fa4fd786d/streams-connection.png" alt="Streams built-in connection" /></p>
<p>Elastic also provides the Elastic Cloud Managed Endpoint for even easier storage, data-processing, and scaling. If you use this Managed Endpoint, it means that you can configure OpenTelemetry to send data directly to Elasticsearch, without ANY specialized Collectors. Any way you choose, once your traces are flowing, Kibana’s APM UI provides powerful visualization and analysis capabilities will be everything you need to debug your code. You are able to drill down into individual requests, identify bottlenecks, find anomalies and troubleshoot any issues that arise with confidence.</p>
<p>Here is one span of interest from this repository. Within Kibana, you can immediately filter by the Trace ID, finding other spans with the same Trace ID to visually see the entire trace.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt07ee960435778536/6a7f054173d9bddcb129d7f8/pre-filter-traces.png" alt="A span of interest among many" />
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltff0f71d463353c0c/6a7f0544ea068d7b00f09b4c/post-filter-traces.png" alt="The entire trace of the span" /></p>
<p>Kibana Discover also allows you to switch indices instantly without losing your filters, ensuring that you can also see the logs that correspond with the same Trace ID.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt77ba55b402496814/6a7f05482f00b2d0c8efe852/log-trace.png" alt="Logs matching the Trace ID" /></p>
<p>In addition to the manually checking your traces, you can automatically check them within the APM UI (shown below). This is easy trace visualization using the Kibana APM UI is readily available while using the <code>elasticapm</code> connector. Below is a visualization of a trace comprised of spans within our project. Knowing both methods of correlating spans is beneficial to build the foundation of utilizing Kibana and the APM UI for observability.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8ca3abbac39f6f65/6a7f054bbd2198b235757d48/automatic-apm-trace.png" alt="Automatic trace span hierarchy in Kibana APM" /></p>
<p>Here is a fully built out dashboard built from the repository featured in this article. The possibilities with Elastic Observability are endless!</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf6d064cb610d0f80/6a7f054eead8ec624cbaa4df/kibana-dashboard.png" alt="Full Kibana Dashboard" /></p>
<h2 id="congratsyourenotjustadeveloperanymore">Congrats, You’re Not “Just” a Developer Anymore!</h2>
<p>We’ve broken down the why and how behind OpenTelemetry’s basic components, including the TraceProvider, the span, the exporter and the Collector. Here, you’ve done more than just implement your tracing tool. You now understand the complete data flow from your code to the graphs on your dashboard.</p>
<p>You can now speak the language of observability with confidence, not because you memorized a configuration file, but because you now understand the data flow from your code to the graph on your dashboard. You understand how telemetry moves through your system. You aren’t “just” a developer anymore; you’re now a developer who can truly see.</p>
<p>Try out the code repo above! Included in the [repository]() is a generate-traffic.sh script file. You can run this repeatedly in order to generate logs, traces, and metrics for you to play with within the APM UI. Also, check out our latest <a href="https://www.elastic.co/docs/release-notes/elasticsearch">releases</a> in our release docs page for exciting Elastic updates.</p>]]></content:encoded>
    <link>https://www.elastic.co/observability-labs/blog/developers-guide-to-easy-ops</link>
    <guid isPermaLink="false">developers-guide-to-easy-ops</guid>
    <category><![CDATA[Infrastructure Monitoring]]></category>
    <category><![CDATA[OpenTelemetry]]></category>
    <dc:creator><![CDATA[Sophia Solomon]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt76532418dd498412/6a7f055196b5a66f0087b133/blog-header.png" length="0" type="image/png"/>
    <pubDate>Tue, 17 Mar 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[AIOps with Elastic Observability: Modern AIOps & Log Intelligence]]></title>
    <description><![CDATA[Exploring modern AIOps capabilities, including anomaly detection, log intelligence, and log analysis &amp; categorization with Elastic Observability.]]></description>
    <content:encoded><![CDATA[<h2 id="aiopsblogrefresherunlockingintelligencefromyourlogswithelastic">AIOps Blog Refresher: Unlocking Intelligence from Your Logs with Elastic</h2>
<p>Elastic has been leading the charge with AIOps, especially in the recent 9.2 update of Elastic Observability with Streams. The conversation around AIOps has shifted dramatically as we move through the year. DevOps and SRE teams aren't asking whether they need AIOps, they're asking how to leverage it more effectively to stay ahead of exponentially growing complexity.</p>
<p>The current challenge of AIOps is that modern cloud-native environments generate massive volumes of telemetry data that are magnitudes larger than past environments. But here's what many teams overlook: logs are the richest source of operational intelligence you have. Logs are able to tell you exactly what happened and why, while metrics only tell you something is wrong, and traces only tell you where. The problem is that most organizations are drowning in logs. Microservices, such as user authentications or inventories, serverless functions, and Kubernetes generate millions of log entries daily. Without AI and machine learning, finding meaningful patterns in this data takes too much time and energy.</p>
<h2 id="logintelligenceimprovementwhatsnewin2025">Log Intelligence Improvement: What's New in 2025</h2>
<p>Historically in observability, unlocking your log intelligence included long manual effort that required not only parsing through logs, but also structuring those logs. Elastic Observability has drastically changed how teams extract value from logs. Observability is not just simple signal analysis - modern tools need to have proactive, log-driven investigations. At Elastic, this modernity is Streams.</p>
<p>Streams, a new release from Elastic, is a collection of AI-driven tools that identify significant events in parsed raw logs by enriching logs with meaningful fields. With Streams, SREs can maximize the value of their data, their logs, and their systems. With system reliability as the goal, Streams helps to reduce pipeline management overhead and accelerates observability analysis. And it takes nearly no time to set up!</p>
<p>Here is how Streams powers the Elastic Observability capabilities available now.</p>
<h3 id="advancedlograteanalysis">Advanced Log Rate Analysis</h3>
<p>Log rate analysis can go far beyond only detecting spikes. Elastic's machine learning automatically identifies when log volumes deviate from expected baselines, then contextualizes these changes within your broader system performance. When your application suddenly generates more error logs, Elastic’s AIOps doesn't just alert you, it also determines whether it's a critical issue requiring immediate attention or just a temporary anomaly.</p>
<p>This matters to your analysis because not all log spikes are equal. A 10x increase in DEBUG logs might indicate verbose logging accidentally enabled in production. A 2x increase in ERROR logs could signal a cascading failure. Log rate analysis distinguishes between these scenarios automatically, giving your team the context needed to respond appropriately.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5bb4ac6d272c3925/6a7f0dc4eab5be0e4020a739/log-analysis.png" alt="Log Analysis" /></p>
<h3 id="intelligentlogcategorizationwithstreams">Intelligent Log Categorization with Streams</h3>
<p>This is where AIOps shines with log data. Streams uses machine learning algorithms in order to automatically classify and group similar log patterns, dramatically reducing noise. Instead of manually parsing millions of entries, the system identifies common structures, groups related events, and surfaces the categories that matter most.</p>
<p>Logs are unstructured by nature, making them difficult to analyze at scale. Streams corrals chaotic log streams into organized, queryable patterns. Instantly, you can see that 80% of your errors fall into three categories, helping you prioritize where to focus remediation efforts. This approach helps you reduce noise and accelerate analysis, allowing teams to act on insights faster.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt43de44a2668aba4d/6a7f0dc7e02fac4c835d65dc/categories.png" alt="Log Categorizations" /></p>
<h3 id="multidimensionalanomalydetection">Multi-Dimensional Anomaly Detection</h3>
<p><a href="https://www.elastic.co/docs/explore-analyze/machine-learning/anomaly-detection">Anomaly detection</a> now simultaneously examines relationships between logs, metrics, and traces. A slight increase in response time might not trigger an alert by itself, but when correlated with unusual log patterns and memory consumption changes, the system recognizes it as an early warning sign.</p>
<p>Logs contain a myriad of contextual information that metrics and traces can't capture: stack traces, user IDs, transaction details, error messages, etc. By correlating log anomalies with other signals, you get the full picture of what's happening in your system. This whole holistic view enables teams to catch issues earlier, as well as understand their full impact across the stack.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1c652019d828e657/6a7f0dca3ce8e26a5acf53db/anomalies.png" alt="Anomaly Detection" /></p>
<h3 id="enhancedrootcauseanalysispoweredbysignificantevents">Enhanced Root Cause Analysis Powered by Significant Events</h3>
<p>When an issue occurs, Elastic's Streams accelerates root cause analysis through AI-assisted parsing of logs and bringing about <a href="https://www.elastic.co/docs/solutions/observability/streams/management/significant-events">“Significant events.”</a> Significant event queries can be defined by AI or manually, depending on if you know what logs you are looking for or not. Then, Elastic’s AIOps traces the problem through your entire stack using these events, as well as enriched log data combined with distributed tracing. This system is able to correlate failed transactions with specific log entries, deployment events, and infrastructure changes. This helps you understand not just what broke, but why and when.</p>
<p>Streams makes the analysis of your logs quick and automatic by going across your entire distributed system within seconds, grabbing relevant log entries such as stack traces, state information, error messages, and more. What used to require hours of manual investigation and deduction now happens automatically, freeing you and your team from tedious detective work and enabling faster resolution. </p>
<h2 id="logsinactionrealworldimpact">Logs in Action: Real-World Impact</h2>
<p>Let's look at how these capabilities work together in practice. Imagine your payment processing service is experiencing intermittent failures - only 0.5% of transactions, but enough to concern your team. Traditional monitoring shows everything is mostly okay, but customers are still complaining.</p>
<p>Without Streams, an SRE might initially run some broad queries, manually sift through thousands of logs, struggle to connect all the dots, and ultimately not understand the correlation between the errors and recent system changes. </p>
<p>With Elastic Streams and AIOps, many of these potential problems are instantly mitigated:</p>
<ul>
<li><p>Streams automatically parse the payment service, adding connection timeouts to a new category of significant events</p></li>
<li><p>Log rate analysis with Streams reveal that this significant event category has been slowly growing over the past month, showing growth of the timeouts from a small number of occurrences into a larger amount</p></li>
<li><p>Elastic’s built-in anomaly detection correlates these significant events with deployment data, and identifies that they started appearing after a recent load balancer configuration</p></li>
<li><p>Root analysis pinpoints the exact database connection pool setting that is too restrictive for peak load by tracing affected transactions through previously enriched logs</p></li>
</ul>
<p>What usually takes 4-8 hours of manual log analysis is resolved in minutes, with Elastic automatically highlighting the relevant log entries that tell the complete story. This is the power of AIOps and Streams as applied to log intelligence.</p>
<h2 id="thepowerofunifiedlogintelligence">The Power of Unified Log Intelligence</h2>
<p>What sets Elastic apart is treating logs as a priority in your observability strategy. Elastic provides comprehensive log ingestion that centralizes petabytes of logs from across your infrastructure with flexible parsing and enrichment. The platform uses purpose-built machine learning models that understand log patterns, not generic algorithms retrofitted for log analysis.</p>
<p>Logs don't exist in isolation, which is why Elastic correlates log data with metrics, traces, and business events to provide complete context. And because log volumes can be massive, Elastic's tiered storage approach means you can retain years of logs for compliance and historical analysis without breaking the budget.</p>
<h2 id="whylogsmattermorethanever">Why Logs Matter More Than Ever</h2>
<p>Logs have become the cornerstone of effective AIOps for three critical reasons.</p>
<p>First off, logs capture what metrics can't. A metric tells you the CPU is at 80%, but a log tells you which process is consuming resources and why. This level of detail is essential for understanding not just that something is wrong, but what specifically is causing the problem.</p>
<p>Second, logs provide business context. Error messages contain user IDs, transaction ldetails, and business logic failures that help you understand customer impact. When you're troubleshooting an issue, knowing which customers are affected and what they were trying to do is invaluable for prioritizing your response.</p>
<p>Third, logs enable true root cause analysis. Stack traces, error messages, and application state captured in logs are essential for understanding the why behind every incident. Without this information, teams are left guessing at root causes rather than definitively identifying and fixing them.</p>
<p>The teams winning with AIOps in 2025 aren't just monitoring metrics, they're extracting intelligence from their logs at scale, turning operational data into actionable insights.</p>
<h2 id="transformyourlogstrategytoday">Transform Your Log Strategy Today</h2>
<p>Every hour your team spends manually searching through logs is an hour they're not spending on innovation. Every incident that could have been prevented through intelligent log analysis represents both technical debt and business risk.</p>
<p>Elastic Observability provides the foundation you need to unlock the intelligence hidden in your logs. With automatic categorization, anomaly detection, and ML-powered analysis, you can start seeing value immediately. Check out this recent <a href="https://www.elastic.co/observability-labs/blog/elastic-observability-streams-ai-logs-investigations">article</a> to get started with Elastic Streams and Observability today!</p>]]></content:encoded>
    <link>https://www.elastic.co/observability-labs/blog/modern-aiops-elastic-observability</link>
    <guid isPermaLink="false">modern-aiops-elastic-observability</guid>
    <category><![CDATA[Agentic Observability]]></category>
    <category><![CDATA[Logs Analytics]]></category>
    <dc:creator><![CDATA[Sophia Solomon]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt64fd099b0fe44551/6a7f0dcd1967ea79c83307bb/blog-header.png" length="0" type="image/png"/>
    <pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>