天天看点

分布式链路追踪系统--OpenCensus

作者:寒笛过霜天

OpenCensus 是 Google 开源的一个用来收集和追踪应用程序指标中立厂商的第三方库。支持多个语言的lib库, 但是不能展示。

OpenCensus 是 Google 开源的一个用来收集和追踪应用程序指标中立厂商的第三方库, 能够减少应用的部署与构建成本, 尤其适合微服务架构。

OpenCensus 有各种不同的编程语言编写的版本, 包括 Go、Java、PHP、C++、Python 等等。它旨在帮助开发者更容易收集和提交跟踪应用程序指标。

这是一个中立的单一库发行, 可自动收集和跟踪应用指标, 可在本地显示, 也可将其发送到分析工具。

OpenCensus 目前支持 Prometheus、SignalFX、Stackdriver 和 Zipkin。

开发者可以使用它来测试微服务, 并将数据发送到任何受支持的后端服务。

官方网:

http://opencensus.io/

GitHub 项目:

https://github.com/census-instrumentation

有多个项目的客户端。 Java, C++, Go, .Net, Python, PHP, Node.js, Erlang, and Ruby。这些客户端都支持。

使用的案例

https://github.com/census-instrumentation/opencensus-go/tree/v0.22.5/examples

案例: HTTP服务分布式链路追踪

> # mkdir tracing

> # vim server.go

package main
import (
"fmt"
"log"
"net/http"
"time"
"go.opencensus.io/zpages"
"go.opencensus.io/examples/exporter"
"go.opencensus.io/plugin/ochttp"
"go.opencensus.io/stats/view"
"go.opencensus.io/trace"
)
const (
metricsLogFile = "/tmp/metrics.log"
tracesLogFile = "/tmp/trace.log"
)
func main() {
// 启动z-Pages服务器。
go func() {
mux := http.NewServeMux()
zpages.Handle(mux, "/debug")
log.Fatal(http.ListenAndServe("127.0.0.1:8081", mux))
}()
// 使用日志导出器导出度量,但您可以选择任何支持的导出器。
exporter, err := exporter.NewLogExporter(exporter.Options{
ReportingInterval: 10 * time.Second,
MetricsLogFile: metricsLogFile,
TracesLogFile: tracesLogFile,
})
if err != nil {
log.Fatalf("Error creating log exporter: %v", err)
}
exporter.Start()
defer exporter.Stop()
defer exporter.Close()
// 始终跟踪此演示。在生产应用程序中,您应该将此配置为跟踪概率采样器设置在所需的位置概率。
trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
// 每秒钟报告一次数据
view.SetReportingPeriod(1 * time.Second)
client := &http.Client{Transport: &ochttp.Transport{}}
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "hello world")
// 提供一个示例,说明如何使用元数据对跨度进行注释
_, span := trace.StartSpan(req.Context(), "child")
defer span.End()
span.Annotate([]trace.Attribute{trace.StringAttribute("key", "value")}, "something happened")
span.AddAttributes(trace.StringAttribute("hello", "world"))
time.Sleep(time.Millisecond * 125)
r, _ := http.NewRequest("GET", "https://example.com", nil)
// 在传出请求中传递跟踪头信息。
r = r.WithContext(req.Context())
resp, err := client.Do(r)
if err != nil {
log.Println(err)
} else {
// TODO: handle response
resp.Body.Close()
}
})
log.Fatal(http.ListenAndServe(":50030", &ochttp.Handler{}))
}           

> # vim client.go

package main
import (
"log"
"net/http"
"time"
"go.opencensus.io/plugin/ochttp"
"go.opencensus.io/trace"
"go.opencensus.io/examples/exporter"
"go.opencensus.io/stats/view"
)
const server = "http://localhost:50030"
func main() {
// 注册 stats 并跟踪导出程序以导出收集的数据。
exporter := &exporter.PrintExporter{}
view.RegisterExporter(exporter)
trace.RegisterExporter(exporter)
// 始终跟踪此演示。在生产应用程序中,您应该将此配置为跟踪概率采样器设置在所需的位置概率。
trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
// 每秒钟报告一次数据
view.SetReportingPeriod(1 * time.Second)
client := &http.Client{Transport: &ochttp.Transport{}}
resp, err := client.Get(server)
if err != nil {
log.Printf("Failed to get response: %v", err)
} else {
resp.Body.Close()
}
time.Sleep(2 * time.Second) // 等到统计报告出来。
}           

> # go run server.go

> # go run client.go

#----------------------------------------------

TraceID: 7a4b4b8d5c9c0ad37f8896d7c046d507

SpanID: c94fc0853d16c131

Span:

Status: OK [0]

Elapsed: 3.072s

Attributes:

- http.method=GET

- http.status_code=200

- http.path=

- http.url=http://localhost:50030

- http.host=localhost:50030

继续阅读