@imqueue/opentelemetry-instrumentation-imqueue
Version:
This module provides OpenTelemetry instrumentation for @imqueue
143 lines • 6.1 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImqueueInstrumentation = void 0;
/*!
* Copyright (c) 2022, imqueue.com <support@imqueue.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
const instrumentation_1 = require("@opentelemetry/instrumentation");
const api_1 = require("@opentelemetry/api");
const enums_1 = require("./enums");
const path_1 = __importDefault(require("path"));
let packageJson;
let instrumentationName = '@imqueue/opentelemetry-instrumentation-imqueue';
let instrumentationVersion = '2.0.3';
const packageName = '@imqueue/rpc';
const versions = ['>=1.10'];
const componentName = 'imq';
try {
packageJson = require(`${path_1.default.resolve('.')}${path_1.default.sep}package.json`);
instrumentationName = packageJson.name;
instrumentationVersion = packageJson.version;
}
catch (err) {
// Use fallback values if package.json cannot be read
}
class ImqueueInstrumentation extends instrumentation_1.InstrumentationBase {
static thisTracer;
constructor(config = {}) {
super(instrumentationName, instrumentationVersion, Object.assign({}, config));
}
init() {
const module = new instrumentation_1.InstrumentationNodeModuleDefinition(packageName, versions, moduleExports => {
const { beforeCallClient, beforeCallService, afterCall } = this;
Object.assign(moduleExports.DEFAULT_IMQ_CLIENT_OPTIONS, { beforeCall: beforeCallClient, afterCall });
Object.assign(moduleExports.DEFAULT_IMQ_SERVICE_OPTIONS, { beforeCall: beforeCallService, afterCall });
return moduleExports;
}, moduleExports => {
ImqueueInstrumentation.unpatchClient(moduleExports);
ImqueueInstrumentation.unpatchService(moduleExports);
return moduleExports;
});
ImqueueInstrumentation.thisTracer = this.tracer;
return module;
}
beforeCallClient = async function (req) {
req.toJSON = () => {
const copy = Object.assign({}, req);
delete copy.span;
return copy;
};
try {
const span = ImqueueInstrumentation.thisTracer.startSpan(enums_1.SpanNames.IMQ_REQUEST, {
attributes: {
[enums_1.AttributeNames.SPAN_KIND]: enums_1.TraceKind.CLIENT,
[enums_1.AttributeNames.RESOURCE_NAME]: `${this.serviceName}.${req.method}`,
[enums_1.AttributeNames.SERVICE_NAME]: this.serviceName,
[enums_1.AttributeNames.IMQ_CLIENT]: req.from,
[enums_1.AttributeNames.COMPONENT]: componentName,
},
kind: api_1.SpanKind.CLIENT,
});
req.metadata = req.metadata || {};
req.metadata.clientSpan = {};
api_1.propagation.inject(api_1.trace.setSpan(api_1.context.active(), span), req.metadata.clientSpan);
req.span = span;
}
catch (error) {
// Silently handle the error
}
};
beforeCallService = async function (req) {
req.toJSON = () => {
const copy = Object.assign({}, req);
delete copy.span;
return copy;
};
try {
const carrier = (req.metadata || { clientSpan: null }).clientSpan;
const parentContext = api_1.propagation.extract(api_1.context.active(), carrier);
req.span = ImqueueInstrumentation.thisTracer.startSpan(enums_1.SpanNames.IMQ_RESPONSE, {
attributes: {
[enums_1.AttributeNames.SPAN_KIND]: enums_1.TraceKind.SERVER,
[enums_1.AttributeNames.RESOURCE_NAME]: `${this.name}.${req.method}`,
[enums_1.AttributeNames.SERVICE_NAME]: this.name,
[enums_1.AttributeNames.IMQ_CLIENT]: req.from,
[enums_1.AttributeNames.COMPONENT]: componentName,
},
kind: api_1.SpanKind.SERVER,
}, parentContext);
}
catch (error) {
// Silently handle the error
}
};
afterCall = async function (req) {
try {
req.span?.end();
}
catch (error) {
// Silently handle the error
}
};
static unpatchClient(serviceModule) {
if (!serviceModule.DEFAULT_IMQ_CLIENT_OPTIONS) {
return;
}
const { beforeCall, afterCall, } = serviceModule.DEFAULT_IMQ_CLIENT_OPTIONS;
if (beforeCall) {
delete serviceModule.DEFAULT_IMQ_CLIENT_OPTIONS.beforeCall;
}
if (afterCall) {
delete serviceModule.DEFAULT_IMQ_CLIENT_OPTIONS.afterCall;
}
}
static unpatchService(serviceModule) {
if (!serviceModule.DEFAULT_IMQ_SERVICE_OPTIONS) {
return;
}
const { beforeCall, afterCall, } = serviceModule.DEFAULT_IMQ_SERVICE_OPTIONS;
if (beforeCall) {
delete serviceModule.DEFAULT_IMQ_SERVICE_OPTIONS.beforeCall;
}
if (afterCall) {
delete serviceModule.DEFAULT_IMQ_SERVICE_OPTIONS.afterCall;
}
}
}
exports.ImqueueInstrumentation = ImqueueInstrumentation;
//# sourceMappingURL=instrumentation.js.map