@fluidware-it/opentracing-injector
Version:
Instrument your app with ease
200 lines (152 loc) • 5.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.tracingMiddleware = exports.instrumentAsync = exports.instrumentCallback = exports.instrumentSync = exports.injectSpanIntoData = exports.injectSpanIntoHeaders = exports.extractSpanFromHeaders = exports.extractSpanFromData = exports.startSpanWithTags = exports.getOpenTracer = exports.initOpenTracer = void 0;
var _opentracing = require("opentracing");
var _tracers = require("./tracers");
var _envUtils = require("./utils/envUtils");
let tracer;
const initOpenTracer = function (environment, logger = false) {
const {
OPENTRACING_DISABLE,
OPENTRACING_CLIENT_NAME
} = environment || process.env;
if (_envUtils.EnvParse.envBool(OPENTRACING_DISABLE) || !OPENTRACING_CLIENT_NAME) {
tracer = new _opentracing.Tracer();
return tracer;
}
const initiator = (0, _tracers.getTracerInitiator)(OPENTRACING_CLIENT_NAME);
tracer = initiator.init(environment, logger);
process.on('SIGINT', function () {
initiator.stop(tracer, function () {
process.exit(0);
});
});
return tracer;
};
exports.initOpenTracer = initOpenTracer;
const getOpenTracer = function () {
if (!tracer) {
throw new Error('tracer not initialized. Call initOpenTracer()');
}
return tracer;
};
exports.getOpenTracer = getOpenTracer;
const startSpanWithTags = function (spanName, spanOpts = {}, tags = {}) {
const span = tracer.startSpan(spanName, spanOpts || {});
if (tags && typeof tags === 'object') {
Object.keys(tags).forEach(k => {
span.setTag(k, tags[k]);
});
}
return span;
};
exports.startSpanWithTags = startSpanWithTags;
const extractSpanFromData = function (data, spanName, tags) {
const spanOpts = {};
if (data.trace) {
const parentSpan = tracer.extract(_opentracing.FORMAT_TEXT_MAP, data.trace);
if (parentSpan) {
spanOpts.childOf = parentSpan;
}
}
return startSpanWithTags(spanName, spanOpts, tags);
};
exports.extractSpanFromData = extractSpanFromData;
const extractSpanFromHeaders = function (headers, spanName, tags) {
const spanOpts = {};
const parentSpan = tracer.extract(_opentracing.FORMAT_HTTP_HEADERS, headers);
if (parentSpan) {
spanOpts.childOf = parentSpan;
}
return startSpanWithTags(spanName, spanOpts, tags);
};
exports.extractSpanFromHeaders = extractSpanFromHeaders;
const injectSpanIntoHeaders = function (span, headers = {}) {
span.setTag(_opentracing.Tags.SPAN_KIND, _opentracing.Tags.SPAN_KIND_RPC_CLIENT); // Send span context via request headers (parent id etc.)
tracer.inject(span, _opentracing.FORMAT_HTTP_HEADERS, headers);
return headers;
};
exports.injectSpanIntoHeaders = injectSpanIntoHeaders;
const injectSpanIntoData = function (span, data = {}) {
span.setTag(_opentracing.Tags.SPAN_KIND, _opentracing.Tags.SPAN_KIND_MESSAGING_PRODUCER); // Send span context via data map (parent id etc.)
tracer.inject(span, _opentracing.FORMAT_TEXT_MAP, data.trace);
return data;
};
exports.injectSpanIntoData = injectSpanIntoData;
const instrumentSync = function (spanName, spanOpts, tags = {}, func) {
const span = startSpanWithTags(spanName, spanOpts, tags);
let ret;
try {
ret = func(span);
} catch (e) {
span.setTag(_opentracing.Tags.ERROR, true);
span.log({
event: 'error',
error_message: e.message,
'error.object': e
});
throw e;
} finally {
span.finish();
}
return ret;
};
exports.instrumentSync = instrumentSync;
const instrumentCallback = function (spanName, spanOpts, tags = {}, cb) {
const span = startSpanWithTags(spanName, spanOpts, tags);
if (!cb || typeof cb !== 'function') {
throw new Error('callback is required and must be a function');
}
cb(span, function (err) {
if (err) {
span.setTag(_opentracing.Tags.ERROR, true);
span.log({
event: 'error',
error_message: err.message,
'error.object': err
});
}
span.finish();
});
};
exports.instrumentCallback = instrumentCallback;
const instrumentAsync = async function (spanName, spanOpts, tags = {}, func) {
const span = startSpanWithTags(spanName, spanOpts, tags);
let ret;
try {
ret = await func(span);
} catch (e) {
span.setTag(_opentracing.Tags.ERROR, true);
span.log({
event: 'error',
error_message: e.message,
'error.object': e
});
throw e;
} finally {
span.finish();
}
return ret;
};
exports.instrumentAsync = instrumentAsync;
const tracingMiddleware = function (req, res, next, reqPropertyName = 'parentSpan') {
const span = extractSpanFromHeaders(req.headers, 'http request', {
'http.url': req.originalUrl,
'http.method': req.method,
'http.host': req.hostname
});
req[reqPropertyName] = span;
const {
end
} = res;
res.end = function (chunk, encoding) {
res.end = end;
res.end(chunk, encoding);
span.setTag('http.statusCode', res.statusCode);
span.finish();
};
setImmediate(next);
};
exports.tracingMiddleware = tracingMiddleware;