Baggage 是 OpenTelemetry 中的一个重要概念,它允许我们在分布式追踪中传递自定义的上下文信息。Baggage 以键值对的形式存在,可以在服务间传递,使得我们能够在不同的服务中访问这些共享的上下文数据。这在跨服务调用时非常有用,例如,我们可以在客户端设置一些调试信息或用户标识,并在服务端获取这些信息,从而实现更灵活的追踪和监控。
在客户端,我们初始化链路追踪器(tracer),并创建一个根 Span 来表示整个请求的开始。然后,我们使用 gtrace.SetBaggageValue
方法在上下文中设置 Baggage 信息,这些信息将随着 HTTP 请求一起发送到服务端。
package main
import (
"github.com/gogf/gf/contrib/trace/otlphttp/v2"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/gtrace"
"github.com/gogf/gf/v2/os/gctx"
)
const (
ServiceName = "tracing-http-client"
JaegerUdpEndpoint = "127.0.0.1:6831"
)
func main() {
var ctx = gctx.New()
shutdown, err := otlphttp.Init(ServiceName, JaegerUdpEndpoint, "/api/traces")
if err != nil {
g.Log().Fatal(ctx, err)
}
defer shutdown(ctx)
StartRequests()
}
func StartRequests() {
ctx, span := gtrace.NewSpan(gctx.New(), "StartRequests")
defer span.End()
ctx = gtrace.SetBaggageValue(ctx, "name", "hello")
content := g.Client().GetContent(ctx, "http://127.0.0.1:8199/hello")
g.Log().Print(ctx, content)
}
初始化链路追踪器:
otlphttp.Init(serviceName, endpoint, path)
:初始化链路追踪器,连接到指定的 tracing 服务。gctx.New()
:创建一个新的上下文对象。创建根 Span:
gtrace.NewSpan(gctx.New(), "StartRequests")
:创建一个根 Span,表示整个请求的开始。设置 Baggage 信息:
gtrace.SetBaggageValue(ctx, "name", "hello")
:在上下文中设置 Baggage 信息,键为 name
,值为 hello
。发送 HTTP 请求:
g.Client().GetContent(ctx, "http://127.0.0.1:8199/hello")
:发送 HTTP GET 请求,并将上下文传递给请求。package main
import (
"fmt"
"github.com/gogf/gf/contrib/trace/otlphttp/v2"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/net/gtrace"
"github.com/gogf/gf/v2/os/gctx"
"github.com/opentracing/opentracing-go"
"github.com/uber/jaeger-client-go"
jaegerCfg "github.com/uber/jaeger-client-go/config"
"io"
)
const (
ServiceName = "tracing-http-server"
JaegerUdpEndpoint = "localhost:6831"
)
func main() {
var ctx = gctx.New()
shutdown, err := otlphttp.Init(ServiceName, JaegerUdpEndpoint, "/api/otlp/traces")
if err != nil {
g.Log().Fatal(ctx, err)
}
defer shutdown(ctx)
tracer := opentracing.GlobalTracer()
span := tracer.StartSpan("in-process-service")
defer span.Finish()
s := g.Server()
s.Group("/", func(group *ghttp.RouterGroup) {
group.GET("/hello", HelloHandler)
})
s.SetPort(8199)
s.Run()
}
func HelloHandler(r *ghttp.Request) {
ctx, span := gtrace.NewSpan(r.Context(), "StartRequests")
defer span.End()
value := gtrace.GetBaggageVar(ctx, "name").String()
r.Response.Write("hello:", value)
}
初始化链路追踪器:
otlphttp.Init(serviceName, endpoint, path)
:初始化链路追踪器,连接到指定的 tracing 服务。gctx.New()
:创建一个新的上下文对象。创建 HTTP 服务器:
g.Server()
:创建一个新的 HTTP 服务器。s.Group("/", func(group *ghttp.RouterGroup) { ... })
:定义路由组,处理 /hello
路由。处理请求:
gtrace.NewSpan(r.Context(), "HelloHandler")
:创建一个新的 Span,表示请求处理的开始。gtrace.GetBaggageVar(ctx, "name").String()
:从上下文中获取 Baggage 信息,键为 name
。r.Response.Write("hello:", value)
:将获取的 Baggage 信息写入响应中。
客户端提交的
baggage
已经被服务端成功接收到并打印返回。并且客户端在输出日志内容的时候也同时输出了 TraceId
信息。TraceId
是一条链路的唯一ID,可以通过该ID检索该链路的所有日志信息,并且也可以通过该 TraceId
在 Jaeger
系统上查询该调用链路详情。
在 Jaeger
UI 中,我们可以看到这次请求涉及到两个服务:otlp-http-client
和 otlp-http-server
,分别表示HTTP请求的客户端和服务端,并且每个服务中分别涉及到 2
个 span
链路节点。
点击这个 trace
的详情,可以看得到调用链的层级关系。并且可以看得到客户端请求的地址、服务端接收的路由以及服务端路由函数名称。我们这里来介绍一下客户端的 Attributes
信息和 Events
信息,也就是 Jaeger
中展示的 Tags
信息和 Process
信息。
如果您喜欢我的文章,请点击下面按钮随意打赏,您的支持是我最大的动力。
最新评论