与其他编程语言不同,Go 不支持完全自动化的插桩功能。相反,你需要依赖一些插桩库来生成针对对应库的遥测数据。例如,net/http 的插桩库配置后,将会发起请求时自动创建相关的 spans 数据。

依赖准备

首先,你需要安装对应的插桩库。
通常的示例格式如下:

  1. go get go.opentelemetry.io/contrib/instrumentation/{import-path}/otel{package-name}

接下来,你需要在代码中显式引用它并进行相应的配置。

net/http 示例

接下来,我们会以 net/http 库为例进行演示如何针对 http 服务进行自动插桩。
首先,需要安装对应的 net/http 的插桩库:

  1. go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp

接下来,你需要使用上述库来封装你的代码中的 HTTP 服务处理逻辑:

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "net/http"
  7. "time"
  8. "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
  9. "go.opentelemetry.io/otel"
  10. "go.opentelemetry.io/otel/attribute"
  11. )
  12. // Package-level tracer.
  13. // This should be configured in your code setup instead of here.
  14. var tracer = otel.Tracer("github.com/full/path/to/mypkg")
  15. // sleepy mocks work that your application does.
  16. func sleepy(ctx context.Context) {
  17. _, span := tracer.Start(ctx, "sleep")
  18. defer span.End()
  19. sleepTime := 1 * time.Second
  20. time.Sleep(sleepTime)
  21. span.SetAttributes(attribute.Int("sleep.duration", int(sleepTime)))
  22. }
  23. // httpHandler is an HTTP handler function that is going to be instrumented.
  24. func httpHandler(w http.ResponseWriter, r *http.Request) {
  25. fmt.Fprintf(w, "Hello, World! I am instrumented autoamtically!")
  26. ctx := r.Context()
  27. sleepy(ctx)
  28. }
  29. func main() {
  30. // Wrap your httpHandler function.
  31. handler := http.HandlerFunc(httpHandler)
  32. wrappedHandler := otelhttp.NewHandler(handler, "hello-instrumented")
  33. http.Handle("/hello-instrumented", wrappedHandler)
  34. // And start the HTTP serve.
  35. log.Fatal(http.ListenAndServe(":3030", nil))
  36. }

此外,假设你已经完成了 Exporter 和全局 TracerProvider 的配置,那么,你的代码将会:

  • 监听 3030 端口启动一个 HTTP 服务。
  • 针对 /hello-instrumented url 的访问时,会自动生成一个 span 用于表示当前 HTTP 请求。
  • 在执行 sleepy 函数时,创建一个 span 作为自动生成的 span 的子 span 表示 sleepy 函数执行流程。

在应用程序中,有选择性的增加手动插桩并与各个框架自动插桩相互组合,这对于帮助应用程序和服务得到良好的可观测性非常重要。

可用插桩库

完整的可用插桩库可以在 OpenTelementry 仓库中查询。