iT邦幫忙

2022 iThome 鐵人賽

DAY 9
3
DevOps

淺談DevOps與Observability系列 第 9

淺談OpenTelemetry Specification - Metrics (續)

  • 分享至 

  • xImage
  •  

Prometheus V.S. OpenTelmetry Metrics

Prometheus Metrics

去年小弟剛好也有提到, Metrics 淺談
裡面有提到Prometheus提供了4種Metric types

  • Gauger
  • Counter
  • Histogram
  • Summary

Kind of OTel Instrument

OTel Instrument API定義了一種Instrument的Kind

Sync/Async instrument的差異

  • Sync就是同步計算(聚合); 可以跟Context做關聯
  • Async則是先註冊一組Callback函式, 按照想要的方式調用; 可能是每15秒調用一次做累計這樣; 不能跟Context做關聯

Monotonic/Non-monotoic instrument的差異

  • Monotonic在這裡只會逐漸往上累積, 因為傳入的值是非負數的
  • Non-Monotonic則是可以增加、減少、甚至不變; 像UpDown系列的都是.

昨天有提到有

  • Counter
    • 對應到Prometheus的Counter
    • 非負增量(Monotonic)的Sync instrument
    • 常見用在累積流量, 累積請求數, 累積錯誤數...
  • AsyncCounter
    • 對應到Prometheus的Counter
    • Monotonic的Asnyc instrument
    • 常見用在定期查看每個執行緒或進程佔用的總CPU time
  • UpDownCounter
    • 對應到Prometheus的Gauge
    • 能增量和減量(Non-Monotonic)的Snyc instrument
    • 常見用在計算特定集合的大小數量
  • AsyncUpDownCounter
    • 對應到Prometheus的Gauge
    • Non-Monotonic的Asnyc instrument
    • 捕獲當前活動數, 或是隊列等的大小
  • Histogram
    • 對應到Prometheus的Histogram
    • Monotonic的Sync instrument
    • 產生具有統計意義的任何值, 像是request duration或者response大小的分堆計算數量
  • AsyncGauge
    • 對應到Prometheus的Gauge
    • Non-Monotonic的Asnyc instrument
    • 檢測當前狀態, 像是當下室溫, 當下風扇轉速, 當下執行緒數量.

能在OTel metric instrument看到interface

Prometheus的兼容性

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


上一篇
淺談OpenTelemetry Specification - Metrics
下一篇
淺談OpenTelemetry Specification - Trace
系列文
淺談DevOps與Observability36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

我要留言

立即登入留言