美文网首页
prometheus Exemplar

prometheus Exemplar

作者: flystarts | 来源:发表于2024-01-08 20:36 被阅读0次

Prometheus client提供了指标采集上报Exemplar的能力,用法:

注册

histogram = Histogram.builder()
            .name("request_duration_seconds")
            .help("request duration in seconds")
            .unit(Unit.SECONDS)
            .labelNames("http_status").withExemplars()
            .register();

打点

histogram.labelValues("200").observeWithExemplar(nanosToSeconds(System.nanoTime() - start),
                    Labels.of("abc","aa"));

如果用了opentelemetry agent,则会自动添加trace_id和span_id
如果没用,就需要自行添加了

prometheus java client工程里自带了一个demo,在example-exemplars-tail-sampling目录里
项目里有个docker-compose.yaml文件,定义了一个完整的工程,


image.png

demo工程的部署:

1、先编译出jar包
2、cd example-exemplars-tail-sampling
docker-compose up
实际操作的时候发现两个java的容器起不来,报错找不到jar包
懒得去找原因了,写了2个dockerfile,手动执行docker run启动两个java容器

FROM openjdk:11-jre
COPY example-hello-world-app.jar  /example-hello-world-app.jar
COPY opentelemetry-javaagent.jar /opentelemetry-javaagent.jar
ENV OTEL_TRACES_EXPORTER=otlp
ENV OTEL_METRICS_EXPORTER=none
ENV OTEL_LOGS_EXPORTER=none
ENTRYPOINT ["java","-javaagent:opentelemetry-javaagent.jar",  "-jar","/example-hello-world-app.jar"]

然后把docker-compose.yaml里java容器部分删掉,启动剩余的容器
起来后的界面


image.png

看到exemplar里有个trace_id还有traceid,其中后者是我手动加的,前者是框架自动带的
点击按钮可以调到调用链

源码分析

trace_id的注入:ExemplarSampler类的updateCustomExemplar

if (!labels.contains(Exemplar.TRACE_ID) && !labels.contains(Exemplar.SPAN_ID)) {
            labels = labels.merge(doSampleExemplar());
        }

如果exemplar中没有trace_id就会尝试自动获取

try {
            SpanContext spanContext = SpanContextSupplier.getSpanContext();
            if (spanContext != null) {
                if (spanContext.isCurrentSpanSampled()) {  //只有采样的才上报样本
                    String spanId = spanContext.getCurrentSpanId();
                    String traceId = spanContext.getCurrentTraceId();
                    if (spanId != null && traceId != null) {
                        spanContext.markCurrentSpanAsExemplar();
                        return Labels.of(Exemplar.TRACE_ID, traceId, Exemplar.SPAN_ID, spanId);
                    }
                }
            }

这里是从SpanContextSupplier获取context,目前只支持opentelemetry的

 try {
            if (OpenTelemetrySpanContext.isAvailable()) {
                spanContextRef.set(new OpenTelemetrySpanContext());
            }
        } catch (NoClassDefFoundError ignored) {
            // tracer_otel dependency not found
        } catch (UnsupportedClassVersionError ignored) {
            // OpenTelemetry requires Java 8, but client_java might run on Java 6.
        }
        try {
            if (OpenTelemetryAgentSpanContext.isAvailable()) {
                spanContextRef.set(new OpenTelemetryAgentSpanContext());
            }

写Exemplar的
/metrics接口的handler:PrometheusScrapeHandler
先调PrometheusRegistry的scrape接口获取数据,
遍历collector获取数据

for (Collector collector : collectors) {
            MetricSnapshot snapshot = scrapeRequest == null ? collector.collect() : collector.collect(scrapeRequest);
            if (snapshot != null) {
                if (result.containsMetricName(snapshot.getMetadata().getName())) {
                    throw new IllegalStateException(snapshot.getMetadata().getPrometheusName() + ": duplicate metric name.");
                }
                result.metricSnapshot(snapshot);
            }
        }

再调OpenMetricsTextFormatWriter类的writeScrapeTimestampAndExemplar写返回报文

相关文章

网友评论

      本文标题:prometheus Exemplar

      本文链接:https://www.haomeiwen.com/subject/ewwindtx.html