本文讲解怎么快速部署 Jaeger 服务端,以及 Go 客户端的使用示例~
部署 Jaeger 服务端
写本文时,Jaeger 的版本是 1.19
为了快速入门,Win 系统建议选择 Win 版本的,其它系统可以选择 Docker 版本的,
文本一开始选择 Win 版本的 Jaeger~
下载后,将 jaeger
的目录添加到系统环境变量的 PATH
中,
然后在 CMD 中,运行 jaeger-all-in-one
,
然后在浏览器中浏览 http://localhost:16686
目前没有任何跟踪日志,接下来撸一些实验性代码体验一下~
另外,Jaeger 服务端运行的时候,需要的端口:
端口 | 协议 | 组件 | 作用 |
---|---|---|---|
6831 | UDP | agent(代理客户端) | accept jaeger.thrift over compact thrift protocol |
6832 | UDP | agent(代理客户端) | accept jaeger.thrift over binary thrift protocol |
5778 | HTTP | agent(代理客户端) | serve configs |
16686 | HTTP | query(查询) | serve frontend |
14268 | HTTP | collector(收集器) | accept jaeger.thrift directly from clients |
14250 | HTTP | collector(收集器) | accept model.proto |
9411 | HTTP | collector(收集器) | Zipkin compatible endpoint (optional) |
客户端
你可以在 官方文档 - Client Libraries 找到 Jaeger 各编程语言客户端的源码地址以及使用方法~
OpenTracing tutorials for Java, Go, Python, Node.js and C#
初体验
本节目标:
- 初始化 Tracer
- 创建一个简单 trace
- 给 trace 添加批注(annotate)
大写的 Tracer
指跟踪系统,小写的 trace
指跟踪记录~
官方定义是:
A trace is a data/execution path through the system,
and can be thought of as a directed acyclic graph of spans.
如果你对这个定义很模糊,让我们一起实践后,最后自己再总结一下~
创建一个 hello.go
文件,代码如下: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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68package main
import (
"fmt"
"io"
"os"
"github.com/opentracing/opentracing-go"
_ "github.com/uber/jaeger-client-go"
jaegercfg "github.com/uber/jaeger-client-go/config"
jaegerlog "github.com/uber/jaeger-client-go/log"
"github.com/uber/jaeger-lib/metrics"
)
func initJaeger(serviceName string) (opentracing.Tracer, io.Closer) {
// 官方推荐 生产环境用默认配置就好了~
// cfg := jaegercfg.Configuration{}
// https://github.com/jaegertracing/jaeger-client-go/blob/master/config/example_test.go
// 测试的话,则采集所有跟踪(采样)
// and enable LogSpan to log every span via configured Logger.
cfg := &jaegercfg.Configuration{
ServiceName: serviceName,
// 采样器
Sampler: &jaegercfg.SamplerConfig{
Type: "const",
Param: 1,
},
// (将采样)汇报者
Reporter: &jaegercfg.ReporterConfig{
LogSpans: true,
},
}
// Example logger and metrics factory. Use github.com/uber/jaeger-client-go/log
// and github.com/uber/jaeger-lib/metrics respectively to bind to real logging and metrics
// frameworks.
jLogger := jaegerlog.StdLogger
jMetricsFactory := metrics.NullFactory
tracer, closer, err := cfg.NewTracer(jaegercfg.Logger(jLogger), jaegercfg.Metrics(jMetricsFactory))
if err != nil {
panic(fmt.Sprintf("ERROR: cannot init Jaeger: %v\n", err))
}
return tracer, closer
}
func main() {
if len(os.Args) != 2 {
panic("ERROR: Expecting one argument")
}
helloTo := os.Args[1]
// serviceName 会出现在 http://localhost:16686 UI 界面的 Service 选项框中
tracer, closer := initJaeger("hello-world")
defer closer.Close()
// operationName 会出现在 http://localhost:16686 UI 界面的 Operation 选项框中
// 一个 span(跨度) 是应用程序中完成某些工作的逻辑表示形式
// 每一个 span(跨度) 至少拥有的属性有:operation name, a start time, and a finish time.
span := tracer.StartSpan("say-hello")
// 打个断点,调试一下, 看看 span 有什么属性
helloStr := fmt.Sprintf("Hello, %s!", helloTo)
println(helloStr)
span.Finish()
}
使用命令 go run hello.go XiaoBai
运行后:1
2
32020/mm/dd HH:MM:ss Initializing logging reporter
Hello, XiaoBai!
2020/mm/dd HH:MM:ss Reporting span 46288729024383c8:46288729024383c8:0000000000000000:1
如果你的 Jaeger 服务端有运行起来,那么:serviceName:hello-world
会出现在 http://localhost:16686 UI 界面的 Service
选项框中operationName:say-hello
会出现在 http://localhost:16686 UI 界面的 Operation
选项框中
46288729024383c8
可以复制到 UI 界面的 Lookup by Trace ID
文本框中做精确查询
如果 Jaeger 服务端没有运行起来,上面运行也不会报错~
给 trace 加上 Tag
如果我们给 go run hello.go
传递不同的人名作为参数,如:go run hello.go Susan
go run hello.go Alice
在 UI 界面中选择 Service:hello-world
以及 Operation:say-hello
,
然后点击 Find Traces
,会得到多条跟踪记录,
如果我们能在跟踪中捕获程序参数来区分它们,那将会很美滋滋的~
1 | span := tracer.StartSpan("say-hello") |
现在可以更好地查询我们要分析的跟踪信息了,可以在 UI 界面中:
Service:hello-world
Operation:say-hello
Tags:helloTo=Alice
点击 Find Traces
后,点击查询到跟踪信息,看看里面记录了什么~
给 trace 加上 Log
我们的 hello 程序是如此简单,以至很难展示记录日志的示例~
本人提供给你脑补的代码:1
2
3
4
5
6
7
8
9
10
11// 支付订单
func Pay(orderId int64, args interface{}) {
span.SetTag("orderId", orderId)
log.Info("支付时的其它参数:" + json(args))
...
log.Info("开始总送积分...")
...
}
本例子提供的代码:1
2
3
4
5
6
7
8
9
10
11
12import "github.com/opentracing/opentracing-go/log"
...
helloStr := fmt.Sprintf("Hello, %s!", helloTo)
span.LogFields(
log.String("event", "string-format"),
log.String("value", helloStr),
)
println(helloStr)
span.LogKV("event", "println")
点击 Find Traces
后,点击查询到最新跟踪信息,
现在跟踪信息中除了有 Tags
,Process
外,还有 Logs
本文的示例很不符合我们现实业务中的代码,但我们的重点是理解 Jaeger 的使用,
越往后学习,例子就越接近我们日常编写的代码了~
参考资料
官方文档:
https://www.jaegertracing.io/docs
C#,Go,Java,Python,Node.js 各语言客户端的代码示例:
https://github.com/yurishkuro/opentracing-tutorial