Skip to main content

Development

Land Telemetry - Overview

Overview of Land's telemetry architecture using two parallel pipes - logs and traces - that share a single trace_id for correlation.

Land Telemetry - Overview

Land emits telemetry through two parallel pipes that share one trace_id:

PipeSinkStrengthCost
PostHoghttps://eu.i.posthog.comAggregations, dashboards, retentionOne event per millisecond cap
OTLP127.0.0.1:4318 (Jaeger)Per-request waterfall, parent/childLocal-only, requires collector

Joining the pipes: every PostHog event carries $trace_id and $span_id properties; every Jaeger span carries posthog.event / posthog.distinct_id attributes. A HogQL JOIN against Jaeger’s trace export - or a manual click-through from a PostHog event into the Jaeger UI - reconstructs the full causal chain.

Layout

LayerFile / ModulePipe(s)
Build.shMaintain/Script/PostHogCapture.shPostHog + OTLP
MountainElement/Mountain/Source/Binary/Build/PostHogPlugin/*PostHog
MountainElement/Mountain/Source/IPC/DevLog/EmitOTLPSpan.rsOTLP
MountainElement/Mountain/Source/Telemetry/*OTLP (tracing)
CocoonElement/Cocoon/Source/Telemetry/PostHogBridge.tsPostHog
CocoonElement/Cocoon/Source/Telemetry/OTLPBridge.tsOTLP
WindElement/Wind/Source/Telemetry/Bridge.tsboth
SkyElement/Sky/Source/Function/Telemetry/Bridge.tsboth
OutputElement/Output/Source/Telemetry/*both
Sidecarsre-export Mountain’s macros via the tracing crateOTLP

Event-name convention

Every Land-emitted event uses the prefix land:<element>:<action>:

  • land:build:start, land:build:phase:complete, land:build:complete, land:build:error
  • land:mountain:session:start, land:mountain:ipc:invoke, land:mountain:handler:complete, land:mountain:error
  • land:cocoon:session:start, land:cocoon:entry:load, land:cocoon:entry:loaded, land:cocoon:handler:complete, land:cocoon:stub:active, land:cocoon:error
  • land:wind:layer:ready, land:wind:command:invoke
  • land:sky:build:complete, land:sky:resource:error, land:sky:throttle-dropped
  • land:output:build:complete
  • land:session:start, land:session:end - Sky-emitted aggregates
  • land:boot:timing - workbench boot percentile telemetry
  • land:ipc:marks, land:vscode:marks, land:extension-host:marks, land:all:marks - performance mark batches

PostHog’s $exception autocapture stays as-is; treat it like a PostHog-special name.

Configuration - .env.Land.PostHog

Single source of truth for both pipes. Read at boot by every layer.

VarDefaultEffect
Authorizephc_…PostHog project key
Beamhttps://eu.i.posthog.comPostHog endpoint
ReporttrueMaster toggle for the PostHog pipe
OTLPEndpointhttp://127.0.0.1:4318OTLP collector
OTLPEnabledtrueMaster toggle for the OTLP pipe
CapturetrueMaster telemetry kill - short-circuits both
TraceallRUST_LOG-like span filter
Record0Mirror every payload to a per-session NDJSON
Brand(empty - per-process)distinct_id seed
Throttle5posthog-js client-side rate-limit
Buffer3000Cocoon batch window (ms)
Batch20Cocoon batch size
Cap7Sky $exception/10 s
Replayfalseposthog-js session recording
Askfalseposthog-js surveys

Production = zero bytes

Every layer compiles the telemetry stack out of release builds:

  • Rust (Mountain, Air, Echo, Rest, Grove, Mist) - capture paths gate on cfg!(debug_assertions). LLVM dead-codes them in --release.
  • TypeScript - bridges import lazily through if (process.env.NODE_ENV !== "production") { … } so esbuild’s define collapses the conditional and tree-shakes the SDK.
  • Astro - bundle config check if (import.meta.env.DEV) drops the posthog-js + OTLP SDK paths from astro build.

Plus the runtime kill switches: Capture=false short-circuits all pipes regardless of build mode; Report=false / OTLPEnabled=false flip a single pipe. (Capture is the telemetry switch; the unrelated Disable in .env.Land.Diagnostics controls polyfill / shim loading.)

Bring-up sequence

# Once - bring up the local Jaeger collector.
sh Land/Container/Up.sh

# Every dev session - env vars feed every layer.
export Trace=all Record=1 Capture=true
sh Land/Maintain/Debug/Build.sh --profile debug-electron-bundled

# Run the binary; Mountain initialises both pipes from `.env.Land.PostHog`.
export Trace=all
./Element/Mountain/Target/debug/<binary>

# Inspect:
#   PostHog dashboards: https://eu.posthog.com/project/151871
#   Jaeger UI:          http://127.0.0.1:16686

See Effect-OTel.md for the Effect-TS integration pattern Wind / Cocoon use, and Tree-Shaking.md for the production-zero contract.