Vaxilaトレースのストレージ構造
現在のストレージ実装
Section titled “現在のストレージ実装”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で実装されている。
Parquetの構造
Section titled “Parquetの構造”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": { ... },}