115 lines
4.2 KiB
JavaScript
115 lines
4.2 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('assert');
|
|
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
|
|
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
|
const { FetchInstrumentation } = require('opentelemetry-instrumentation-fetch-node');
|
|
const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
|
|
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
|
const {
|
|
BasicTracerProvider,
|
|
// ConsoleSpanExporter,
|
|
// SimpleSpanProcessor,
|
|
BatchSpanProcessor,
|
|
} = require('@opentelemetry/sdk-trace-base');
|
|
const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks');
|
|
const { OTTracePropagator } = require('@opentelemetry/propagator-ot-trace');
|
|
const { Resource } = require('@opentelemetry/resources');
|
|
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
|
|
|
const CaptureSpanProcessor = require('./capture-span-processor');
|
|
|
|
const config = require('../lib/config');
|
|
const basePath = config.get('basePath');
|
|
assert(basePath);
|
|
const jaegerTracesEndpoint = config.get('jaegerTracesEndpoint');
|
|
|
|
const packageInfo = require('../../package.json');
|
|
assert(packageInfo.name);
|
|
|
|
const basePathUrl = new URL(basePath);
|
|
|
|
// (Diagnostics) For troubleshooting, set the log level to DiagLogLevel.DEBUG.
|
|
//
|
|
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
|
|
|
|
const provider = new BasicTracerProvider({
|
|
resource: new Resource({
|
|
[SemanticResourceAttributes.SERVICE_NAME]: `${packageInfo.name} - ${basePathUrl.host}`,
|
|
}),
|
|
});
|
|
// Export spans to console (useful for debugging).
|
|
// provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
|
|
|
|
// Export spans to Jaeger
|
|
let isExportingToJaeger = false;
|
|
if (jaegerTracesEndpoint) {
|
|
const exporter = new JaegerExporter({
|
|
tags: [],
|
|
endpoint: jaegerTracesEndpoint,
|
|
});
|
|
// Use this for immediate span submission
|
|
//provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
|
|
// Otherwise, we should just use the more performant batched processor
|
|
provider.addSpanProcessor(new BatchSpanProcessor(exporter));
|
|
|
|
isExportingToJaeger = true;
|
|
}
|
|
|
|
const captureSpanProcessor = new CaptureSpanProcessor();
|
|
provider.addSpanProcessor(captureSpanProcessor);
|
|
|
|
function startTracing() {
|
|
if (!isExportingToJaeger) {
|
|
console.warn(
|
|
`⚠ Tracing was started but \`jaegerTracesEndpoint\` was not configured so we are not exporting anything.`
|
|
);
|
|
}
|
|
|
|
provider.register({
|
|
contextManager: new AsyncLocalStorageContextManager(),
|
|
propagator: new OTTracePropagator(),
|
|
});
|
|
|
|
registerInstrumentations({
|
|
instrumentations: [
|
|
getNodeAutoInstrumentations({
|
|
'@opentelemetry/instrumentation-http': {
|
|
// Docs:
|
|
// https://github.com/open-telemetry/opentelemetry-js/tree/51afd54bd63e46d5d530266761144c7be2f6b3a7/experimental/packages/opentelemetry-instrumentation-http#http-instrumentation-options
|
|
//
|
|
// This is the place to ignore root level spans for Express routes. My
|
|
// first guess would be in `ignoreLayers` in
|
|
// `@opentelemetry/instrumentation-express` but that's not the case, see
|
|
// https://github.com/open-telemetry/opentelemetry-js-contrib/issues/1034#issuecomment-1158435392
|
|
ignoreIncomingRequestHook: (req) => {
|
|
// Ignore spans from static assets. It's just noise to trace them and there
|
|
// is nothing special about the routes.
|
|
const isStaticAsset = !!req.url.match(/^\/assets\//);
|
|
return isStaticAsset;
|
|
},
|
|
},
|
|
}),
|
|
// We have to instrument `undici` to cover the native `fetch` API built-in to
|
|
// Node.js. We're using `opentelemetry-instrumentation-fetch-node` because there
|
|
// is no official instrumentation and `opentelemetry-instrumentation-undici`
|
|
// doesn't seem to work.
|
|
new FetchInstrumentation({}),
|
|
],
|
|
});
|
|
|
|
process.on('SIGTERM', () => {
|
|
provider
|
|
.shutdown()
|
|
.then(() => console.log('Tracing terminated'))
|
|
.catch((error) => console.log('Error terminating tracing', error))
|
|
.finally(() => process.exit(0));
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
startTracing,
|
|
provider,
|
|
captureSpanProcessor,
|
|
};
|