1318243841
The resolved @opentelemetry/semantic-conventions version in CI does not export ATTR_SERVICE_NAMESPACE/ATTR_SERVICE_NAME as named exports, breaking the backend test import. Use plain 'service.name'/'service.namespace' string keys so the code is independent of the semantic-conventions version.
73 lines
2.7 KiB
JavaScript
73 lines
2.7 KiB
JavaScript
// OpenTelemetry Node SDK bootstrap for FarmaClic backend.
|
|
// Started as a side-effect import from server.js (ESM).
|
|
//
|
|
// Env vars (set by docker-compose):
|
|
// OTEL_SERVICE_NAME — default: farmaclic-backend
|
|
// OTEL_EXPORTER_OTLP_ENDPOINT — OTLP gRPC endpoint (e.g. http://alloy:4317)
|
|
//
|
|
// Exports traces to the shared Grafana Alloy collector, where they are
|
|
// routed to Tempo.
|
|
|
|
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
|
|
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
|
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
|
|
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
|
|
import * as resources from '@opentelemetry/resources';
|
|
import { PinoInstrumentation } from '@opentelemetry/instrumentation-pino';
|
|
|
|
const serviceName = process.env.OTEL_SERVICE_NAME || 'farmaclic-backend';
|
|
const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4317';
|
|
|
|
// Use plain string attribute keys (not the semantic-conventions named exports)
|
|
// so we don't depend on a specific @opentelemetry/semantic-conventions version.
|
|
const resource = typeof resources.resourceFromAttributes === 'function'
|
|
? resources.resourceFromAttributes({
|
|
'service.name': serviceName,
|
|
'service.namespace': 'farmaclic',
|
|
})
|
|
: new resources.Resource({
|
|
'service.name': serviceName,
|
|
'service.namespace': 'farmaclic',
|
|
});
|
|
|
|
// Metrics → OTLP → Alloy → Prometheus remote_write. The PeriodicExportingMetricReader
|
|
// makes the auto-instrumentations (http/express/redis) emit request duration/error
|
|
// metrics with no extra code, on top of the custom business metrics in src/metrics.js.
|
|
const metricReader = new PeriodicExportingMetricReader({
|
|
exportIntervalMillis: 15_000,
|
|
exporter: new OTLPMetricExporter({ url: otlpEndpoint }),
|
|
});
|
|
|
|
const sdk = new NodeSDK({
|
|
resource,
|
|
traceExporter: new OTLPTraceExporter({ url: otlpEndpoint }),
|
|
metricReader,
|
|
instrumentations: [
|
|
getNodeAutoInstrumentations({
|
|
// Disable fs by default — it is noisy and rarely useful.
|
|
'@opentelemetry/instrumentation-fs': { enabled: false },
|
|
'@opentelemetry/instrumentation-dns': { enabled: false },
|
|
}),
|
|
new PinoInstrumentation(),
|
|
],
|
|
});
|
|
|
|
if (process.env.NODE_ENV !== 'test') {
|
|
sdk.start();
|
|
}
|
|
|
|
const shutdown = async () => {
|
|
try {
|
|
if (process.env.NODE_ENV !== 'test') {
|
|
await sdk.shutdown();
|
|
}
|
|
} catch (err) {
|
|
// eslint-disable-next-line no-console
|
|
console.error('OpenTelemetry shutdown failed', err);
|
|
}
|
|
};
|
|
|
|
process.on('SIGTERM', shutdown);
|
|
process.on('SIGINT', shutdown);
|