メモ書きレベル。
OpenTelemetryのRubyライブラリは現状、traceのみがひとまず使える状態で、metricsについてはunder developmentな状態となっている。
一応metricsのコード自体は存在し、alphaでリリースしようなPRも出ていたので、試してみた。
GitHubのコードを展開し、PR#1641をマージして、metrics_apiとmetrics_sdkのgemを順にrake build
で作成してインストールする。
metricsのKind実装としてはCounter、UpDownCounter、Histogramの3つのみで、それ以外のGaugeなどは非対応だった。無駄に情報量が多いものの、Histogramでひとまず送るようにしてみる。ほぼサンプルどおり。
require 'opentelemetry-metrics-sdk' require 'opentelemetry-exporter-otlp-metrics' # デフォルト #ENV['OTEL_EXPORTER_OTLP_METRICS_ENDPOINT'] = 'http://localhost:4318/v1/metrics' OpenTelemetry::SDK.configure console_metric_exporter = OpenTelemetry::Exporter::OTLP::MetricsExporter.new OpenTelemetry.meter_provider.add_metric_reader(console_metric_exporter) meter = OpenTelemetry.meter_provider.meter('mymetric') histogram = meter.create_histogram('myhistogram', unit: 'smidgen', description: 'description') histogram.record(123, attributes: {'foo' => 'bar'}) OpenTelemetry.meter_provider.metric_readers.each(&:pull) OpenTelemetry.meter_provider.shutdown
デフォルトのエンドポイントはローカルホストのHTTP protobufに向けたhttp://localhost:4318/v1/metrics
になっている。変更したいときには環境変数OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
を指定してやればいい。
RubyのOTLP Metrics Exporter実装はまだgRPCに対応していないので、gRPCしか受け付けないところに送るにはotel-collectorにまず集約する必要がある(traceのほうはgRPC対応しているので、参考にしながら実装はできるだろう)。どっちにしろデバッグ用途やバッチ処理を含めてotel-collectorを挟んだほうが安全そうではある。
受け口のotel-collectorを設定する。
receivers: otlp: protocols: http: exporters: debug: verbosity: detailed service: pipelines: metrics: receivers: [otlp] exporters: [debug]
Rubyコードから投稿してみる。
2024-06-24T00:01:46.280+0900 info MetricsExporter {"kind": "exporter", "data_type": "metrics", "name": "debug", "resource metrics": 1, "metrics": 1, "data points": 1} 2024-06-24T00:01:46.280+0900 info ResourceMetrics #0 Resource SchemaURL: Resource attributes: -> service.name: Str(unknown_service) -> process.pid: Int(899318) -> process.command: Str(otlp-metric.rb) -> process.runtime.name: Str(ruby) -> process.runtime.version: Str(3.1.2) -> process.runtime.description: Str(ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu]) -> telemetry.sdk.name: Str(opentelemetry) -> telemetry.sdk.language: Str(ruby) -> telemetry.sdk.version: Str(1.4.1) ScopeMetrics #0 ScopeMetrics SchemaURL: InstrumentationScope mymetric Metric #0 Descriptor: -> Name: myhistogram -> Description: description -> Unit: smidgen -> DataType: Histogram -> AggregationTemporality: Delta HistogramDataPoints #0 Data point attributes: -> foo: Str(bar) StartTimestamp: 2024-06-23 15:01:46.27934498 +0000 UTC Timestamp: 2024-06-23 15:01:46.279463724 +0000 UTC Count: 1 Sum: 123.000000 Min: 123.000000 Max: 123.000000 ExplicitBounds #0: 0.000000 ExplicitBounds #1: 5.000000 ExplicitBounds #2: 10.000000 ExplicitBounds #3: 25.000000 ExplicitBounds #4: 50.000000 ExplicitBounds #5: 75.000000 ExplicitBounds #6: 100.000000 ExplicitBounds #7: 250.000000 ExplicitBounds #8: 500.000000 ExplicitBounds #9: 1000.000000 Buckets #0, Count: 0 Buckets #1, Count: 0 Buckets #2, Count: 0 Buckets #3, Count: 0 Buckets #4, Count: 0 Buckets #5, Count: 0 Buckets #6, Count: 0 Buckets #7, Count: 1 Buckets #8, Count: 0 Buckets #9, Count: 0 Buckets #10, Count: 0 {"kind": "exporter", "data_type": "metrics", "name": "debug"}
ちゃんと出ていそう。service.nameが空なのはRuby側のどこかで設定する必要があるな。
エクスポート先のテストとしてMackerelを使ってみよう。MackerelのOTLPはgRPCのみの受け付けなので、受け取ったものをotel-collector経由で渡す。
receivers: otlp: protocols: http: exporters: otlp/mackerel: endpoint: otlp.mackerelio.com:4317 compression: gzip headers: Mackerel-Api-Key: ${env:MACKEREL_APIKEY} debug: verbosity: detailed service: pipelines: metrics: receivers: [otlp] exporters: [otlp/mackerel, debug]
Mackerelのクエリグラフでもmyhistogramが出ることを確認。