UNPKG

@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
"use strict"; 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