There is an idea from Charity Majors, co-founder of Honeycomb and co-author of Observability Engineering, that sticks with me every time observability comes up. Observability, she says, isn’t about the dashboards you prepared; it’s about being able to ask any question of your system, and understand any state it fell into, without having predicted that question in advance. That means the known-unknowns are the easy part. The hard part, the part that actually matters, is the unknown-unknowns.
I keep seeing observability, and traces in particular, implemented to answer one narrow thing: did service A make its way to service C? That’s useful, but it’s a very small question. It tells you the request completed the hop; not what state your system, your user, or your business logic was in when it did. So when something breaks at 3am, that’s exactly the context which you’re missing. There’s a whole universe of questions you simply cannot answer with that information.
If I add OpenTelemetry to my .NET application with the default initialization and instrumentation, I get more or less low-cardinality data. That’s enough to answer something like “What is our average error rate?” Sounds like a reasonable question, but it gives a fake sense of awareness. It’s too broad to expose the details that led your system to its current state. What if I want to answer something like:
For users on the new mobile client in Germany who experienced latency over 500ms, which feature flag was enabled?
You need more data for that, right?
Improving the signal, improving the questions
OpenTelemetry lets you enrich your telemetry signals with contextual data, as a result expanding the range of questions you can ask your system. With the right context attached, you move from the known-unknowns — the answers to questions you already thought of — to the unknown-unknowns, the answers to questions you had no idea you’d need to ask.
Say your signals carry just these three attributes:
- request-origin-country
- feature-flag-name
- user-agent
Already, that’s nothing. You can ask “which feature flags are failing, and only on which browsers?” or “is this error concentrated in one country?”
Now imagine you also have:
- commit-sha
- release-number
- rollback-flag
- user-tier
- account-id
- user-id
- availability-zone
- retry-count
Look at what that unlocks — questions you can answer without shipping new code, just because the context was already there:
- “Did the error rate spike only for requests running commit abc123, or does it also show up on the previous release, regardless of which feature flags were enabled?”
- “Are users in Germany on release v2.4.1 disproportionately hitting a specific feature flag combination that users in other countries aren’t?”
- “Is the latency regression correlated with a specific release number, or does it track a feature flag that happens to have shipped in that same release?”
- “Of all requests from a given country with a feature flag enabled, what fraction are on the latest commit vs. an older one — and does that fraction explain the difference in error rates between regions?”

Why it’s worth it
Increased context means you need to think about naming conventions so your dimensions stay queryable, and be careful about what you attach: high-cardinality fields like user-id are exactly the ones you don’t want to treat carelessly.
Here is a sample in C # showing that adding context with OpenTelemetry is not rocket science.
// Program.cs — resource-level context, set once for the whole app builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource
.AddService("checkout-api")
.AddAttributes(
new Dictionary<string, object> {
["deployment.release_number"] = Environment.GetEnvironmentVariable("RELEASE_NUMBER") ?? "unknown", ["deployment.commit_sha"] = Environment.GetEnvironmentVariable("GIT_COMMIT_SHA") ?? "unknown", })) .WithTracing(t => t .AddAspNetCoreInstrumentation()
.AddOtlpExporter());
So the choice is not really about metrics versus events. It’s whether your instrumentation stops at confirming what you already expected, or goes one step further and explains what you didn’t. The three pillars will always tell you the error rate or latency spiked. Contextualized, high-cardinality signals are what let you answer more important questions like: for whom, on what, and why?
