【发布时间】:2022-08-03 13:40:09
【问题描述】:
我正在 Google Cloud Platform 的 Cloud Run 中检测 node.js 服务。
我遇到了一个问题Trace 中未显示自定义跨度.
我知道跟踪是有效的,因为 HTTP/TCP 跨度(您可以在 GCP 中免费获得)正确显示嵌套 - 如果没有配置,它们不会自动嵌套,这表明下面的配置正在工作:
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
我不确定是否需要添加其他权限(或者可能需要将它们添加到哪个实体)。
到目前为止我已经尝试过
- 使用和不使用 Provider 配置进行部署(没有区别)
- 使用 Open-Telemetry
OTLPTraceExporter在 GCP 中导出 span(仍然没有显示) - 改用 Stackdriver
trace-agent(与 webpack 不兼容) - 使用带有 Open-Telemetry 收集器的
OTLPTraceExporter在本地运行所有这些(一切都按预期工作——所有跟踪都显示出来了) - 在 GCP 中使用 ConsoleSpanExporter(跨度在日志中正确显示)
我真的很茫然。
-
根据 GCP 的文档,Google Compute Engine 和 GKE 有 auto-instrumentation 模块,但 Cloud Run 没有。你可以查看这个 Github Cloud Run Support。
-
啊,谢谢你的链接!我已经在链接评论中尝试了建议的更改:\"@patryk-smc 我没有实际示例,但跟踪应该可以正常工作。使用常规 BatchSpanProcessor 并在程序结束之前调用 TracerProvider.shutdown()。对于 Cloud Run,您可以添加一个 SIGTERM 处理程序来调用关机。\" ...但它似乎在 Cloud Run 中不起作用。
标签: node.js google-cloud-run open-telemetry google-cloud-trace