Skip to content

Vaxilaトレースのストレージ構造

Mackerelのトレーシングバックエンド(kamatari)はS3にParquetファイルを置いている。たぶん構造としては

organization_id=(org_id)/
dt=(日付)/
(org_id)_(plan_id)_(timestamp)_1.parquet

最後の 1 はファイルタイプらしいけど、既存のファイルはだいたい 1 のようにみえる。(timestamp) はトレースの作成日ではなくてファイルを処理した時刻。(plan_id) が変われば別のトレースとして扱うことになるが、フリープランからスタンダードプランに移行することもあるのでこれは正しい。

ではトレースIDから実態のファイルをどうやって探すのかでいえば、PostgreSQLに public.trace_metas テーブルがあり、そのテーブルから path カラムを調べることで実現できる。

SELECT * FROM trace_metas WHERE organization_id = (org_id) AND trace_id = '\x(trace_id)'

このとき、1つのトレースIDが複数のParquetにまたがる場合がある。なので全てのParquetをまとめて1つのトレースとして扱う必要がある。トレースを構成するParquetを集めている処理はtrace.Fetcher.FetchTraceSpansで実装されている。

1つのparquetに複数のトレースIDが入っている。たぶん1つのスパンが以下のようなJSONになってる。

{
"trace_id": "xxx",
"span_id": "xxx",
"trace_state": "",
"parent_span_id": "xxx",
"name": "POST",
"kind": 3,
"start_time_unix_nano": "1749451840735637692",
"end_time_unix_nano": "1749451840809668108",
"attributes": [
{
"key": "network.protocol.version",
"value": "1.1",
"value_int": null,
"value_double": null,
"value_bool": null,
"value_kv_list": null,
"value_array": null,
"value_type": "1"
}, { ... }
],
"resource": {
"attributes": [ ... ],
},
"scope": { ... },
}