@splunk/otel
Version:
The Splunk distribution of OpenTelemetry Node Instrumentation provides a Node agent that automatically instruments your Node application to capture and report distributed traces to Splunk APM.
122 lines • 5.09 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.OtlpHttpProfilingExporter = void 0;
const api_1 = require("@opentelemetry/api");
const resources_1 = require("@opentelemetry/resources");
const core_1 = require("@opentelemetry/core");
const package_json_1 = require("../../package.json");
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
const utils_1 = require("./utils");
const OTEL_SDK_VERSION = package_json_1.dependencies['@opentelemetry/core'];
function countSamples(stacktraces) {
let sampleCount = 0;
for (const profilingStacktrace of stacktraces) {
sampleCount += profilingStacktrace.stacktrace.length;
}
return sampleCount;
}
function commonAttributes(profilingType, sampleCount, instrumentationSource) {
return {
'profiling.data.format': 'pprof-gzip-base64',
'profiling.data.type': profilingType,
'com.splunk.sourcetype': 'otel.profiling',
'profiling.data.total.frame.count': sampleCount,
'profiling.instrumentation.source': instrumentationSource,
};
}
function createEndpoint(endpoint) {
if (endpoint.includes('/v1/logs')) {
return endpoint;
}
return new URL('/v1/logs', endpoint).href;
}
const OTEL_PROFILING_VERSION = '0.1.0';
class OtlpHttpProfilingExporter {
constructor(options) {
this._callstackInterval = options.callstackInterval;
this._endpoint = createEndpoint(options.endpoint);
this._resource = (0, resources_1.resourceFromAttributes)({
[semantic_conventions_1.ATTR_TELEMETRY_SDK_LANGUAGE]: 'node',
[semantic_conventions_1.ATTR_TELEMETRY_SDK_VERSION]: OTEL_SDK_VERSION,
}).merge(options.resource);
this._instrumentationSource = options.instrumentationSource;
this._scope = {
name: 'otel.profiling',
version: OTEL_PROFILING_VERSION,
};
}
async send(profile) {
const { stacktraces } = profile;
const sampleCount = countSamples(stacktraces);
api_1.diag.debug(`profiling: Exporting ${sampleCount} CPU samples`);
const attributes = commonAttributes('cpu', sampleCount, this._instrumentationSource);
return (0, utils_1.encode)((0, utils_1.serialize)(profile, { samplingPeriodMillis: this._callstackInterval }))
.then((serializedProfile) => {
const ts = (0, core_1.hrTime)();
const logs = [
{
hrTime: ts,
hrTimeObserved: ts,
body: serializedProfile.toString('base64'),
resource: this._resource,
instrumentationScope: this._scope,
attributes,
droppedAttributesCount: 0,
},
];
api_1.context.with((0, core_1.suppressTracing)(api_1.context.active()), () => {
this._getExporter().export(logs, (result) => {
if (result.error !== undefined) {
api_1.diag.error('Error exporting profiling data', result.error);
}
});
});
})
.catch((err) => {
api_1.diag.error('Error encoding cpu profile', err);
});
}
async sendHeapProfile(profile) {
const serialized = (0, utils_1.serializeHeapProfile)(profile);
const sampleCount = profile.samples.length;
const attributes = commonAttributes('allocation', sampleCount, 'continuous');
api_1.diag.debug(`profiling: Exporting ${sampleCount} heap samples`);
return (0, utils_1.encode)(serialized)
.then((serializedProfile) => {
const ts = (0, core_1.hrTime)();
const logs = [
{
hrTime: ts,
hrTimeObserved: ts,
body: serializedProfile.toString('base64'),
resource: this._resource,
instrumentationScope: this._scope,
attributes,
droppedAttributesCount: 0,
},
];
api_1.context.with((0, core_1.suppressTracing)(api_1.context.active()), () => {
this._getExporter().export(logs, (result) => {
if (result.error !== undefined) {
api_1.diag.error('Error exporting profiling data', result.error);
}
});
});
})
.catch((err) => {
api_1.diag.error('Error encoding heap profile', err);
});
}
_getExporter() {
if (this._exporter !== undefined) {
return this._exporter;
}
const { OTLPLogExporter, } = require('@opentelemetry/exporter-logs-otlp-proto');
this._exporter = new OTLPLogExporter({
url: this._endpoint,
});
return this._exporter;
}
}
exports.OtlpHttpProfilingExporter = OtlpHttpProfilingExporter;
//# sourceMappingURL=OtlpHttpProfilingExporter.js.map
;