开放遥测跨度未显示在 GCP Cloud Trace 中

发布于 2025-01-12 19:56:42 字数 3200 浏览 1 评论 0原文

我正在 Google Cloud Platform 的 Cloud Run 中检测 Node.js 服务。

我遇到了自定义跨度未显示在跟踪中的问题。

跨度(您在 GCP 中免费获得)显示正确嵌套 - 如果没有配置,它们不会自动嵌套,这表明下面的配置正在工作:

我知道跟踪正在工作,因为 HTTP/ TCP tracing.ts:

import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import {
  SimpleSpanProcessor,
} from "@opentelemetry/sdk-trace-base";
import { TraceExporter } from "@google-cloud/opentelemetry-cloud-trace-exporter";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
import * as opentelemetry from "@opentelemetry/api";
import { AsyncHooksContextManager } from "@opentelemetry/context-async-hooks";
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
import { Resource } from "@opentelemetry/resources"

export const provider = new NodeTracerProvider({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: "my-service-name",
  })
});

// this *should* work automatically in GCP??
provider.addSpanProcessor(new SimpleSpanProcessor(new TraceExporter({
  resourceFilter: /^service\./
})));

provider.register();

opentelemetry.trace.setGlobalTracerProvider(provider);

const contextManager = new AsyncHooksContextManager();
contextManager.enable();
opentelemetry.context.setGlobalContextManager(contextManager);

export const tracer = opentelemetry.trace.getTracer("basic");

// this works (spans are correctly associated with parents)
registerInstrumentations({
  instrumentations: [
    getNodeAutoInstrumentations({
      "@opentelemetry/instrumentation-http": {},
      "@opentelemetry/instrumentation-express": {},
    }),
  ],
});

显示的跨度是那些在代码中发出的跨度,如以下经过编辑的生产代码:

import { tracer } from "../tracing";

// ...

export const doWork = async (
  req: Request,
  res: Response
) => {

  // ... but this does *NOT* work: these spans appear nowhere
  // start span
  const span = tracer.startSpan("doWork");
  const ctx = opentelemetry.trace.setSpan(opentelemetry.context.active(), span);
  opentelemetry.propagation.extract(ctx, req.headers);

  try {
    // ... do work here with ctx to emit child spans

    res.status(200).send("ok");
  } catch (e) {
    res.status(500).send("error");
  }

  span.end();
};

我不清楚为什么这些跨度没有显示在任何地方。

部署 Cloud Run 实例的服务帐户具有 roles/cloudtrace.agent 角色:

- members:
  - serviceAccount:<my service account name>@<project id>.iam.gserviceaccount.com
  role: roles/cloudtrace.agent    

我不确定是否需要添加其他权限(或者可能需要将它们添加到哪个实体) 。

到目前为止,我已经尝试

  • 使用 Open-Telemetry OTLPTraceExporter进行部署,使用或不使用 Provider 配置(没有区别),
  • 导出 GCP 中的跨度(仍然没有显示任何内容)
  • 以使用 Stackdriver trace-agent code> (与 webpack 不兼容)
  • 使用 OTLPTraceExporter 和 Open-Telemetry 收集器在本地运行所有这些(一切都按预期工作 - 跟踪所有显示)
  • 使用GCP 中的 ConsoleSpanExporter (跨度在日志中正确显示)

我真的很茫然。

I am instrumenting a node.js service in Google Cloud Platform's Cloud Run.

I'm running into a problem where custom spans are not showing up in Trace.

I know that tracing is working because HTTP/TCP spans (which you get for free in GCP) are showing up nested properly--they wouldn't be nested automatically without configuration, which suggests to me the configuration below is working:

tracing.ts:

import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import {
  SimpleSpanProcessor,
} from "@opentelemetry/sdk-trace-base";
import { TraceExporter } from "@google-cloud/opentelemetry-cloud-trace-exporter";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
import * as opentelemetry from "@opentelemetry/api";
import { AsyncHooksContextManager } from "@opentelemetry/context-async-hooks";
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
import { Resource } from "@opentelemetry/resources"

export const provider = new NodeTracerProvider({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: "my-service-name",
  })
});

// this *should* work automatically in GCP??
provider.addSpanProcessor(new SimpleSpanProcessor(new TraceExporter({
  resourceFilter: /^service\./
})));

provider.register();

opentelemetry.trace.setGlobalTracerProvider(provider);

const contextManager = new AsyncHooksContextManager();
contextManager.enable();
opentelemetry.context.setGlobalContextManager(contextManager);

export const tracer = opentelemetry.trace.getTracer("basic");

// this works (spans are correctly associated with parents)
registerInstrumentations({
  instrumentations: [
    getNodeAutoInstrumentations({
      "@opentelemetry/instrumentation-http": {},
      "@opentelemetry/instrumentation-express": {},
    }),
  ],
});

The spans that are not showing up are those that are emitted in code like the following redacted production code:

import { tracer } from "../tracing";

// ...

export const doWork = async (
  req: Request,
  res: Response
) => {

  // ... but this does *NOT* work: these spans appear nowhere
  // start span
  const span = tracer.startSpan("doWork");
  const ctx = opentelemetry.trace.setSpan(opentelemetry.context.active(), span);
  opentelemetry.propagation.extract(ctx, req.headers);

  try {
    // ... do work here with ctx to emit child spans

    res.status(200).send("ok");
  } catch (e) {
    res.status(500).send("error");
  }

  span.end();
};

It is unclear to me why these spans are not showing up anywhere.

The service account that deploys the Cloud Run instance has the roles/cloudtrace.agent role:

- members:
  - serviceAccount:<my service account name>@<project id>.iam.gserviceaccount.com
  role: roles/cloudtrace.agent    

I am unsure if there are additional permissions that need to be added (or what entity they may need to be added to).

So far I have tried

  • deploying with and without Provider configuration (no difference)
  • using the Open-Telemetry OTLPTraceExporter to export spans in GCP (still nothing shows up)
  • using the Stackdriver trace-agent instead (not compatible with webpack)
  • running all of this locally using the OTLPTraceExporter with a Open-Telemetry collector (everything works exactly as expected -- traces all showing up)
  • using the ConsoleSpanExporter in GCP (spans show up correctly in logs)

I'm really at a loss.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

巴黎夜雨 2025-01-19 19:56:42

根据 GCP 文档中的检查,仅限 Google Compute Engine和 GKE 均受此服务支持。

不过,您可以参考 Github 中的 Cloud Run 支持,如果您正在 Cloud Run 和 Stackoverflow 上运行 OpenTelemetry 讨论

As checked in GCP documentation, only Google Compute Engine and GKE are supported by this service.

However, you can refer to Cloud Run Support in Github, if you are running OpenTelemetry on Cloud Run and a Stackoverflow discussion.

林空鹿饮溪 2025-01-19 19:56:42

对我来说,这是几件事的结合:

使用 BatchSpanProcessor 对我来说是成功的,即使没有正确调用 shutdown 也是如此。

即,像这样:

 provider.addSpanProcessor(new BatchSpanProcessor(new TraceExporter()));

但是,并非所有跨度都会在 GCP 上进行采样,因此我需要在 NodeTracerProvider 中添加一个 AlwaysOnSampler

export const provider = new NodeTracerProvider({
  sampler: new AlwaysOnSampler(), //https://github.com/open-telemetry/opentelemetry-js/issues/3057
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: processName,
  }),
});

我目前不确定为什么所有在本地运行时会对跟踪进行采样,但在 GCP 上运行时仅对一部分进行采样。

For me, this was a combination of a few things:

Using a BatchSpanProcessor did the trick for me, even without properly calling shutdown.

ie, something like this:

 provider.addSpanProcessor(new BatchSpanProcessor(new TraceExporter()));

However, not all spans will be sampled on GCP, so I needed to add an AlwaysOnSampler in the NodeTracerProvider:

export const provider = new NodeTracerProvider({
  sampler: new AlwaysOnSampler(), //https://github.com/open-telemetry/opentelemetry-js/issues/3057
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: processName,
  }),
});

I'm currently not sure why all traces are sampled when running locally, but only a subset are sampled when running on GCP.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文