autotel
Version:
Write Once, Observe Anywhere
109 lines (107 loc) • 4.97 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_values = require('./values-tm4bi0FF.cjs');
const require_functional = require('./functional-CJI0HCVJ.cjs');
const require_trace_factory_validation = require('./trace-factory-validation-Dc8epn87.cjs');
let _opentelemetry_api = require("@opentelemetry/api");
//#region src/semantic-helpers.ts
/**
* Semantic convention helpers for OpenTelemetry
*
* Pre-configured trace helpers that follow OpenTelemetry semantic conventions
* for common operation types. Reduces boilerplate and ensures consistency.
*
* Based on: https://opentelemetry.io/docs/specs/semconv/
*/
function setConfiguredAttributes(ctx, attributes) {
if (!attributes) return;
for (const [key, value] of Object.entries(attributes)) {
const attributeValue = require_values.toAttributeValue(value);
if (attributeValue !== void 0) ctx.setAttribute(key, attributeValue);
}
}
/**
* Shared tail of `traceDB`/`traceHTTP`/`traceMessaging`: wrap `fn` directly
* when given, otherwise return the curried factory-acceptor form.
*/
function wrapSemantic(helperName, name, spanKind, configure, fn) {
if (fn) {
require_trace_factory_validation.assertTraceFactory(helperName, fn);
return require_functional.withTracing({
name,
spanKind
})((ctx) => {
configure(ctx);
return fn;
});
}
return (factory) => {
require_trace_factory_validation.assertTraceFactory(helperName, factory);
return require_functional.withTracing({
name,
spanKind
})((ctx) => {
configure(ctx);
const handler = factory(ctx);
require_trace_factory_validation.assertTraceFactory(helperName, handler, "result");
return handler;
});
};
}
function traceDB(config, fn) {
if (require_values.asRecord(config) === void 0) throw new TypeError("traceDB: config must be an object");
if (require_values.nonEmptyString(config.system) === void 0) throw new TypeError("traceDB: config.system must be a non-empty string");
const target = config.collection ?? config.database;
const spanName = (config.querySummary ?? [config.operation, target].filter(Boolean).join(" ")) || config.system;
const configure = (ctx) => {
ctx.setAttribute("db.system.name", config.system);
ctx.setAttribute("db.system.name", config.system);
if (config.operation) {
ctx.setAttribute("db.operation.name", config.operation);
ctx.setAttribute("db.operation.name", config.operation);
}
if (config.database) {
ctx.setAttribute("db.namespace", config.database);
ctx.setAttribute("db.namespace", config.database);
}
if (config.collection) ctx.setAttribute("db.collection.name", config.collection);
if (config.querySummary) ctx.setAttribute("db.query.summary", config.querySummary);
setConfiguredAttributes(ctx, config.attributes);
};
return wrapSemantic("traceDB", spanName, _opentelemetry_api.SpanKind.CLIENT, configure, fn);
}
function traceHTTP(config, fn) {
if (require_values.asRecord(config) === void 0) throw new TypeError("traceHTTP: config must be an object");
const method = config.method?.toUpperCase() || "HTTP";
const target = config.route ?? config.urlTemplate;
const spanName = target ? `${method} ${target}` : method;
const configure = (ctx) => {
if (config.method) ctx.setAttribute("http.request.method", method);
if (config.url) ctx.setAttribute("url.full", config.url);
if (config.route) ctx.setAttribute("http.route", config.route);
if (config.urlTemplate) ctx.setAttribute("url.template", config.urlTemplate);
setConfiguredAttributes(ctx, config.attributes);
};
return wrapSemantic("traceHTTP", spanName, _opentelemetry_api.SpanKind.CLIENT, configure, fn);
}
function traceMessaging(config, fn) {
if (require_values.asRecord(config) === void 0) throw new TypeError("traceMessaging: config must be an object");
if (require_values.nonEmptyString(config.system) === void 0) throw new TypeError("traceMessaging: config.system must be a non-empty string");
const operation = config.operation ?? "messaging";
const spanName = [operation, config.destination].filter(Boolean).join(" ");
const operationType = operation === "publish" ? "send" : operation;
const spanKind = operation === "publish" ? _opentelemetry_api.SpanKind.PRODUCER : operation === "process" ? _opentelemetry_api.SpanKind.CONSUMER : operation === "receive" ? _opentelemetry_api.SpanKind.CLIENT : _opentelemetry_api.SpanKind.INTERNAL;
const configure = (ctx) => {
ctx.setAttribute("messaging.system", config.system);
if (config.operation) {
ctx.setAttribute("messaging.operation.name", config.operation);
ctx.setAttribute("messaging.operation.type", operationType);
}
if (config.destination) ctx.setAttribute("messaging.destination.name", config.destination);
setConfiguredAttributes(ctx, config.attributes);
};
return wrapSemantic("traceMessaging", spanName, spanKind, configure, fn);
}
//#endregion
exports.traceDB = traceDB;
exports.traceHTTP = traceHTTP;
exports.traceMessaging = traceMessaging;