登录
首页 >  Golang >  Go问答

追踪 gRPC 服务的服务器端的方法及实施

来源:stackoverflow

时间:2024-03-18 22:36:29 308浏览 收藏

在使用 OpenTelemetry 收集器跟踪 gRPC 服务时,需要对服务器端进行配置。本文将介绍如何使用 gRPC 拦截器和配置跟踪导出器来追踪服务器端的方法和实施步骤。通过配置 gRPC 服务器拦截器,可以截获每个请求并启动一个跨度,以便跟踪请求的处理过程。同时,配置跟踪导出器将跨度数据发送到收集器,以实现可观察性和分析。

问题内容

我正在使用收集器来跟踪我的 java 服务中的跨度,该服务是 http 和 grpc。收集器端点是 localhost:55680。此 java 服务跟踪成功。

现在,我想使用这个收集器来跟踪我基于 grpc 的 go 服务。

在我的 go 服务中,我复制以下文件:来自 repo opentelemetry-go-contrib 的拦截器.go 和 grpctrace.go,此处 https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main /instrumentation/google.golang.org/grpc/otelgrpc

现在,我创建一个名为 config.go 的文件:

package grpctracing

import (
  "context"
  "log"

  "go.opentelemetry.io/otel"
  "go.opentelemetry.io/otel/exporters/otlp"
  "go.opentelemetry.io/otel/exporters/otlp/otlpgrpc"
  "go.opentelemetry.io/otel/label"
  "go.opentelemetry.io/otel/propagation"
  "go.opentelemetry.io/otel/sdk/resource"
  sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

// init configures an opentelemetry exporter and trace provider
func inittracing() {

  ctx := context.background()

  driver := otlpgrpc.newdriver(
    otlpgrpc.withinsecure(),
    otlpgrpc.withendpoint("localhost:55680"),
  )

  exporter, err := otlp.newexporter(ctx, driver) // configure as needed.
  if err != nil {
    log.fatal(err)
  }
  defer func() {
    err := exporter.shutdown(ctx)
    if err != nil {
      log.fatalf("failed to stop exporter: %v", err)
    }
  }()

  service := "test-service"

  tracerprovider := sdktrace.newtracerprovider(
    sdktrace.withconfig(sdktrace.config{defaultsampler: sdktrace.alwayssample()}),
    sdktrace.withresource(resource.newwithattributes(
      label.key("service.name").string(service),
    )),
    sdktrace.withbatcher(exporter),
  )


  if err != nil {
    log.fatal(err)
  }
  otel.settracerprovider(tracerprovider)
  otel.settextmappropagator(propagation.newcompositetextmappropagator(propagation.tracecontext{}, propagation.baggage{}))
}

现在,当我启动 grpc 服务器时,我会执行以下操作:

grpctracing.inittracing()
        ...
    grpcserver := grpc.newserver(
        grpc.unaryinterceptor(grpctracing.unaryserverinterceptor()),
    )

这是服务器拦截器,这个叫每一个请求:

func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
  return func(
    ctx context.Context,
    req interface{},
    info *grpc.UnaryServerInfo,
    handler grpc.UnaryHandler,
  ) (interface{}, error) {
    requestMetadata, _ := metadata.FromIncomingContext(ctx)
    metadataCopy := requestMetadata.Copy()

    entries, spanCtx := Extract(ctx, &metadataCopy, opts...)
    ctx = baggage.ContextWithValues(ctx, entries...)

    tracer := newConfig(opts).TracerProvider.Tracer(
      instrumentationName,
      trace.WithInstrumentationVersion(otelcontrib.SemVersion()),
    )

    name, attr := spanInfo(info.FullMethod, peerFromCtx(ctx))
    ctx, span := tracer.Start(
      trace.ContextWithRemoteSpanContext(ctx, spanCtx),
      name,
      trace.WithSpanKind(trace.SpanKindServer),
      trace.WithAttributes(attr...),
    )
    defer span.End()

    messageReceived.Event(ctx, 1, req)

    resp, err := handler(ctx, req)
    if err != nil {
      s, _ := status.FromError(err)
      span.SetStatus(codes.Error, s.Message())
      span.SetAttributes(statusCodeAttr(s.Code()))
      messageSent.Event(ctx, 1, s.Proto())
    } else {
      span.SetAttributes(statusCodeAttr(grpc_codes.OK))
      messageSent.Event(ctx, 1, resp)
    }

    return resp, err
  }
}

第一个请愿书,我收到以下消息: rpc 错误:代码 = 已取消 desc = 上下文已取消 对于下一个请愿书,我收到以下消息: exporter 已断开连接

我检查了收集器日志,似乎没有请求到来。

知道为什么它不起作用吗?我做错了什么?

谢谢!!!


解决方案


我的错误在这几行:

defer func() {
    err := exporter.Shutdown(ctx)
    if err != nil {
      log.Fatalf("failed to stop exporter: %v", err)
    }
}()

我删除了这一行并且它起作用了!

理论要掌握,实操不能落!以上关于《追踪 gRPC 服务的服务器端的方法及实施》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>