optimize(querying) ∧ ¬optimize(writing)
annotate(span, context) where context = {
business ∪ user ∪ technical ∪ outcome
}
high-dimensionality → better-queryability
high-cardinality(userId) → acceptable
∀ span → attach(identity ∪ user ∪ business ∪ performance ∪ outcome)
¬queryable → ¬enough-context
Reference: See Article.md for full article by Boris Tane (loggingsucks.com)
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: wide-events3description: Conceptual guide to wide events (canonical log lines) for observability. Use when thinking about instrumentation strategy, span annotations, or designing what context to capture. Use when this capability is needed.4---56<wide-events>78<philosophy>9traditional := many(log-lines) → grep(services) → hope10wide := one(event) → query(structured) → answer1112optimize(querying) ∧ ¬optimize(writing)13</philosophy>1415<current-practice>16implementation := OTel spans + annotations17wide-events := mental-model for annotation strategy1819annotate(span, context) where context = {20 business ∪ user ∪ technical ∪ outcome21}22</current-practice>2324<dimensionality>25wide-event.fields := {26 identity: {traceId, spanId, service, operation}27 user: {userId, accountTier, accountAge, lifetimeValue}28 business: {featureFlags, experimentGroup, cartValue}29 performance: {durationMs, dbQueryCount, cacheHitRate, retryCount}30 outcome: {success, errorCode, httpStatus}31}3233high-dimensionality → better-queryability34high-cardinality(userId) → acceptable35</dimensionality>3637<anti-patterns>38scattered-logs := console.log("step1") >> console.log("step2") >> ...39low-dimensionality := span.set("success", true) ∧ |fields| < 540technical-only := {http.status, db.queries} ∧ ¬{user, business}41</anti-patterns>4243<correct-pattern>44span.setAttributes({45 "request.operation", "user.id", "user.tier",46 "cart.items", "cart.value", "feature.*",47 "db.query_count", "cache.hit_rate",48 "request.success"49})5051∀ span → attach(identity ∪ user ∪ business ∪ performance ∪ outcome)52</correct-pattern>5354<tail-sampling>55retain(100%) := errors ∨ slow(>p99) ∨ vip56retain(1-5%) := success ∧ fast57</tail-sampling>5859<queryability-test>60before(instrument) → verify(answerable({61 "failures where tier=premium ∧ feature.new_flow=true"62 "p99(latency) group by tier"63 "errors group by featureFlags"64 "full context for user X incident"65}))6667¬queryable → ¬enough-context68</queryability-test>6970<terminology>71cardinality := |unique values| (userId=high, httpMethod=low)72dimensionality := |fields per event| (more → better)73wide-event := canonical-log-line := one comprehensive record74</terminology>7576<when-to-apply>77deciding(span-annotations)78reviewing(instrumentation-coverage)79debugging(incidents) → "what context was missing?"80planning(new-service-observability)81choosing(fields-to-index)82</when-to-apply>8384</wide-events>8586Reference: See `Article.md` for full article by Boris Tane (loggingsucks.com)8788---89> Converted and distributed by [TomeVault](https://tomevault.io/claim/kriegcloud) — claim your Tome and manage your conversions.90<!-- tomevault:4.0:skill_md:2026-04-11 -->