From 184b21229c7831050182d9add336f94b935c6d01 Mon Sep 17 00:00:00 2001 From: pikalovArtemN Date: Fri, 3 May 2024 22:22:22 +0300 Subject: [PATCH] chore(instrumentation-runtime-node): fetch other metrics to convention --- .../src/instrumentation.ts | 2 +- .../src/metrics/eventLoopLagCollector.ts | 46 ++++---- .../metrics/eventLoopUtilizationCollector.ts | 4 +- .../src/metrics/gcCollector.ts | 4 +- .../src/metrics/heapSizeAndUsedCollector.ts | 71 +++-------- .../metrics/heapSpacesSizeAndUsedCollector.ts | 110 +++++++----------- .../src/types/heapSizes.ts | 4 + .../src/types/heapSpaces.ts | 5 + 8 files changed, 99 insertions(+), 147 deletions(-) create mode 100644 plugins/node/instrumentation-runtime-node/src/types/heapSizes.ts create mode 100644 plugins/node/instrumentation-runtime-node/src/types/heapSpaces.ts diff --git a/plugins/node/instrumentation-runtime-node/src/instrumentation.ts b/plugins/node/instrumentation-runtime-node/src/instrumentation.ts index a222757982..1d5f59bca8 100644 --- a/plugins/node/instrumentation-runtime-node/src/instrumentation.ts +++ b/plugins/node/instrumentation-runtime-node/src/instrumentation.ts @@ -28,7 +28,7 @@ const DEFAULT_CONFIG: RuntimeNodeInstrumentationConfig = { monitoringPrecision: 5000, }; -const namePrefix = 'nodejs'; +const namePrefix = 'jsruntime'; export class RuntimeNodeInstrumentation extends InstrumentationBase { private _collectors: MetricCollector[] = []; diff --git a/plugins/node/instrumentation-runtime-node/src/metrics/eventLoopLagCollector.ts b/plugins/node/instrumentation-runtime-node/src/metrics/eventLoopLagCollector.ts index cede9930f2..49021deba6 100644 --- a/plugins/node/instrumentation-runtime-node/src/metrics/eventLoopLagCollector.ts +++ b/plugins/node/instrumentation-runtime-node/src/metrics/eventLoopLagCollector.ts @@ -16,12 +16,13 @@ import {RuntimeNodeInstrumentationConfig} from '../types'; import {Meter} from '@opentelemetry/api'; import * as perf_hooks from 'node:perf_hooks'; +import {version} from 'node:process'; import {IntervalHistogram} from 'node:perf_hooks'; import {BaseCollector} from './baseCollector'; import {NODE_JS_VERSION_ATTRIBUTE} from "../consts/attributes"; const NODEJS_EVENTLOOP_LAG = 'eventloop.lag'; -const NODEJS_EVENTLOOP_LAG_ATTRIBUTE_TYPE = 'nodejs.eventloop.lag.type'; +const NODEJS_EVENTLOOP_LAG_ATTRIBUTE_TYPE = 'eventloop.lag.type'; export interface EventLoopLagInformation { @@ -54,32 +55,31 @@ export class EventLoopLagCollector extends BaseCollector { - if (this._scrapeQueue.length === 0) return; - - const data = this._scrapeQueue.shift(); - if (data === undefined) return; - - const start = process.hrtime(); - const lagResult = await new Promise(res => { - setImmediate((start: [number, number]) => { - res(this._reportEventloopLag(start)); - }, start); - }); + ).addCallback(async observableResult => { + if (this._scrapeQueue.length === 0) return; - observableResult.observe(lagResult, { - [NODE_JS_VERSION_ATTRIBUTE]: process.version - }); + const data = this._scrapeQueue.shift(); + if (data === undefined) return; - for(const [value, attributeType] of Object.keys(data).entries()) { - observableResult.observe(value, { - [NODEJS_EVENTLOOP_LAG_ATTRIBUTE_TYPE]: attributeType, - [NODE_JS_VERSION_ATTRIBUTE]: process.version - }); - } + const start = process.hrtime(); + const lagResult = await new Promise(res => { + setImmediate((start: [number, number]) => { + res(this._reportEventloopLag(start)); + }, start); + }); + observableResult.observe(lagResult, { + [NODE_JS_VERSION_ATTRIBUTE]: version }); + + for (const [value, attributeType] of Object.keys(data).entries()) { + observableResult.observe(value, { + [NODEJS_EVENTLOOP_LAG_ATTRIBUTE_TYPE]: attributeType, + [`${this.namePrefix}.${NODEJS_EVENTLOOP_LAG_ATTRIBUTE_TYPE}`]: version + }); + } + + }); } internalEnable(): void { diff --git a/plugins/node/instrumentation-runtime-node/src/metrics/eventLoopUtilizationCollector.ts b/plugins/node/instrumentation-runtime-node/src/metrics/eventLoopUtilizationCollector.ts index f44b400eb9..17eeec1228 100644 --- a/plugins/node/instrumentation-runtime-node/src/metrics/eventLoopUtilizationCollector.ts +++ b/plugins/node/instrumentation-runtime-node/src/metrics/eventLoopUtilizationCollector.ts @@ -20,7 +20,7 @@ import { BaseCollector } from './baseCollector'; const { eventLoopUtilization: eventLoopUtilizationCollector } = performance; -const NODEJS_EVENT_LOOP_UTILIZATION = 'event_loop.utilization'; +const NODEJS_EVENT_LOOP_UTILIZATION = 'eventloop.utilization'; export class EventLoopUtilizationCollector extends BaseCollector { constructor( @@ -36,7 +36,7 @@ export class EventLoopUtilizationCollector extends BaseCollector { diff --git a/plugins/node/instrumentation-runtime-node/src/metrics/gcCollector.ts b/plugins/node/instrumentation-runtime-node/src/metrics/gcCollector.ts index 8991820c2a..fbe8cf476b 100644 --- a/plugins/node/instrumentation-runtime-node/src/metrics/gcCollector.ts +++ b/plugins/node/instrumentation-runtime-node/src/metrics/gcCollector.ts @@ -20,7 +20,7 @@ import { BaseCollector } from './baseCollector'; import * as perf_hooks from 'node:perf_hooks'; import { PerformanceObserver } from 'node:perf_hooks'; -const NODEJS_GC_DURATION_SECONDS = 'gc.duration_seconds'; +const NODEJS_GC_DURATION_SECONDS = 'gc.duration'; const DEFAULT_GC_DURATION_BUCKETS = [0.001, 0.01, 0.1, 1, 2, 5]; const kinds: string[] = []; @@ -59,7 +59,7 @@ export class GCCollector extends BaseCollector { { description: 'Garbage collection duration by kind, one of major, minor, incremental or weakcb.', - unit: 'double', + unit: 's', valueType: ValueType.DOUBLE, advice: { explicitBucketBoundaries: DEFAULT_GC_DURATION_BUCKETS, diff --git a/plugins/node/instrumentation-runtime-node/src/metrics/heapSizeAndUsedCollector.ts b/plugins/node/instrumentation-runtime-node/src/metrics/heapSizeAndUsedCollector.ts index 7af05bb521..d00c13df32 100644 --- a/plugins/node/instrumentation-runtime-node/src/metrics/heapSizeAndUsedCollector.ts +++ b/plugins/node/instrumentation-runtime-node/src/metrics/heapSizeAndUsedCollector.ts @@ -16,25 +16,10 @@ import { RuntimeNodeInstrumentationConfig } from '../types'; import { Meter } from '@opentelemetry/api'; import { BaseCollector } from './baseCollector'; +import {HeapSizes} from "../types/heapSizes"; -const NODEJS_HEAP_SIZE_TOTAL = 'heap_size_total_bytes'; -const NODEJS_HEAP_SIZE_USED = 'heap_size_used_bytes'; -const NODEJS_EXTERNAL_MEMORY = 'external_memory_bytes'; - -export const metricNames = [ - { - name: NODEJS_HEAP_SIZE_TOTAL, - description: 'Process heap size from Node.js in bytes.', - }, - { - name: NODEJS_HEAP_SIZE_USED, - description: 'Process heap size used from Node.js in bytes.', - }, - { - name: NODEJS_EXTERNAL_MEMORY, - description: 'Node.js external memory size in bytes.', - }, -]; +const NODEJS_HEAP_SIZE = 'heap.size'; +const NODEJS_HEAP_SIZE_STATE = 'heap.size.state'; export class HeapSizeAndUsedCollector extends BaseCollector { constructor( @@ -45,42 +30,24 @@ export class HeapSizeAndUsedCollector extends BaseCollector } updateMetricInstruments(meter: Meter): void { - const heapSizeTotal = meter.createObservableGauge( - `${this.namePrefix}.${metricNames[0].name}`, - { - description: metricNames[0].description, - unit: '1', - } - ); - const heapSizeUsed = meter.createObservableGauge( - `${this.namePrefix}.${metricNames[1].name}`, + meter.createObservableGauge( + `${this.namePrefix}.${NODEJS_HEAP_SIZE}`, { - description: metricNames[1].description, - unit: '1', + description: "Process heap size from Node.js in bytes.", + unit: 'By', } - ); - const externalMemUsed = meter.createObservableGauge( - `${this.namePrefix}.${metricNames[2].name}`, - { - description: metricNames[2].description, - unit: '1', - } - ); - - meter.addBatchObservableCallback( - observableResult => { - if (this._scrapeQueue.length === 0) return; - - const data = this._scrapeQueue.shift(); - if (data === undefined) return; - observableResult.observe(heapSizeTotal, data.heapTotal); - observableResult.observe(heapSizeUsed, data.heapUsed); - if (data.external !== undefined) { - observableResult.observe(externalMemUsed, data.external); - } - }, - [heapSizeTotal, heapSizeUsed, externalMemUsed] - ); + ).addCallback(async observableResult => { + if (this._scrapeQueue.length === 0) return; + + const data = this._scrapeQueue.shift(); + if (data === undefined) return; + observableResult.observe(data.heapTotal, { + [`${this.namePrefix}.${NODEJS_HEAP_SIZE_STATE}`]: HeapSizes.Total + }); + observableResult.observe(data.heapUsed, { + [`${this.namePrefix}.${NODEJS_HEAP_SIZE_STATE}`]: HeapSizes.Used + }); + }); } internalEnable(): void {} diff --git a/plugins/node/instrumentation-runtime-node/src/metrics/heapSpacesSizeAndUsedCollector.ts b/plugins/node/instrumentation-runtime-node/src/metrics/heapSpacesSizeAndUsedCollector.ts index 62d817c126..20877e04ab 100644 --- a/plugins/node/instrumentation-runtime-node/src/metrics/heapSpacesSizeAndUsedCollector.ts +++ b/plugins/node/instrumentation-runtime-node/src/metrics/heapSpacesSizeAndUsedCollector.ts @@ -13,30 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { RuntimeNodeInstrumentationConfig } from '../types'; -import { Meter } from '@opentelemetry/api'; -import { BaseCollector } from './baseCollector'; +import {RuntimeNodeInstrumentationConfig} from '../types'; +import {Meter} from '@opentelemetry/api'; +import {BaseCollector} from './baseCollector'; import * as v8 from 'node:v8'; -import { HeapSpaceInfo } from 'v8'; +import {HeapSpaceInfo} from 'v8'; +import {HeapSpaces} from "../types/heapSpaces"; -const NODEJS_HEAP_SPACE_TOTAL = 'heap_space_total_bytes'; -const NODEJS_HEAP_SPACE_USED = 'heap_space_used_bytes'; -const NODEJS_HEAP_SPACE_AVAILABLE = 'heap_space_available_bytes'; +const NODEJS_HEAP_SPACE = 'heap.space'; +const NODEJS_HEAP_SPACE_STATE = 'heap.space.state'; +const NODEJS_HEAP_SPACE_SPACENAME = 'heap.space.spacename'; -export const metricNames = [ - { - name: NODEJS_HEAP_SPACE_TOTAL, - description: 'Process heap space size total from Node.js in bytes.', - }, - { - name: NODEJS_HEAP_SPACE_USED, - description: 'Process heap space size used from Node.js in bytes.', - }, - { - name: NODEJS_HEAP_SPACE_AVAILABLE, - description: 'Process heap space size available from Node.js in bytes.', - }, -]; export class HeapSpacesSizeAndUsedCollector extends BaseCollector< HeapSpaceInfo[] @@ -49,59 +36,48 @@ export class HeapSpacesSizeAndUsedCollector extends BaseCollector< } updateMetricInstruments(meter: Meter): void { - const heapSpaceTotal = meter.createObservableGauge( - `${this.namePrefix}.${metricNames[0].name}`, + meter.createObservableGauge( + `${this.namePrefix}.${NODEJS_HEAP_SPACE}`, { - description: metricNames[0].description, - unit: 'bytes', + description: "Process heap space size total from Node.js in bytes.", + unit: 'By', } - ); - const heapSpaceUsed = meter.createObservableGauge( - `${this.namePrefix}.${metricNames[1].name}`, - { - description: metricNames[1].description, - unit: 'bytes', - } - ); - const heapSpaceAvailable = meter.createObservableGauge( - `${this.namePrefix}.${metricNames[2].name}`, - { - description: metricNames[2].description, - unit: 'bytes', - } - ); + ).addCallback(async observableResult => { + if (this._scrapeQueue.length === 0) return; - meter.addBatchObservableCallback( - observableResult => { - if (this._scrapeQueue.length === 0) return; + const data = this._scrapeQueue.shift(); + if (data === undefined) return; + for (const space of data) { + const spaceName = space.space_name.substring( + 0, + space.space_name.indexOf('_space') + ); + observableResult.observe(space.space_size, { + [`${this.namePrefix}.${NODEJS_HEAP_SPACE_SPACENAME}`]: spaceName, + [`${this.namePrefix}.${NODEJS_HEAP_SPACE_STATE}`]: HeapSpaces.Total + }); + observableResult.observe(space.space_used_size, { + [`${this.namePrefix}.${NODEJS_HEAP_SPACE_SPACENAME}`]: spaceName, + [`${this.namePrefix}.${NODEJS_HEAP_SPACE_STATE}`]: HeapSpaces.Used + + }); + observableResult.observe( + space.space_available_size, + { + [`${this.namePrefix}.${NODEJS_HEAP_SPACE_SPACENAME}`]: spaceName, + [`${this.namePrefix}.${NODEJS_HEAP_SPACE_STATE}`]: HeapSpaces.Availabe + } + ); + } + }); - const data = this._scrapeQueue.shift(); - if (data === undefined) return; - for (const space of data) { - const spaceName = space.space_name.substring( - 0, - space.space_name.indexOf('_space') - ); - observableResult.observe(heapSpaceTotal, space.space_size, { - space: spaceName, - }); - observableResult.observe(heapSpaceUsed, space.space_used_size, { - space: spaceName, - }); - observableResult.observe( - heapSpaceAvailable, - space.space_available_size, - { space: spaceName } - ); - } - }, - [heapSpaceTotal, heapSpaceUsed, heapSpaceAvailable] - ); } - internalEnable(): void {} + internalEnable(): void { + } - internalDisable(): void {} + internalDisable(): void { + } protected scrape(): HeapSpaceInfo[] { return v8.getHeapSpaceStatistics(); diff --git a/plugins/node/instrumentation-runtime-node/src/types/heapSizes.ts b/plugins/node/instrumentation-runtime-node/src/types/heapSizes.ts new file mode 100644 index 0000000000..36fccdf1d9 --- /dev/null +++ b/plugins/node/instrumentation-runtime-node/src/types/heapSizes.ts @@ -0,0 +1,4 @@ +export enum HeapSizes { + Total = "total", + Used = "used", +} diff --git a/plugins/node/instrumentation-runtime-node/src/types/heapSpaces.ts b/plugins/node/instrumentation-runtime-node/src/types/heapSpaces.ts new file mode 100644 index 0000000000..af9f843607 --- /dev/null +++ b/plugins/node/instrumentation-runtime-node/src/types/heapSpaces.ts @@ -0,0 +1,5 @@ +export enum HeapSpaces { + Total = "total", + Used = "used", + Availabe = "available" +}