Skip to main content

Demo Server


Source Code


Init Provider

参考 Client


OTEL HTTP Handler

mux := http.NewServeMux()
mux.Handle("/hello", otelhttp.NewHandler(handler, "/hello"))
server := &http.Server{
    Addr:    ":7080",
    Handler: mux,
}
if err := server.ListenAndServe(); err != http.ErrServerClosed {
    handleErr(err, "server failed to serve")
}
  • otelhttp.NewHandler 创建一个处理 span 的 Handler
  • server.ListenAndServe() 会调用 Handler 的 ServeHTTP()
  • ServeHTTP() 函数执行的时候会创建 span
  • 如果 Header 中带有 traceparent 头部,会创建子 span
  • 当 HTTP 请求处理完成后,span 自动结束并被加入上报队列
net > http > server.go
func (c *conn) serve(ctx context.Context) {
    // ...
    serverHandler{c.server}.ServeHTTP(w, w.req)
    // ...
}
otelhttp@v0.37.0 > handler.go
// ServeHTTP serves HTTP requests (http.Handler).
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // ...
    ctx := h.propagators.Extract(r.Context(), propagation.HeaderCarrier(r.Header))
    // ...
    ctx, span := tracer.Start(ctx, h.spanNameFormatter(h.operation, r), opts...)
    defer span.End()
}
go.opentelemetry.io > otel > sdk@v1.11.2 > trace > trace.go
// Start starts a Span and returns it along with a context containing it.
//
// The Span is created with the provided name and as a child of any existing
// span context found in the passed context. The created Span will be
// configured appropriately by any SpanOption passed.
func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanStartOption) (context.Context, trace.Span) {
    // ...
    s := tr.newSpan(ctx, name, &config)
    // ...
    return trace.ContextWithSpan(ctx, s), s
}

Get Header Context

ctx := req.Context()
span := trace.SpanFromContext(ctx)
bag := baggage.FromContext(ctx)
  • 从 ctx 中获取当前 span,这个 span 是在 ServeHTTP 中创建的
  • 从 Header 的 baggage 字段中提取信息

Simulate Error

// Sdding errors generation
if counter%errorProb == 0 {
    defer span.End()
    serverErr := fmt.Errorf("Internal Server Error - Randomized for Sampling")
    http.Error(w, serverErr.Error(), http.StatusInternalServerError)
    span.RecordError(serverErr)
    span.SetStatus(codes.Error, serverErr.Error())
    return
}