OpenTelemetryにおいて、OTel CollectorのReceiverを開発するときやアプリケーションに計装をする際、MetricsのUnit(単位)にどんな文字列を指定すべきかよく分からなかったので調べてみました。
semconv
OpenTelemetryにはSemantic Conventions(semconv)と呼ばれる規約があります。あるデータに対して異なる実装間で共通の名前がついていると便利なので標準を取り決めましょうといった趣旨のものです。Metricsにおいてはメトリック名や属性、単位といったデータについて規約が定められています。
semconvには一般的な規約と具体的な規約があります。具体というと、例えばHTTPに関する規約、AWSなどのクラウドサービスに関する規約、といった形です。「HTTPサーバのリクエストの継続時間を計装する際にはhttp.server.request.duration
という名前にして、属性としてHTTPメソッドを必ず付与し、その属性名はhttp.request.method
にしましょう。またそのメトリックの単位はs
としましょう」といった内容がずらずらと並んでいる形です。
一方で、一般的な規約というのは、具体的な規約を策定する際に指針となる、具体ケースに依存しない規約になります。この規約の単位に関する記述を読めば、今回の謎は解決しそうです。ということで該当箇所を読んでみると以下のような記述があります。
https://opentelemetry.io/docs/specs/semconv/general/metrics/#instrument-units
Units should follow the Unified Code for Units of Measure.
単位はUCUMと呼ばれる別のルールに従うべきだと書かれています。さて、新しい概念が出てきたので今度はそちらを追っていきましょう。
UCUM
UCUMは、数量とその単位を電子的な手段で正確に伝達するために生まれた符号システムです。先ほどの引用上のリンクにアクセスするとその仕様を閲覧することができますが、長大で理解するのが大変なので、簡単にここで紹介します。
電子的な伝達を目的としているため、UCUMにおいて単位はUS-ASCII文字だけで記述されます。残念ながら日本語文字や絵文字は使えません。
SI単位系のように原子単位とその組み合わせ(次元)で表現します。アノテーションといって、個数などの無次元の単位に意味を付与できる仕組みがあるのも特徴です。参考までに、Mackerelで現在使える単位をUCUMで表現してみました。
Mackerelの単位 | OpenTelemetry(UCUM)の単位表記例 |
---|---|
float | 1 |
integer | {request} |
percentage | % |
seconds | s |
milliseconds | ms |
bytes | By |
bytes/sec | By/s |
bits/sec | bit/s |
iops | {operation}/s |
semconvで/sを見かけない件
ところで、/s
とつくような単位はsemconvで見かけることがありません。従来IOPSとして監視していたようなメトリックも、OpenTelemetryのレイヤーではあくまでI/O Operationの数として扱う(単位は{operation}
)雰囲気になっています。
ある時間についての割合というのは計測値そのものではなく計算した結果であり、OpenTelemetryとしては生の計測値をできる限りそのまま取り扱おうという指針なのでしょう。SDKやCollector上で行われる集計(aggregation)を除いて、投稿したメトリックをユーザが扱いやすいように加工するのはExportする先のサービスの責務ということになります。OpenTelemetryの責任範囲(Backendに投稿するまで)やObservability(集計によってデータの解像度は不可逆に低下し、結果として可観測性も失われる)を鑑みると自然な価値観であると言えます。
監視サービスの作り手として、投稿したメトリックを自在に引き便利に取り扱うための、Observability Backendの機能設計や実装の難しさを日々痛感しています。