当前位置: 首页 > 知识库问答 >
问题:

如何使用收集器在go中跟踪gRPC服务(服务器端)

佴波鸿
2023-03-14

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

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

在我的go服务中,我复制以下文件:interceptor。去grpctrace。从repo opentelemetry转到contrib,这里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错误:code=cancelled desc=context cancelled对于下一次请愿,我收到以下消息:exporter disconnected

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

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

谢谢

共有1个答案

雷曜灿
2023-03-14

我的错误在这几行:

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

我删除了这条线,它工作了!

 类似资料:
  • 下面的安全标识(如用户和组)在运行时环境中映射的角色是环境指定的而非应用指定的,理想的是: 使登录机制和策略是 web 应用部署到的环境属性。 在同一个容器部署的所有应用能使用相同的认证信息来表示principal,且 需要重新认证用户仅当已经越过了安全策略域边界。 因此,servlet 容器需要在容器级别(而不是在 web 应用级别)跟踪认证信息。这允许在一个 web 应用已经通过认证的用户可以

  • 问题:假设有两个服务 A 和 B,服务 A 对服务 B 进行 API 调用。一段时间后,服务A因网络错误而掉落或丢失。 另一个服务将如何猜测来自服务A的出站呼叫丢失/从未发生?我需要另一个并发应用程序,如果服务A出站呼叫丢失,它将自动响应(运行紧急代码)。 存在哪些尖端解决方案? 例如,我的想法: 服务 A 在某些中间件中注册调用事件(事件信息、“正在运行”状态、时间戳等)。 如果此调用在 N 秒

  • 根据这个http://www.grpc.io/docs/tutorials/basic/python.html#creating-这里的服务器和示例https://github.com/grpc/grpc/tree/v1.0.0/examples/python/route_guide,当我生成我的pb2时。py文件中,应创建几个名为Stub和Servicer的类。但是,我生成了pb2。py文件不包

  • 我正在尝试让这个gRPC服务器示例与Google Asylo(https://github.com/google/asylo/tree/master/asylo/examples/grpc_server)一起工作。.要初始化服务器,我需要在此配置文件中指定server_address(https://github.com/google/asylo/blob/master/asylo/example

  • 我想使用电子商务跟踪我的网站,但我的网站不是一个传统的电子商务类型的网站。我们是一家船运公司,所以我们的订单是以运费为基础的。 网站的工作方式是客户在前端提交一个盒子来处理,然后在后端我们计算运输成本,然后批量运行我们所有的客户不同的货物。 有没有一种方法可以让我使用电子商务跟踪代码,并让它在我批处理所有货物时在后端通过每次发货循环? 谢谢你!

  • 当规则应用程序在KIE服务器上运行时,如何启用规则引擎跟踪/日志记录? 规则应用程序是在工作台中创建的,不包含自定义代码。我能够使用KIE REST API执行规则,但是规则应用程序没有产生预期的结果。 环境: 我尝试了以下步骤: 使用Git在本地克隆工作台项目 将logback.xml添加到项目的根目录 将更改推回到工作台git repo 在工作台项目编辑器视图中添加了日志作为依赖项 更新项目版