SSS Image 07
| |

Why Enrichment turns Logs into actual Observability

Logs are often treated as if they’re complete, atomic truths: a line appears, something happened, and that’s the end of the story. But anyone who has ever tried to build real observability knows that a single log line rarely tells you anything meaningful. Logs are fragments. Observability is the reconstruction of what those fragments actually mean.

The difference between the two is enrichment.

Enrichment is the process of adding context, stitching related events together, and transforming raw emissions into coherent, interpretable stories. And importantly, no vendor, product, or “standard” owns this layer. You do. Enrichment is where you decide what your logs should say, how they should relate, and what narrative they should ultimately tell.

This is the layer that turns logging into observability.

Enrichment is about Relationships, Not Decoration

A lot of people think enrichment means “add more fields.” That’s part of it, but it’s not the core of it. The real power of enrichment is relational: understanding how log lines connect across time, across processes, and across systems.

Observability isn’t built from isolated events. It’s built from sequences, correlations, and cause and effect chains. Enrichment is the logic that identifies those relationships and produces a single, coherent event that actually reflects what happened.

To illustrate this, let’s use a simple but very real example: Pi hole DNS logs.

The Pi hole Example: Two Lines, One Story

When Pi hole blocks a DNS query, it doesn’t emit one log line. It emits two:

Jul 14 14:48:37 dnsmasq[2169]: query[A] nrdp.logs.netflix.com from 192.168.21.45
Jul 14 14:48:37 dnsmasq[2169]: gravity blocked (CNAME) nrdp.logs.netflix.com is 0.0.0.0

Each line is a fragment. The first line tells you:

  • A DNS query occurred
  • For nrdp.logs.netflix.com
  • From client 192.168.21.45

The second line tells you:

  • The query was blocked
  • By the gravity database
  • And hence resolved to 0.0.0.0

Individually, they’re incomplete. Together, they form a single event: a device attempted to reach a domain, and Pi hole blocked it.

Enrichment is the process of linking these lines and producing a unified, meaningful record.

Look Forward, Look Backward: How Enrichment Thinks

To build that unified record, your enrichment logic needs temporal awareness.

Look backward: Given a “gravity blocked” line, find the query that triggered it.

Look forward: Given a query line, determine what happened next.

Good enrichment reconstructs the conversation happening inside the logs. It groups related lines by timestamp, domain, client, and process, then produces a single enriched event that captures the full picture.

What an Enriched Pi hole Event Looks Like

Here is how those two lines translate into a fully OpenTelemetry compliant log record. All custom fields are placed under attributes, and the top-level structure follows the OTel Log Data Model.

{
  "timestamp": "2024-07-14T14:48:37Z",
  "severityNumber": 5,
  "severityText": "WARN",
  "body": "DNS query blocked by Pi-hole gravity",
  "attributes": {
    "client.ip": "192.168.21.45",
    "dns.domain": "nrdp.logs.netflix.com",
    "dns.action": "blocked",
    "dns.reason": "gravity (CNAME) blacklist",
    "dns.resolved_ip": "0.0.0.0",
    "source": "pihole-dnsmasq",
    "story": "Client 192.168.21.45 attempted to reach nrdp.logs.netflix.com, but Pi-hole gravity blocked it (CNAME → 0.0.0.0)"
  }
}

This enriched event enables:

  1. Endpoint identification
    You know exactly which device made the call (or at least its IP).
  2. Outcome clarity
    You know what Pi hole did and why.
  3. Frequency analysis
    You can measure how often this domain is queried or blocked.

This is observability. Not raw logs, but enriched, correlated, contextualized events.

Aside: Reverse DNS and Hostname Enrichment

You may have noticed that the enriched example uses only the client IP. That’s intentional. Pi hole’s raw logs do not include hostnames, and we haven’t performed any reverse DNS lookup here.

Reverse DNS (PTR lookup) is simply another form of enrichment.  In my work, I’ve seen two possible ways to enrich this information.  Each has their own pros and cons.

As I see it, you have two options:

  1. Perform a reverse DNS lookup for each client IP This gives you hostnames directly from your DNS infrastructure.
    Pros: automatic, consistent, no manual bookkeeping.
    Cons: requires reliable PTR records and may introduce lookup latency.
  2. Maintain a cross reference mapping of IPs to hostnames/descriptions This can be a static file, a CMDB, an inventory system, or a small database.
    Pros: extremely fast, fully under your control, can include human friendly descriptions.
    Cons: requires maintenance and updates when devices change.

Both approaches are valid. Both are forms of enrichment. And both follow the same pattern we’ve already discussed: take a raw field, add context, and produce a more meaningful event.

A secondary enrichment is outside the scope of this post, but you could see how you could enrich this data even more to look like this:

{
  "timestamp": "2024-07-14T14:48:37Z",
  "severityNumber": 5,
  "severityText": "WARN",
  "body": "DNS query blocked by Pi-hole gravity",
  "attributes": {
    "client.ip": "192.168.21.45",
    "client.name": "living-room-tv",
    "dns.domain": "nrdp.logs.netflix.com",
    "dns.action": "blocked",
    "dns.reason": "gravity (CNAME) blacklist",
    "dns.resolved_ip": "0.0.0.0",
    "source": "pihole-dnsmasq",
    "story": "living-room-tv attempted to reach nrdp.logs.netflix.com, but Pi-hole gravity blocked it (CNAME → 0.0.0.0)"
  }
}

Pi hole is Rudimentary, but the Pattern is Universal

Pi hole is a simple example, but the lesson applies everywhere.

Database logs:
A query starts, locks are acquired, a timeout occurs, a rollback happens. Each line is a fragment; enrichment ties them into a transaction story.

Network access logs:
Connections open, authenticate, authorize, deny, retry, close. Enrichment builds a session level narrative instead of isolated events.

Application logs:
Requests traverse multiple services, throw errors, trigger retries. Enrichment correlates trace IDs, user IDs, and error codes into a coherent flow.

Across all domains, the principle holds: A single log line is rarely the whole story. The story lives in the relationships between lines.

Vendor Agnostic Storytelling: You own the Schema

The most important point is that enrichment is yours. No vendor dictates how you correlate logs, what fields you add, or what narrative you build. OpenTelemetry provides structure but not meaning. Meaning comes from you. You decide:

  • How events relate
  • What context matters
  • What fields exist
  • What the final story looks like

Once you embrace that, logs stop being passive emissions and start becoming active explanations.

That’s what turns logging into observability.

Similar Posts

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.