zeekayandHanzo Dev 914fbfaa70 datastoretraces: ingested_at is the server's, not the sender's
The span writer bound ingested_at. In event.span's DDL that one column is three
things at once:

  ReplacingMergeTree(ingested_at)     -- which duplicate survives a merge
  PARTITION BY toDate(ingested_at)    -- which partition the row lands in
  TTL toDateTime(ingested_at) + 30d   -- when the row is deleted

Verified against the live table, not assumed:

  ingested_at  DateTime64(3)  DEFAULT  now64(3)
  ReplacingMergeTree(ingested_at) PARTITION BY toDate(ingested_at)
  ORDER BY (org, trace_id, time, id)
  TTL toDateTime(ingested_at) + toIntervalDay(30)

So binding it handed a sender the retention of its own rows: date a batch
forward and it outlives the policy, date it back and it is deleted on arrival,
and either way it can beat a newer row in a Replacing merge. That is not a
retention policy, it is the absence of one — the column exists to record when WE
received a row, and only the server's clock can mean that.

The column already carries DEFAULT now64(3), so nothing is lost by omitting it.

cloud's planesink.go always omitted it and cloud enforces the rule downstream
(TestRetentionIsNotARequestParameter, apps/analytics/capture_test.go). This
writer was the divergent side — and it is the side that owns the DDL, so the
rule now lives here too: a guard enforced only downstream is one the schema's
own writers can still break.

TestPlaneWritersNeverBindIngestedAt asserts no INSERT template in this package
binds it; re-adding the column to spanSQLTmpl fails it with the reason. It
covers all six write paths, not just the one that was wrong.
TestPlaneTablesAreQualified keeps every INSERT database-qualified, since the
templates take the database as a parameter and an unqualified one would silently
write to another plane with the same table names.

WithNow keeps feeding the support tables' unix_milli, the resource bucket and
the zero-time fallbacks; it no longer feeds event.span.

  ok  github.com/hanzoai/o11y/pkg/datastoretraces

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 22:09:57 -07:00
2021-01-24 13:09:49 +05:30
2026-04-23 19:24:27 -07:00
2021-01-03 18:15:44 +05:30
2026-04-23 19:24:27 -07:00
2026-08-01 20:24:32 -07:00
2026-08-01 20:24:32 -07:00

o11y

o11y

Metrics, traces and logs for the Hanzo platform, in one place. OpenTelemetry on the wire, Hanzo Datastore — an OLAP column store — on disk.

License

Run it

cd deploy/docker
docker compose up -d

Open http://localhost:8080. deploy/install.sh does the same thing with a few more checks, and deploy/docker/docker-compose.ha.yaml is the multi-replica variant.

Send it data

The collector listens for OTLP on 4317 (gRPC) and 4318 (HTTP). Point any OpenTelemetry SDK or the OTel Collector at it:

export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318

Traces, metrics and logs land in Datastore and show up under APM, Logs, Traces, Metrics and Exceptions in the UI. Dashboards and alerting are built on the same queries.

What it is for

Every Hanzo service emits here. It is multi-tenant by design: queries scope by org from the X-Org-Id claim in the JWT, on every panel. It sits behind gateway like the other Hanzo subsystems, and mounts under the unified cloud binary per HIP-0106.

   instrumented app  ->  OTLP  ->  o11y collector
                                       |
                                 Hanzo Datastore
                                       |
                             APM | logs | traces | metrics
                                       |
                          queries scoped by X-Org-Id from JWT
                                       |
                          dashboards | alerting | exceptions

Docs

Lineage

Forked from SigNoz (MIT Expat, copyright 2020–present SigNoz Inc.), synced to upstream main at commit 3e6339019. The import history was squashed, so the root commit here is a Hanzo branding commit rather than upstream's history. See NOTICE.

License

MIT — see LICENSE.

S
Description
Hanzo o11y — OpenTelemetry-native observability (metrics, traces, logs) for the Hanzo platform, backed by Hanzo Datastore.
Readme MIT
128 MiB
Languages
TypeScript 49.3%
Go 42.3%
SCSS 4%
Python 3.4%
JavaScript 0.6%
Other 0.2%