Azure / Azure/azure-functions-nodejs-opentelemetry
parentTraceId undefined after migrating
- Dominant language
- TypeScript
- Stars
- 2
- Forks
- 11
- PR merge metrics
- No merged PRs in 30d
Description
We have been experimenting with otel on azure functions for some time now.
Yesterday we saw this lib in the updated docs and decided to give it a try, but replacing it seems like the propagation does not work as before.
debugging locally(after seeing the issue on azure) seems like the`_patch` is never called
changes:
```diff
- import { app, LogLevel } from '@azure/functions';
import { AzureMonitorLogExporter, AzureMonitorTraceExporter } from '@azure/monitor-opentelemetry-exporter';
import { context as otelContext, propagation } from '@opentelemetry/api';
import { SeverityNumber } from '@opentelemetry/api-logs';
import { getNodeAutoInstrumentations, getResourceDetectors } from '@opentelemetry/auto-instrumentations-node';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { detectResourcesSync } from '@opentelemetry/resources';
import { LoggerProvider, SimpleLogRecordProcessor } from '@opentelemetry/sdk-logs';
import { NodeTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node';
import { PrismaInstrumentation } from '@prisma/instrumentation';
+ import { AzureFunctionsInstrumentation } from '@azure/functions-opentelemetry-instrumentation';
const resource = detectResourcesSync({ detectors: getResourceDetectors() });
const tracerProvider = new NodeTracerProvider({
resource,
});
tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new AzureMonitorTraceExporter()));
tracerProvider.register();
const loggerProvider = new LoggerProvider({ resource });
loggerProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(new AzureMonitorLogExporter()));
registerInstrumentations({
tracerProvider,
loggerProvider,
- instrumentations: [new PrismaInstrumentation(), getNodeAutoInstrumentations()],
+ instrumentations: [new PrismaInstrumentation(), getNodeAutoInstrumentations(), new AzureFunctionsInstrumentation()],
});
- // NOTE: The below code will soon be a part of a new package `@opentelemetry/instrumentation-azure-functions`
- // See here for more info: https://github.com/Azure/azure-functions-nodejs-library/issues/245
- app.setup({ capabilities: { WorkerOpenTelemetryEnabled: true } });
- const logger = loggerProvider.getLogger('default');
- app.hook.log(context => {
- logger.emit({
- body: context.message,
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
- severityNumber: toOtelSeverityNumber(context.level),
- severityText: context.level,
- attributes: {},
- });
- });
- app.hook.preInvocation(context => {
- console.log(context.invocationContext.traceContext, 'traceContext');
- // eslint-disable-next-line fp/no-mutation
- context.functionHandler = otelContext.bind(
- propagation.extract(otelContext.active(), {
- traceparent: context.invocationContext.traceContext?.traceParent,
- tracestate: context.invocationContext.traceContext?.traceState,
- }),
- context.functionHandler
- );
- });
- function toOtelSeverityNumber(level: LogLevel): SeverityNumber {
- switch (level) {
- case 'information': {
- return SeverityNumber.INFO;
- }
- case 'debug': {
- return SeverityNumber.DEBUG;
- }
- case 'error': {
- return SeverityNumber.ERROR;
- }
- case 'trace': {
- return SeverityNumber.TRACE;
- }
- case 'warning': {
- return SeverityNumber.WARN;
- }
- case 'critical': {
- return SeverityNumber.FATAL;
- }
- default: {
- return SeverityNumber.UNSPECIFIED;
- }
- }
- }
```
otel related dependencies:
```
"@azure/functions-opentelemetry-instrumentation": "^0.1.0",
"@azure/identity": "^4.4.1",
"@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.25",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/api-logs": "^0.52.1",
"@opentelemetry/auto-instrumentations-node": "^0.49.1",
"@opentelemetry/instrumentation": "^0.52.1",
"@opentelemetry/instrumentation-http": "^0.52.1",
"@opentelemetry/resources": "^1.25.1",
"@opentelemetry/sdk-logs": "^0.52.1",
"@opentelemetry/sdk-trace-node": "^1.25.1",
```
Contributor guide
Research direction
Start with AzureFunctionsInstrumentation and inspect why its _patch entry point is not called when it is registered alongside getNodeAutoInstrumentations. Reproduce the shown migration with the listed dependency versions and trace propagation setup; done means parentTraceId is populated for Azure Functions invocations and the instrumentation works without the removed hooks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, typescript
- Domain
- backend, observability-sre
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100