UNPKG

@ogcio/o11y-sdk-node

Version:

Opentelemetry standard instrumentation SDK for NodeJS based project

61 lines (60 loc) 3.17 kB
import { OnEndingHookSpanProcessor } from "./on-ending-hook-span-processor.js"; const PROFILING_ATTRIBUTE_PREFIX = "profiling"; /** * A SpanProcessor that captures pseudo-profiling data (CPU time and memory usage) * for each span and adds them as span attributes. * * This processor wraps the span's end() method to capture profiling metrics * just before the span is marked as ended, while the span is still writable. */ export class PseudoProfilingSpanProcessor extends OnEndingHookSpanProcessor { _spanProfilingData = new WeakMap(); onStart(span, _context) { super.onStart(span, _context); const cpuUsageStart = process.cpuUsage(); const memoryUsageStart = process.memoryUsage(); // Store profiling data this._spanProfilingData.set(span, { cpuUsageStart, memoryUsageStart, }); } onEnding(span) { this._captureProfilingData(span); } /** * Captures profiling data and sets attributes on the span. * Called just before the span is ended, while it's still writable. */ _captureProfilingData(span) { const profilingData = this._spanProfilingData.get(span); if (!profilingData) { return; } const { cpuUsageStart, memoryUsageStart } = profilingData; const cpuUsageEnd = process.cpuUsage(cpuUsageStart); const memoryUsageEnd = process.memoryUsage(); const memoryDelta = { heapUsed: memoryUsageEnd.heapUsed - memoryUsageStart.heapUsed, heapTotal: memoryUsageEnd.heapTotal - memoryUsageStart.heapTotal, external: memoryUsageEnd.external - memoryUsageStart.external, rss: memoryUsageEnd.rss - memoryUsageStart.rss, arrayBuffers: memoryUsageEnd.arrayBuffers - memoryUsageStart.arrayBuffers, }; // CPU time in microseconds span.setAttribute(`${PROFILING_ATTRIBUTE_PREFIX}.cpu.user_time_us`, cpuUsageEnd.user); span.setAttribute(`${PROFILING_ATTRIBUTE_PREFIX}.cpu.system_time_us`, cpuUsageEnd.system); span.setAttribute(`${PROFILING_ATTRIBUTE_PREFIX}.cpu.total_time_us`, cpuUsageEnd.user + cpuUsageEnd.system); // Memory delta in bytes span.setAttribute(`${PROFILING_ATTRIBUTE_PREFIX}.memory.heap_used_delta_bytes`, memoryDelta.heapUsed); span.setAttribute(`${PROFILING_ATTRIBUTE_PREFIX}.memory.heap_total_delta_bytes`, memoryDelta.heapTotal); span.setAttribute(`${PROFILING_ATTRIBUTE_PREFIX}.memory.external_delta_bytes`, memoryDelta.external); span.setAttribute(`${PROFILING_ATTRIBUTE_PREFIX}.memory.rss_delta_bytes`, memoryDelta.rss); span.setAttribute(`${PROFILING_ATTRIBUTE_PREFIX}.memory.array_buffers_delta_bytes`, memoryDelta.arrayBuffers); // Absolute memory values at span end (useful for overall monitoring) span.setAttribute(`${PROFILING_ATTRIBUTE_PREFIX}.memory.heap_used_bytes`, memoryUsageEnd.heapUsed); span.setAttribute(`${PROFILING_ATTRIBUTE_PREFIX}.memory.heap_total_bytes`, memoryUsageEnd.heapTotal); // Clean up the WeakMap entry this._spanProfilingData.delete(span); } }