原副标题:如前所述 Grafana LGTM 可探测网络平台的构筑
可探测性现期归属于云原生植物三个较为火的热门话题,它牵涉的文本非常多,不但牵涉多种不同遥感统计数据(信号),比如笔记(log)、分项(metric)、分布式系统跟踪(trace)、已连续预测(continuous profiling)、 该事件(event);还牵涉遥感统计数据各开发周期管理工作,比如说曝露、收集、储存、排序查阅、标准化看板。
现期街道社区有关开放源码商品非常多,各有各的竞争优势,那时他们就来看一看怎样采用 Grafana LGTM 控制技术栈(Grafana、Loki、Tempo、Mimir)加速构筑三个他们的可探测性网络平台。
透过责任编辑你将介绍:
怎样在 Go 流程中求出 metric、trace、log、和它间的关连 TraceID
怎样采用 OTel Collector 展开 metric、trace 搜集
怎样采用 OTel Collector Contrib 展开笔记搜集
如何布署 Grafana Mimir、Loki、Tempo 展开 metric、trace、log 统计数据储存
怎样采用 Grafana 制做标准化可探测性上证指数
为的是此次的课堂教学,他们提早撰写了三个 Go Web 流程,它提供更多 /v1/books 和 /v1/books/1 三个 HTTP USB。
当允诺USB时,会先出访 Redis 内存,假如未投弹将竭尽全力出访 MySQL;整座允诺会详尽历史记录有关笔记、整座链路各期初始化情形和总体允诺延后,当允诺延后 >200ms 时,会透过 Prometheus examplar 历史记录此次允诺的 TraceID,用作该允诺的笔记、初始化链关连。
浏览并新体验实例
他们早已提早将实例流程上传至 github,因此您能采用 git 展开浏览:
git clone https://github.com/grafanafans/prometheus-exemplar.git
cd prometheus-exemplar
采用 docker-compose 启动实例流程:
docker-compose up -d
这个命令会启动以下流程:
采用单节点模式分别启动三个 Mimir、Loki、Tempo
启动三个 Nginx 作为标准化可探测网络平台查阅入口,后端对接 Mimir、Loki、Tempo
启动 demo app, 并启动其依赖的 MySQL 和 Redis, demo app 能使用 http://localhost:8080 出访
启动 Grafana 并导入预设的统计数据源和 demo app 标准化看板,能采用 http://localhost:3000 出访
整座布署架构如下:

当流程布署完成后,他们能采用 wrk 展开 demo app USB批量允诺:
wrk http://localhost:8080/v1/books
wrk http://localhost:8080/v1/books/1
最后透过 http://localhost:3000 页面出访对应的看板:

细节说明
采用 Promethues Go SDK 求出 metrics
在 demo app 中,他们采用 Prometheus Go SDK 作为 metrics 求出,这里没有采用 OpenTelmetry SDK 主要因为当前版本(v0.33.0)还不支持 exemplar, 代码逻辑大致为:
func Metrics(metricPath string, urlMapping func(string) string) gin.HandlerFunc <{p> httpDurationsHistogram := prometheus.NewHistogramVec(prometheus.HistogramOpts<{p> Name: “http_durations_histogram_seconds”,
Help: “Http latency distributions.”,
Buckets: []float64{0.05, 0.1, 0.25, 0.5, 1, 2},
}, []string{“method”, “path”, “code”})
prometheus.MustRegister(httpDurationsHistogram)
return func(c *gin.Context) <{p> …..
observer := httpDurationsHistogram.WithLabelValues(method, url, status)
observer.Observe(elapsed)
if elapsed > 0.2 <{p> observer.(prometheus.ExemplarObserver).ObserveWithExemplar(elapsed, prometheus.Labels<{p> “traceID”: c.GetHeader(api.XRequestID),
})
}
}
}
采用 OTLP HTTP 求出 traces
采用 OTel SDK 展开 trace 埋点:
func (*MysqlBookService) Show(id string, ctx context.Context) (item *Book, err error) <{p> _, span := otel.Tracer().Start(ctx, “MysqlBookService.Show”)
span.SetAttributes(attribute.String(“id”, id))
defer span.End()
// mysql qury random time duration
time.Sleep(time.Duration(rand.Intn(250)) * time.Millisecond)
err = db.Where(Book{Id: id}).Find(&item).Error
return
}
采用 OLTP HTTP 展开求出:
func SetTracerProvider(name, environment, endpoint string) error <{p> serviceName = name
client := otlptracehttp.NewClient(
otlptracehttp.WithEndpoint(endpoint),
otlptracehttp.WithInsecure(),
)
exp, err := otlptrace.New(context.Background(), client)
if err != nil <{p> return err
}
tp := tracesdk.NewTracerProvider(
tracesdk.WithBatcher(exp),
tracesdk.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(serviceName),
attribute.String(“environment”, environment),
)),
)
otel.SetTracerProvider(tp)
return nil
}
结构化笔记
这里他们采用 go.uber.org/zap 包展开结构化笔记输出,并输出到 /var/log/app.log 文件,每个允诺开始时,注入 traceID:
cfg := zap.NewProductionConfig()
cfg.OutputPaths = []string{“stderr”, “/var/log/app.log”}
logger, _ := cfg.Build()
logger.With(zap.String(“traceID”, ctx.GetHeader(XRequestID)))
采用 OTel Collector 展开 metric、trace 搜集
因为 demo app 的 metrics 采用 Prometheus SDK 求出,因此 OTel Collector 需要采用 Prometheus recevier 展开抓取,然后我们再透过 Prometheus remotewrite 将统计数据 push 到 Mimir。
针对 traces,demo app 采用 OTLP HTTP 展开了求出,所有 Collector 需要用 OTP HTTP recevier 展开接收,最后再采用 OTLP gRPC 将统计数据 push 到 Tempo,对应配置如下:
receivers:
otlp:
protocols:
grpc:
http:
prometheus:
config:
scrape_configs:
– job_name: app
scrape_interval: 10s
static_configs:
– targets: [app:8080]
exporters:
otlp:
endpoint: tempo:4317
tls:
insecure: true
prometheusremotewrite:
endpoint: http://mimir:8080/api/v1/push
tls:
insecure: true
headers:
X-Scope-OrgID: demo
processors:
batch:
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
metrics:
receivers: [prometheus]
processors: [batch]
exporters: [prometheusremotewrite]
采用 OTel Collector Contrib 展开 log 搜集
因为他们结构化笔记输出到了/var/log/app.log 文件,因此这里采用 filelog receiver 展开最新笔记读取,最后再经过loki exporter 展开求出,配置如下:
receivers:
filelog:
include: [/var/log/app.log]
exporters:
loki:
endpoint: http://loki:3100/loki/api/v1/push
tenant_id: demo
labels:
attributes:
log.file.name: “filename”
processors:
batch:
service:
pipelines:
logs:
receivers: [filelog]
processors: [batch]
exporters: [loki]
以上就是有关 demo app 可探测性与 Grafana LGTM 控制技术栈集成的核心代码与配置,全部配置请参考 https://github.com/grafanafans/prometheus-exemplar 。
总结
责任编辑他们透过三个简单的 Go 流程,求出了可探测性有关的遥感统计数据,其中包括 metrics、traces、logs, 然后统一由 OTel Collector 展开抓取,分别将三种遥感统计数据推送到 Grafana 的 Mimir、 Tempo、Loki 展开储存,最后再透过 Grafana 标准化看板并展开 metrics、traces、logs 关连查阅。
这里关连的逻辑为采用 Prometheus 的 exemplar 历史记录采样对应的 traceID,然后透过该 traceID 展开有关笔记和 trace 查阅。
