FeelingLife FeelingLife
首页
  • Go

    • Go基础知识
  • Python

    • Python进阶
  • 操作系统
  • 计算机网络
  • MySQL
  • 学习笔记
  • 常用到的算法
  • Docker
  • Kubernetes
  • Observability
  • 容器底层
其他技术
  • 友情链接
  • 收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

xuqil

一介帆夫
首页
  • Go

    • Go基础知识
  • Python

    • Python进阶
  • 操作系统
  • 计算机网络
  • MySQL
  • 学习笔记
  • 常用到的算法
  • Docker
  • Kubernetes
  • Observability
  • 容器底层
其他技术
  • 友情链接
  • 收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 初探可观测性
  • OpenTelemetry

    • 初探OpenTelemetry
    • OpenTelemetry 的基本使用
    • Gin 接入 OpenTelemetry 和 Prometheus
      • 接入 OpenTelemetry
      • 接入 Prometheus
  • 《Observability》
  • OpenTelemetry
xuqil
2023-05-08
目录

Gin 接入 OpenTelemetry 和 Prometheus

# Gin 接入 OpenTelemetry 和 Prometheus

项目地址:https://github.com/xuqil/observability/tree/main/trace/gin/middleware

# 接入 OpenTelemetry

package opentelemetry

import (
	"github.com/gin-gonic/gin"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/trace"
)

const instrumentationName = "github.com/xuqil/observability/trace/gin/middlewares/opentelemetry"

type MiddlewareBuilder struct {
	Tracer trace.Tracer
}

func (m MiddlewareBuilder) Build() gin.HandlerFunc {
	if m.Tracer == nil {
		m.Tracer = otel.GetTracerProvider().Tracer(instrumentationName)
	}
	return func(ctx *gin.Context) {
		reqCtx := ctx.Request.Context()
		// 尝试和客户端的 trace 结合在一起
		reqCtx = otel.GetTextMapPropagator().Extract(reqCtx, propagation.HeaderCarrier(ctx.Request.Header))

		reqCtx, span := m.Tracer.Start(reqCtx, "unknown")
		defer span.End()

		span.SetAttributes(attribute.String("http.method", ctx.Request.Method))
		span.SetAttributes(attribute.String("http.url", ctx.Request.URL.String()))
		span.SetAttributes(attribute.String("http.scheme", ctx.Request.URL.Scheme))
		span.SetAttributes(attribute.String("http.host", ctx.Request.Host))

		ctx.Request = ctx.Request.WithContext(reqCtx)

		ctx.Next()

		span.SetName(ctx.FullPath())
		span.SetAttributes(attribute.Int("http.status", ctx.Writer.Status()))
	}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 接入 Prometheus

package prometheus

import (
	"github.com/gin-gonic/gin"
	"github.com/prometheus/client_golang/prometheus"
	"strconv"
	"time"
)

type MiddlewareBuilder struct {
	Namespace string
	Subsystem string
	Name      string
	Help      string
}

func (m MiddlewareBuilder) Build() gin.HandlerFunc {
	vector := prometheus.NewSummaryVec(prometheus.SummaryOpts{
		Name:      m.Name,
		Subsystem: m.Subsystem,
		Namespace: m.Namespace,
		Help:      m.Help,
		Objectives: map[float64]float64{
			0.5:   0.01,
			0.75:  0.01,
			0.90:  0.01,
			0.99:  0.001,
			0.999: 0.0001,
		},
	}, []string{"pattern", "method", "status"})

	prometheus.MustRegister(vector)
	return func(ctx *gin.Context) {
		startTime := time.Now()
		defer func() {
			duration := time.Now().Sub(startTime).Milliseconds()
			pattern := ctx.FullPath()
			if pattern == "" {
				pattern = "unknown"
			}
			vector.WithLabelValues(pattern, ctx.Request.Method,
				strconv.Itoa(ctx.Writer.Status())).Observe(float64(duration))
		}()
		ctx.Next()
	}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
上次更新: 2024/05/29, 06:25:22
OpenTelemetry 的基本使用

← OpenTelemetry 的基本使用

最近更新
01
ip命令的使用
11-02
02
veth-pair容器中的网络
11-02
03
sendfile、aio和directIO
09-25
更多文章>
Theme by Vdoing | Copyright © 2018-2025 FeelingLife | 粤ICP备2022093535号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式