Skip to content

Commit

Permalink
chore(instrumentation-runtime-node): synchronize with convention
Browse files Browse the repository at this point in the history
  • Loading branch information
pikalovArtemN committed Jul 6, 2024
1 parent ade0ab9 commit 7418c78
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 215 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
* limitations under the License.
*/
export const NODE_JS_VERSION_ATTRIBUTE = 'nodejsruntime.version';
export const V8_HEAP_SIZE_STATE_ATTRIBUTE = 'heap.size.state';
export const V8_HEAP_SIZE_NAME_ATTRIBUTE = 'heap.space.name';
export const V8_HEAP_SIZE = 'heap.size';
10 changes: 5 additions & 5 deletions plugins/node/instrumentation-runtime-node/src/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,20 @@ export class RuntimeNodeInstrumentation extends InstrumentationBase {
this._collectors = [
new EventLoopUtilizationCollector(
this._config,
ConventionalNamePrefix.NodeJsRuntime
ConventionalNamePrefix.NodeJs
),
new EventLoopDelayCollector(
this._config,
ConventionalNamePrefix.NodeJsRuntime
ConventionalNamePrefix.NodeJs
),
new GCCollector(this._config, ConventionalNamePrefix.V8EnjineRuntime),
new GCCollector(this._config, ConventionalNamePrefix.V8js),
new HeapSizeAndUsedCollector(
this._config,
ConventionalNamePrefix.V8EnjineRuntime
ConventionalNamePrefix.V8js
),
new HeapSpacesSizeAndUsedCollector(
this._config,
ConventionalNamePrefix.V8EnjineRuntime
ConventionalNamePrefix.V8js
),
];
if (this._config.enabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,21 @@ import { MetricCollector } from '../types/metricCollector';
import { Meter } from '@opentelemetry/api';
import { clearInterval } from 'node:timers';
import { RuntimeNodeInstrumentationConfig } from '../types';
import { NODE_JS_VERSION_ATTRIBUTE } from '../consts/attributes';

type VersionAttribute = { [NODE_JS_VERSION_ATTRIBUTE]: string };

export abstract class BaseCollector<T> implements MetricCollector {
protected _config: RuntimeNodeInstrumentationConfig = {};

protected namePrefix: string;
private _interval: NodeJS.Timeout | undefined;
protected _scrapeQueue: T[] = [];
protected versionAttribute: VersionAttribute;

protected constructor(
config: RuntimeNodeInstrumentationConfig = {},
namePrefix: string
) {
this._config = config;
this.namePrefix = namePrefix;
this.versionAttribute = { [NODE_JS_VERSION_ATTRIBUTE]: process.version };
}

public disable(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,40 @@ import {IntervalHistogram} from 'node:perf_hooks';
import {BaseCollector} from './baseCollector';

enum NodeJsEventLoopDelay {
delay = 'eventloop.delay',
min = 'eventloop.delay.min',
max = 'eventloop.delay.max',
mean = 'eventloop.delay.mean',
stddev = 'eventloop.delay.stddev',
p50 = 'eventloop.delay.p50',
p90 = 'eventloop.delay.p90',
p99 = 'eventloop.delay.p99',
p99 = 'eventloop.delay.p99'
}

export const metricNames: Record<
NodeJsEventLoopDelay,
{ description: string }
> = {
[NodeJsEventLoopDelay.delay]: {
description: 'Lag of event loop in seconds.',
},
[NodeJsEventLoopDelay.min]: {
description: 'The minimum recorded event loop delay.',
description: 'Event loop minimum delay.',
},
[NodeJsEventLoopDelay.max]: {
description: 'The maximum recorded event loop delay.',
description: 'Event loop maximum delay.',
},
[NodeJsEventLoopDelay.mean]: {
description: 'The mean of the recorded event loop delays.',
description: 'Event loop mean delay.',
},
[NodeJsEventLoopDelay.stddev]: {
description: 'The standard deviation of the recorded event loop delays.',
description: 'Event loop standard deviation delay.',
},
[NodeJsEventLoopDelay.p50]: {
description: 'The 50th percentile of the recorded event loop delays.',
description: 'Event loop 50 percentile delay.',
},
[NodeJsEventLoopDelay.p90]: {
description: 'The 90th percentile of the recorded event loop delays.',
description: 'Event loop 90 percentile delay.',
},
[NodeJsEventLoopDelay.p99]: {
description: 'The 99th percentile of the recorded event loop delays.',
},
description: 'Event loop 99 percentile delay.',
}
};

export interface EventLoopLagInformation {
Expand All @@ -84,13 +80,6 @@ export class EventLoopDelayCollector extends BaseCollector<EventLoopLagInformati
}

updateMetricInstruments(meter: Meter): void {
const delay = meter.createObservableGauge(
`${this.namePrefix}.${NodeJsEventLoopDelay.delay}`,
{
description: metricNames[NodeJsEventLoopDelay.delay].description,
unit: 's',
}
);
const delayMin = meter.createObservableGauge(
`${this.namePrefix}.${NodeJsEventLoopDelay.min}`,
{
Expand Down Expand Up @@ -148,30 +137,17 @@ export class EventLoopDelayCollector extends BaseCollector<EventLoopLagInformati
const data = this._scrapeQueue.shift();
if (data === undefined) return;

const startHrTime = process.hrtime();
const delayResult = await new Promise<number>(res => {
setImmediate((start: [number, number]) => {
res(this._reportEventloopLag(start));
}, startHrTime);
});

observableResult.observe(delay, delayResult, this.versionAttribute);
observableResult.observe(delayMin, data.min, this.versionAttribute);
observableResult.observe(delayMax, data.max, this.versionAttribute);
observableResult.observe(delayMean, data.mean, this.versionAttribute);
observableResult.observe(
delayStddev,
data.stddev,
this.versionAttribute
);
observableResult.observe(delayp50, data.p50, this.versionAttribute);
observableResult.observe(delayp90, data.p90, this.versionAttribute);
observableResult.observe(delayp99, data.p99, this.versionAttribute);
observableResult.observe(delayMin, data.min);
observableResult.observe(delayMax, data.max);
observableResult.observe(delayMean, data.mean);
observableResult.observe(delayStddev, data.stddev);
observableResult.observe(delayp50, data.p50);
observableResult.observe(delayp90, data.p90);
observableResult.observe(delayp99, data.p99);

this._histogram.reset();
},
[
delay,
delayMin,
delayMax,
delayMean,
Expand All @@ -197,17 +173,12 @@ export class EventLoopDelayCollector extends BaseCollector<EventLoopLagInformati
max: this.checkNan(this._histogram.max / 1e9),
mean: this.checkNan(this._histogram.mean / 1e9),
stddev: this.checkNan(this._histogram.stddev / 1e9),
p50: this.checkNan(this._histogram.percentile(90) / 1e9),
p50: this.checkNan(this._histogram.percentile(50) / 1e9),
p90: this.checkNan(this._histogram.percentile(90) / 1e9),
p99: this.checkNan(this._histogram.percentile(99) / 1e9),
};
}

private _reportEventloopLag(start: [number, number]): number {
const delta = process.hrtime(start);
const nanosec = delta[0] * 1e9 + delta[1];
return nanosec / 1e9;
}

private checkNan(value: number) {
return isNaN(value) ? 0 : value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class EventLoopUtilizationCollector extends BaseCollector<EventLoopUtiliz
return;
}
const elu = eventLoopUtilizationCollector(this._scrapeQueue.shift());
observableResult.observe(elu.utilization, this.versionAttribute);
observableResult.observe(elu.utilization);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ export class GCCollector extends BaseCollector<null> {
this._gcDurationByKindHistogram?.record(
entry.duration / 1000,
Object.assign(
{ [`${this.namePrefix}.gc.type`]: kind },
this.versionAttribute
{ [`${this.namePrefix}.gc.type`]: kind }
)
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { BaseCollector } from './baseCollector';
import { HeapSizes } from '../types/heapSizes';
import {
V8_HEAP_SIZE,
V8_HEAP_SIZE_STATE_ATTRIBUTE,
V8_HEAP_SIZE_NAME_ATTRIBUTE,
} from '../consts/attributes';

export class HeapSizeAndUsedCollector extends BaseCollector<NodeJS.MemoryUsage> {
Expand All @@ -42,14 +42,12 @@ export class HeapSizeAndUsedCollector extends BaseCollector<NodeJS.MemoryUsage>
const data = this._scrapeQueue.shift();
if (data === undefined) return;
observableResult.observe(data.heapTotal, {
[`${this.namePrefix}.${V8_HEAP_SIZE_STATE_ATTRIBUTE}`]:
[`${this.namePrefix}.${V8_HEAP_SIZE_NAME_ATTRIBUTE}`]:
HeapSizes.Total,
...this.versionAttribute,
});
observableResult.observe(data.heapUsed, {
[`${this.namePrefix}.${V8_HEAP_SIZE_STATE_ATTRIBUTE}`]:
[`${this.namePrefix}.${V8_HEAP_SIZE_NAME_ATTRIBUTE}`]:
HeapSizes.Used,
...this.versionAttribute,
});
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,28 @@ import { Meter } from '@opentelemetry/api';
import { BaseCollector } from './baseCollector';
import * as v8 from 'node:v8';
import { HeapSpaceInfo } from 'v8';
import { V8_HEAP_SIZE_STATE_ATTRIBUTE } from '../consts/attributes';
import { V8_HEAP_SIZE_NAME_ATTRIBUTE } from '../consts/attributes';

export enum V8HeapSpaceMetrics {
spaceSize = 'heap.space_size',
used = 'heap.space_used_size',
available = 'heap.space_available_size',
physical = 'heap.physical_space_size',
heapLimit = 'memory.heap.limit',
used = 'memory.heap.used',
available = 'memory.heap.space.available_size',
physical = 'memory.heap.space.physical_size',
}

export const metricNames: Record<V8HeapSpaceMetrics, { description: string }> =
{
[V8HeapSpaceMetrics.spaceSize]: {
description: 'Process heap space size total from Node.js in bytes.',
[V8HeapSpaceMetrics.heapLimit]: {
description: 'Total heap memory size pre-allocated.',
},
[V8HeapSpaceMetrics.used]: {
description: 'Process heap space size used from Node.js in bytes.',
description: 'Heap Memory size allocated.',
},
[V8HeapSpaceMetrics.available]: {
description: 'Process heap space size available from Node.js in bytes.',
description: 'Heap space available size.',
},
[V8HeapSpaceMetrics.physical]: {
description: 'Process heap space size available from Node.js in bytes.',
description: 'Committed size of a heap space.',
},
};

Expand All @@ -54,35 +54,35 @@ export class HeapSpacesSizeAndUsedCollector extends BaseCollector<
}

updateMetricInstruments(meter: Meter): void {
const heapSpaceSize = meter.createObservableGauge(
`${this.namePrefix}.${V8HeapSpaceMetrics.spaceSize}`,
const heapLimit = meter.createObservableGauge(
`${this.namePrefix}.${V8HeapSpaceMetrics.heapLimit}`,
{
description: metricNames[V8HeapSpaceMetrics.spaceSize].description,
unit: 'bytes',
description: metricNames[V8HeapSpaceMetrics.heapLimit].description,
unit: 'By',
}
);
const heapSpaceUsed = meter.createObservableGauge(
`${this.namePrefix}.${V8HeapSpaceMetrics.used}`,
{
description: metricNames[V8HeapSpaceMetrics.used].description,
unit: 'bytes',
unit: 'By',
}
);
const heapSpaceAvailable = meter.createObservableGauge(
`${this.namePrefix}.${V8HeapSpaceMetrics.available}`,
{
description: metricNames[V8HeapSpaceMetrics.available].description,
unit: 'bytes',
unit: 'By',
}
);
const heapSpacePhysical = meter.createObservableGauge(
`${this.namePrefix}.${V8HeapSpaceMetrics.physical}`,
{
description: metricNames[V8HeapSpaceMetrics.physical].description,
unit: 'bytes',
unit: 'By',
}
);
const heapSpaceNameAttributeName = `${this.namePrefix}.${V8_HEAP_SIZE_STATE_ATTRIBUTE}`;
const heapSpaceNameAttributeName = `${this.namePrefix}.${V8_HEAP_SIZE_NAME_ATTRIBUTE}`;

meter.addBatchObservableCallback(
observableResult => {
Expand All @@ -93,7 +93,7 @@ export class HeapSpacesSizeAndUsedCollector extends BaseCollector<
for (const space of data) {
const spaceName = space.space_name;

observableResult.observe(heapSpaceSize, space.space_size, {
observableResult.observe(heapLimit, space.space_size, {
[heapSpaceNameAttributeName]: spaceName,
});

Expand All @@ -118,7 +118,7 @@ export class HeapSpacesSizeAndUsedCollector extends BaseCollector<
);
}
},
[heapSpaceSize, heapSpaceUsed, heapSpaceAvailable, heapSpacePhysical]
[heapLimit, heapSpaceUsed, heapSpaceAvailable, heapSpacePhysical]
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/
export enum ConventionalNamePrefix {
NodeJsRuntime = 'nodejsruntime',
V8EnjineRuntime = 'v8jsengineruntime',
NodeJs = 'nodejs',
V8js = 'v8js',
}
Loading

0 comments on commit 7418c78

Please sign in to comment.