63 lines
1.8 KiB
JavaScript
63 lines
1.8 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('assert');
|
|
const opentelemetryApi = require('@opentelemetry/api');
|
|
|
|
const packageInfo = require('../../package.json');
|
|
assert(packageInfo.name);
|
|
assert(packageInfo.version);
|
|
|
|
const tracer = opentelemetryApi.trace.getTracer(packageInfo.name, packageInfo.version);
|
|
|
|
/**
|
|
* Wraps an existing function to instrument it with OpenTelemetry tracing. Now
|
|
* whenever the function runs, it will create a span with the given name. It's
|
|
* basically `tracer.startActiveSpan` with some sensible default behaviors to
|
|
* automatically end spans:
|
|
* - when function completes successfully, status of span also set
|
|
* - when function throws (exception recorded against span)
|
|
* - if function returns a Promise, the promise is resolved
|
|
* @param name Span name, passed through to `tracer.startActiveSpan`
|
|
* @param fn The function to wrap
|
|
* @returns The wrapped function
|
|
*
|
|
* via
|
|
* https://github.com/open-telemetry/opentelemetry-js-api/issues/164#issuecomment-1174925516
|
|
*/
|
|
function trace(name, fn) {
|
|
return function (...args) {
|
|
return tracer.startActiveSpan(name, async (span) => {
|
|
try {
|
|
const result = await Promise.resolve(fn(...args));
|
|
span.setStatus({
|
|
code: opentelemetryApi.SpanStatusCode.OK,
|
|
});
|
|
return result;
|
|
} catch (e) {
|
|
const err = e;
|
|
span.recordException(err);
|
|
span.setStatus({
|
|
code: opentelemetryApi.SpanStatusCode.ERROR,
|
|
message: err.message,
|
|
});
|
|
throw err;
|
|
} finally {
|
|
span.end();
|
|
}
|
|
});
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Wraps an existing function to instrument it with OpenTelemetry tracing. The
|
|
* span name will be the name of the function.
|
|
*/
|
|
function traceFunction(fn) {
|
|
return trace(fn.name, fn);
|
|
}
|
|
|
|
module.exports = {
|
|
trace,
|
|
traceFunction,
|
|
};
|