去年小弟剛好也有提到, Metrics 淺談
裡面有提到Prometheus提供了4種Metric types
OTel Instrument API定義了一種Instrument的Kind
昨天有提到有
能在OTel metric instrument看到interface
Prometheus Compatibility
這裡官方有提供Prometheus與OTel 兩者互換資料模型的部份.
目前文件上, 各自只有一種type無法支持.
這主要用在Promethus的資料與協議, 可以轉成OTLP, 打給OTel collector.
或者OTlp轉成PRometheus資料與協議, 直接提供給Prometheus存儲運算.
因為OTel有提供OTLP metric exporter
也有提供Prometheus metric exporter
之前提到OpenTelemetry其實是個框架(framework).
很多情況下, 它會自動檢測, 攔截一些資訊, 注入到訊息裡豐富它.
這點是Prometheus預設做不到的.
另一點是Prometheus內部有資料庫能存儲數據.
但OpenTelemetry卻沒有, Collector也只是幫忙處理跟轉發, 沒存儲功能.
所以OTel的metric data, 最終還是會回到Prometheus或是跟Prometheus兼容的系統中.
此外OpenTelemetric 在metric data上是可以顯示delta, 而不是累積.
這點Prometheus在資料表達上目前沒辦法.
OpenTelemtric還多了ExponentialHistogram, 是一種Histogram的替代表示.
這目前Prometheus也還沒支持.
OpenTelemtric的metric value支援integer, 但Prometheus只有floats64
OTel metric instrument參考
所以我覺得在資料表達上, Prometheus是OpenTelemetry的子集合.
呼應設計目標, 在語意跟模型上針對流行的部份做擴充與轉譯.
上圖是引入trace與metric, OTel產生的metrics.
會引入一些Span內的資訊, 像圖片裡面的 span_kind="SPAN_KIND_SERVER"
也很方便跟Resource Context組合
res, err := resource.New(context.Background(),
resource.WithFromEnv(),
resource.WithProcess(),
resource.WithTelemetrySDK(),
resource.WithHost(),
resource.WithAttributes(
semconv.ServiceNameKey.String("ITHOME_14th_Server"),
attribute.String("environment", "LOCAL"),
),
)
在Provider建立時給進去, 會在產生Metric時, 把這些context的一些資訊給自動merge.
能看到上圖很多像是environment, host_name, process_runtime_description,
自定義的service_name等等的
// mergeAttrs merges the export.Record's attributes and resources into a
// single set, giving precedence to the record's attributes in case of
// duplicate keys. This outputs one or both of the keys and the values as a
// slice, and either argument may be nil to avoid allocating an unnecessary
// slice.
func mergeAttrs(record export.Record, res *resource.Resource, keys, values *[]string) {
if keys != nil {
*keys = make([]string, 0, record.Attributes().Len()+res.Len())
}
if values != nil {
*values = make([]string, 0, record.Attributes().Len()+res.Len())
}
// Duplicate keys are resolved by taking the record attribute value over
// the resource value.
mi := attribute.NewMergeIterator(record.Attributes(), res.Set())
for mi.Next() {
attr := mi.Attribute()
if keys != nil {
*keys = append(*keys, sanitize(string(attr.Key)))
}
if values != nil {
*values = append(*values, attr.Value.Emit())
}
}
}
在Prometheus有啟用Exemplars, 會自動代入traceID
OTel Sum Aggregation
OTel Metrics API
Prometheus vs. OpenTelemetry Metrics: A Complete Guide