@ogcio/o11y-sdk-node
Version:
Opentelemetry standard instrumentation SDK for NodeJS based project
51 lines (50 loc) • 2.07 kB
JavaScript
import { createNoopMeter, metrics, } from "@opentelemetry/api";
import { getGeoAttributes } from "../../sdk-core/lib/index.js";
import { getNodeSdkConfig } from "./config-manager.js";
const MetricsFactoryMap = {
gauge: (meter) => meter.createGauge.bind(meter),
histogram: (meter) => meter.createHistogram.bind(meter),
counter: (meter) => meter.createCounter.bind(meter),
updowncounter: (meter) => meter.createUpDownCounter.bind(meter),
"async-counter": (meter) => meter.createObservableCounter.bind(meter),
"async-updowncounter": (meter) => meter.createObservableUpDownCounter.bind(meter),
"async-gauge": (meter) => meter.createObservableGauge.bind(meter),
};
function getMeter({ meterName }) {
if (!meterName) {
console.error("Invalid metric name!");
return createNoopMeter();
}
return metrics.getMeter(`custom_metric.${meterName}`);
}
export function getMetric(type, p) {
const meter = getMeter(p);
if (!MetricsFactoryMap[type]) {
throw new Error(`Unsupported metric type: ${type}`);
}
const instrument = MetricsFactoryMap[type](meter).bind(meter)(p.metricName, p.options);
const geoEnabled = getNodeSdkConfig()?.geoEnrichment?.enabled === true;
if (!geoEnabled || type.startsWith("async-")) {
return instrument;
}
return wrapWithGeoAttributes(instrument);
}
function wrapWithGeoAttributes(instrument) {
if (typeof instrument !== "object" || instrument === null) {
return instrument;
}
return new Proxy(instrument, {
get(target, prop, receiver) {
const value = Reflect.get(target, prop, receiver);
if (typeof value !== "function")
return value;
if (prop === "add" || prop === "record") {
return (amount, attributes, ...rest) => {
const merged = { ...getGeoAttributes(), ...attributes };
return value.call(target, amount, merged, ...rest);
};
}
return value.bind(target);
},
});
}