Advanced Topics#

Once you have metrics, logs, traces, dashboards, and alerting in place, advanced observability techniques push further — answering questions that traditional telemetry cannot. This section covers continuous profiling, eBPF, synthetic monitoring, chaos engineering observability, and AIOps.

Continuous Profiling#

Traditional profiling captures a snapshot of CPU, memory, or I/O usage during a debugging session. Continuous profiling runs always in production, attaching profiling data to traces to explain why a span is slow — not just that it’s slow.

What Profiling Captures#

Profile TypeWhat It ShowsExample Insight
CPUWhich functions consume CPU timeJsonSerializer.serialize() takes 40% of CPU in checkout
Heap (Alloc)Which functions allocate the most memoryString.concat() in logging creates 2 GB/min of garbage
Wall ClockReal elapsed time (including I/O waits)HttpClient.send() blocks for 800ms waiting on downstream
Lock/MutexContention on locksConcurrentHashMap.put() contention under high concurrency
I/OBlocking I/O operationsFileInputStream.read() blocking 200ms on cold disk

How It Works#

Continuous profilers sample call stacks at a fixed frequency (typically 100 Hz) and aggregate them into flame graphs:

100% ──── handleRequest()
├── 35% ── validateOrder()
│   ├── 20% ── JsonSchema.validate()
│   └── 15% ── RegexMatcher.match()
├── 45% ── processPayment()
│   ├── 40% ── HttpClient.send()    ← 40% of request time waiting on payment API
│   └──  5% ── PaymentMapper.map()
└── 20% ── saveOrder()
    ├── 15% ── JdbcTemplate.update()
    └──  5% ── AuditLogger.log()

Profiling Tools#

ToolTypeLanguagesBackend
Pyroscope (Grafana)Open sourceGo, Java, Python, Ruby, .NET, Rust, Node.jsSelf-hosted or Grafana Cloud
Datadog Continuous ProfilerSaaSJava, Python, Go, .NET, Ruby, Node.js, PHPDatadog
ParcaOpen source (CNCF)Any (eBPF-based, no agent per language)Self-hosted
async-profilerLibraryJava/JVMLocal or integrate with backends

Pyroscope Integration with Go#

import "github.com/grafana/pyroscope-go"

func main() {
    pyroscope.Start(pyroscope.Config{
        ApplicationName: "order-service",
        ServerAddress:   "http://pyroscope:4040",
        ProfileTypes: []pyroscope.ProfileType{
            pyroscope.ProfileCPU,
            pyroscope.ProfileAllocObjects,
            pyroscope.ProfileAllocSpace,
            pyroscope.ProfileInuseObjects,
            pyroscope.ProfileInuseSpace,
            pyroscope.ProfileGoroutines,
            pyroscope.ProfileMutexCount,
            pyroscope.ProfileMutexDuration,
            pyroscope.ProfileBlockCount,
            pyroscope.ProfileBlockDuration,
        },
        Tags: map[string]string{
            "environment": "production",
            "region":      "eu-west-1",
        },
    })
    // ... application code
}

Trace-to-Profile Correlation#

The most powerful profiling feature: link a slow trace span directly to its flame graph. When a trace shows processPayment() took 2 seconds, click through to see exactly which function calls consumed that time.

Grafana supports this natively with Tempo + Pyroscope integration — span profiling attaches profile data to individual trace spans.

eBPF Observability#

eBPF (Extended Berkeley Packet Filter) is a Linux kernel technology that allows running sandboxed programs inside the kernel without modifying kernel source or loading kernel modules. For observability, this means collecting telemetry with near-zero overhead and without modifying applications.

What eBPF Can Observe#

DomainWhat eBPF SeesTraditional Alternative
NetworkEvery TCP connection, DNS lookup, HTTP requesttcpdump, application-level metrics
File SystemEvery file open, read, write, deleteAudit logs, inotify
ProcessSystem calls, context switches, schedulingstrace (high overhead), /proc
SecurityUnexpected syscalls, process execution, file accessSELinux audit, seccomp

eBPF Observability Tools#

ToolPurposeNotes
CiliumKubernetes networking + observabilityL3/L4/L7 visibility, service map, Hubble UI
Pixie (CNCF)Auto-instrumented Kubernetes observabilityNo code changes, captures HTTP/gRPC/DNS/DB
Grafana BeylaeBPF-based auto-instrumentationHTTP/gRPC metrics and traces with zero code
bpftraceAd-hoc kernel tracingDTrace-like scripting for Linux
ParcaeBPF-based continuous profilingLanguage-agnostic CPU profiling

Grafana Beyla Example#

Beyla uses eBPF to automatically instrument HTTP and gRPC services without any SDK:

# beyla-config.yaml
open_port: 8080
otel_metrics_export:
  endpoint: http://otel-collector:4318/v1/metrics
otel_traces_export:
  endpoint: http://otel-collector:4318/v1/traces
attributes:
  kubernetes:
    enable: true

Deploy as a sidecar or DaemonSet — it intercepts syscalls to observe HTTP requests, producing metrics and traces without touching your application code.

bpftrace One-Liners#

# Count system calls by process
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'

# Histogram of read() sizes
bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret > 0/ { @bytes = hist(args->ret); }'

# Track TCP connections by destination port
bpftrace -e 'kprobe:tcp_connect { @[args->sk->__sk_common.skc_dport] = count(); }'

# Latency of DNS lookups
bpftrace -e 'uprobe:/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo { @start[tid] = nsecs; }
             uretprobe:/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo { @ns = hist(nsecs - @start[tid]); delete(@start[tid]); }'

When to Use eBPF#

Use CaseWhy eBPF
Observing services you cannot modify (third-party, legacy)No code changes required
Network-level visibility (who talks to whom)Sees all TCP/UDP, not just instrumented calls
Ultra-low-overhead profilingKernel-level, < 1% overhead
Security monitoringSees syscalls, file access, process execution
Kubernetes service mesh alternativeL7 visibility without sidecar proxy overhead

Synthetic Monitoring#

Synthetic monitoring runs scripted tests against your production systems at regular intervals — simulating user behaviour to detect issues before real users encounter them.

Types of Synthetic Tests#

TypeWhat It TestsFrequencyExample
HTTP pingEndpoint availability and latencyEvery 30–60sGET /health returns 200 in < 500ms
API testFull API workflowEvery 1–5minCreate order → get order → verify fields
Browser testEnd-to-end user journeyEvery 5–15minLogin → search → add to cart → checkout
SSL/TLS checkCertificate validityEvery 1hCert expires in > 30 days
DNS checkDNS resolutionEvery 1minapi.example.com resolves correctly

Grafana Synthetic Monitoring#

# k6 synthetic test
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  frequency: '60s',
  locations: ['eu-west-1', 'us-east-1', 'ap-southeast-1'],
};

export default function () {
  const res = http.get('https://api.example.com/health');

  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 500ms': (r) => r.timings.duration < 500,
    'body contains ok': (r) => r.body.includes('ok'),
  });
}

Synthetic vs Real User Monitoring (RUM)#

AspectSyntheticRUM
TrafficScripted, consistentReal user behaviour
CoveragePredefined paths onlyAll user journeys
Availability signalDetect outages before usersDetect issues users actually hit
Geographic coverageConfigurable test locationsWherever users are
BaselineStable (same test, same conditions)Variable (device, network, behaviour)

Best practice: Use both. Synthetics detect outages during low-traffic periods (midnight); RUM catches issues that only affect specific devices or user segments.

Chaos Engineering Observability#

Chaos engineering deliberately introduces failures to test system resilience. Observability is essential — without it, you can’t measure the impact of injected failures.

The Chaos-Observability Loop#

1. Hypothesis    → "If payment-service fails, checkout degrades gracefully"
2. Observe       → Record baseline SLIs (error rate, latency, throughput)
3. Inject fault  → Kill payment-service pods / inject 500ms latency / drop 50% of packets
4. Observe       → Monitor SLIs during the experiment
5. Analyse       → Compare actual behaviour to hypothesis
6. Improve       → Fix gaps (missing circuit breaker, no fallback, bad timeout)

Common Chaos Experiments#

ExperimentWhat It TestsObservability Signal
Kill a pod/instanceAuto-recovery, load balancingError rate, recovery time
Inject latency (500ms)Timeout configuration, circuit breakersP99 latency, downstream impact
Drop network packets (50%)Retry logic, connection handlingRetry rate, error rate
Fill disk to 95%Disk space alerting, log rotationDisk usage alerts, application errors
Exhaust CPU (stress-ng)Autoscaling, throttlingCPU metrics, request queuing
Corrupt DNS responsesDNS failover, cachingDNS error metrics, resolution time

Chaos Tools#

ToolTypeIntegration
LitmusKubernetes-native, CNCFChaosEngine CRDs, Prometheus metrics
Chaos MeshKubernetes-native, CNCFCRDs, Grafana dashboard
AWS Fault Injection ServiceAWS-managedCloudWatch integration
GremlinSaaSDatadog, PagerDuty integration
ToxiproxyProxy-based (Shopify)Inject latency/errors at network level

AIOps and Machine Learning#

AIOps applies machine learning to observability data to automate detection, correlation, and remediation.

Anomaly Detection#

Instead of static thresholds (“alert if error rate > 1%”), ML models learn normal patterns and alert on deviations:

Normal pattern: Error rate is 0.05% on weekdays, 0.02% on weekends, spikes to 0.3% during deploys
Static threshold: Alert if > 1%    → Misses the 0.3% anomaly during non-deploy hours
Anomaly detection: Alert if > 3σ from expected value → Catches 0.3% if no deploy occurred
ApproachMethodWhen to Use
Static thresholdFixed value (e.g., > 1%)Well-understood, stable metrics
Dynamic thresholdMoving average + standard deviationMetrics with predictable patterns
Seasonal modelAccounts for daily/weekly cyclesTraffic metrics, business metrics
ClusteringGroups similar anomalies togetherReducing alert noise across many services

Automated Root Cause Analysis#

Advanced platforms correlate multiple signals to suggest root cause:

Alert: Error rate increased on order-service
Correlated signals:
  - Deploy v2.14.3 occurred 3 minutes before
  - DB connection pool utilisation jumped to 100%
  - payment-service latency increased 10x
  - No infrastructure changes detected

Suggested root cause: Deploy v2.14.3 introduced a regression
affecting database performance. Recommend rollback.

Current State of AIOps#

What Works TodayWhat’s Aspirational
Anomaly detection on individual metricsMulti-signal causal analysis
Alert grouping and deduplicationFully automated remediation
Log pattern clusteringNatural language incident investigation
Forecast-based capacity alertsSelf-healing systems

Realistic assessment: AIOps is most valuable for reducing alert noise (clustering, deduplication, anomaly detection) and suggesting correlations. Fully automated root cause analysis and remediation remain research problems for most environments.

Observability Pipeline Optimisation#

As telemetry volume grows, controlling cost and performance becomes critical.

Cost Reduction Strategies#

StrategySavingsTrade-off
Tail-based trace sampling80–95% trace volume reductionRequires collector memory for buffering
Log level filtering at collector50–70% log volume reductionLose DEBUG/TRACE logs
Metric aggregation (recording rules)Reduce query loadPre-computed views only
Log archival (cold storage)90% storage cost reductionQuery latency for archived logs
Attribute dropping (remove noisy fields)10–30% per-event size reductionLose some diagnostic detail

OpenTelemetry Collector Pipeline for Cost Control#

processors:
  # Filter out health check spans
  filter/healthcheck:
    traces:
      span:
        - 'attributes["http.route"] == "/health"'
        - 'attributes["http.route"] == "/ready"'

  # Drop DEBUG logs
  filter/loglevel:
    logs:
      log_record:
        - 'severity_number < 9'  # Drop below INFO

  # Remove noisy attributes
  attributes/cleanup:
    actions:
      - key: http.user_agent
        action: delete
      - key: http.request.header.cookie
        action: delete

  # Tail-based sampling
  tail_sampling:
    decision_wait: 10s
    policies:
      - name: errors
        type: status_code
        status_code: {status_codes: [ERROR]}
      - name: slow
        type: latency
        latency: {threshold_ms: 2000}
      - name: sample
        type: probabilistic
        probabilistic: {sampling_percentage: 5}

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [filter/healthcheck, tail_sampling, attributes/cleanup, batch]
      exporters: [otlp/tempo]
    logs:
      receivers: [otlp]
      processors: [filter/loglevel, attributes/cleanup, batch]
      exporters: [otlp/loki]

Key Takeaways#

  • Continuous profiling answers the “why is this slow?” question that traces cannot — it links flame graphs to trace spans, showing exactly which functions consume time and resources
  • eBPF enables zero-instrumentation observability by hooking into the kernel; tools like Cilium, Pixie, and Beyla provide network, application, and profiling visibility without SDK changes
  • Synthetic monitoring detects outages before users do — run HTTP, API, and browser tests from multiple geographies at regular intervals; combine with RUM for full coverage
  • Chaos engineering requires strong observability: you must measure baseline SLIs before injecting failures, monitor during the experiment, and compare actual behaviour to your hypothesis
  • AIOps is most practically useful today for anomaly detection, alert deduplication, and log clustering — fully automated root cause analysis remains aspirational for most organisations
  • Telemetry cost control is an ongoing concern: use tail-based sampling, log level filtering, attribute pruning, and cold storage archival to reduce volume by 80%+ without losing diagnostic value