如何从OpenTelemetry Traces提取指标创建Dynatrace自定义告警
Dynatrace 从已接入OTel Traces提取ConfigurationData.find耗时指标实现方案
方案一:Dynatrace 控制台配置Span自定义指标(零代码改动,优先选)
不需要修改Go服务代码,直接利用Dynatrace原生的Span转指标能力实现:
- 进入Dynatrace控制台,打开Settings > Metrics > Span metrics页面,新建自定义Span指标
- 配置Span匹配规则,精准过滤目标Span:
- 服务范围:选中当前Go业务服务对应的实体,避免跨服务抓错同名Span
- 核心匹配条件:
Span.operation.name精确等于ConfigurationData.find - 额外校验条件(可选但推荐):增加属性匹配规则
db.system == mongodb,OTel官方Go MongoDB instrumentation会自动给所有数据库操作Span打这个属性,能100%避免和其他业务自定义同名Span混淆
- 指标值配置:度量项选
Span.duration,按需勾选需要的聚合计算规则:原始值、平均值、p50/p95/p99分位值、调用次数都可以选 - 维度配置:只保留排查需要的维度即可,比如
service.name、db.mongodb.collection、status.code,不要保留高基数维度(比如请求ID、用户ID)避免指标成本爆炸 - 保存配置后等待1-2分钟,Dynatrace会实时从上报的Traces流中提取对应指标,默认指标名为
dt.span.custom.<你自定义的指标标识>,比如可以命名为mongodb_config_find_duration
方案二:Go服务侧直接生成同源OTel指标(适合强定制需求场景)
如果需要自定义指标维度、或者对指标上报实时性要求更高,可以直接在OTel SDK层加处理逻辑,从Span生成指标上报,不需要额外改业务逻辑:
- 在初始化OTel TracerProvider时,追加一个自定义SpanProcessor,专门拦截处理目标Span
- 参考实现代码:
import ( "context" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" sdktrace "go.opentelemetry.io/otel/sdk/trace" ) type mongoConfigFindMetricProcessor struct { durationHisto metric.Int64Histogram } // 初始化Processor的时候传入已经初始化好的Meter实例 func NewMongoConfigFindMetricProcessor(meter metric.Meter) *mongoConfigFindMetricProcessor { histo, _ := meter.Int64Histogram( "mongodb.config.find.duration", metric.WithUnit("ms"), metric.WithDescription("Duration of ConfigurationData.find MongoDB operation"), ) return &mongoConfigFindMetricProcessor{durationHisto: histo} } func (p *mongoConfigFindMetricProcessor) OnStart(parent context.Context, s sdktrace.ReadWriteSpan) {} func (p *mongoConfigFindMetricProcessor) OnEnd(s sdktrace.ReadOnlySpan) { // 只匹配目标操作Span if s.Name() != "ConfigurationData.find" { return } // 提取需要的维度属性 var attrs []attribute.KeyValue for _, attr := range s.Attributes() { switch attr.Key { case "db.mongodb.collection", "status.code", "db.mongodb.error_code": attrs = append(attrs, attr) } } // 计算Span耗时,上报直方图指标 durationMs := s.EndTime().Sub(s.StartTime()).Milliseconds() p.durationHisto.Record(context.Background(), durationMs, metric.WithAttributes(attrs...)) } func (p *mongoConfigFindMetricProcessor) Shutdown(ctx context.Context) error { return nil } func (p *mongoConfigFindMetricProcessor) ForceFlush(ctx context.Context) error { return nil } // 初始化TracerProvider时注册这个Processor即可 // tp := sdktrace.NewTracerProvider( // sdktrace.WithSpanProcessor(NewMongoConfigFindMetricProcessor(meter)), // // 其他原有配置:exporter、resource等 // )
- 这种方式生成的指标和Traces完全同源,不会出现控制台规则匹配漏抓的问题,还可以按需追加业务自定义维度。
自定义告警配置
两种方案生成的指标都可以直接用来配置告警:
- 进入Dynatrace Alerting > Metric events页面,新建告警规则
- 指标选择前面创建的
ConfigurationData.find耗时指标,按需配置聚合粒度、分组维度(比如按服务、Mongo集合分组) - 配置触发阈值:比如p95耗时连续5分钟超过500ms、或错误调用占比超过1%即可触发
- 绑定通知渠道后保存规则,告警就会生效
注意:如果用第一种控制台提取指标的方案,提前确认OTel Collector或者服务侧的OTel导出配置没有过滤掉
Span.operation.name、db.system这类核心Span属性,否则会出现规则匹配不到Span的问题。
内容的提问来源于stack exchange,提问作者Rio Simo
相关产品推荐
相关产品推荐

