Skip to content

Commit

Permalink
lint(instrumentation-runtime-node): lint
Browse files Browse the repository at this point in the history
  • Loading branch information
pikalovArtemN committed May 17, 2024
1 parent 926f052 commit dbb34ff
Show file tree
Hide file tree
Showing 14 changed files with 292 additions and 175 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
export const NODE_JS_VERSION_ATTRIBUTE = "nodejsruntime.version"
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* 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 = 'heap.size';
23 changes: 17 additions & 6 deletions plugins/node/instrumentation-runtime-node/src/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@ import { EventLoopDelayCollector } from './metrics/eventLoopDelayCollector';
import { GCCollector } from './metrics/gcCollector';
import { HeapSizeAndUsedCollector } from './metrics/heapSizeAndUsedCollector';
import { HeapSpacesSizeAndUsedCollector } from './metrics/heapSpacesSizeAndUsedCollector';
import {ConventionalNamePrefix} from "./types/ConventionalNamePrefix";
import { ConventionalNamePrefix } from './types/ConventionalNamePrefix';

const DEFAULT_CONFIG: RuntimeNodeInstrumentationConfig = {
monitoringPrecision: 5000,
};


export class RuntimeNodeInstrumentation extends InstrumentationBase {
private _collectors: MetricCollector[] = [];

Expand All @@ -40,11 +39,23 @@ export class RuntimeNodeInstrumentation extends InstrumentationBase {
Object.assign({}, DEFAULT_CONFIG, config)
);
this._collectors = [
new EventLoopUtilizationCollector(this._config, ConventionalNamePrefix.NodeJsRuntime),
new EventLoopDelayCollector(this._config, ConventionalNamePrefix.NodeJsRuntime),
new EventLoopUtilizationCollector(
this._config,
ConventionalNamePrefix.NodeJsRuntime
),
new EventLoopDelayCollector(
this._config,
ConventionalNamePrefix.NodeJsRuntime
),
new GCCollector(this._config, ConventionalNamePrefix.V8EnjineRuntime),
new HeapSizeAndUsedCollector(this._config, ConventionalNamePrefix.V8EnjineRuntime),
new HeapSpacesSizeAndUsedCollector(this._config, ConventionalNamePrefix.V8EnjineRuntime),
new HeapSizeAndUsedCollector(
this._config,
ConventionalNamePrefix.V8EnjineRuntime
),
new HeapSpacesSizeAndUsedCollector(
this._config,
ConventionalNamePrefix.V8EnjineRuntime
),
];
if (this._config.enabled) {
for (const collector of this._collectors) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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";
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 }
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 versionAttribute: VersionAttribute;

protected constructor(
config: RuntimeNodeInstrumentationConfig = {},
namePrefix: string
) {
this._config = config;
this.namePrefix = namePrefix;
this.versionAttribute = {[NODE_JS_VERSION_ATTRIBUTE]: process.version}
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 @@ -15,9 +15,9 @@
*/
import {RuntimeNodeInstrumentationConfig} from '../types';
import {Meter} from '@opentelemetry/api';
import * as perf_hooks from 'node:perf_hooks';
import {IntervalHistogram} from 'node:perf_hooks';
import {BaseCollector} from './baseCollector';
import * as perf_hooks from 'node:perf_hooks';

enum NodeJsEventLoopDelay {
delay = 'eventloop.delay',
Expand All @@ -27,48 +27,37 @@ enum NodeJsEventLoopDelay {
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 }> = {
export const metricNames: Record<
NodeJsEventLoopDelay,
{ description: string }
> = {
[NodeJsEventLoopDelay.delay]: {
description:
'Lag of event loop in seconds.'
},
description: 'Lag of event loop in seconds.',
},
[NodeJsEventLoopDelay.min]: {
description:
'The minimum recorded event loop delay.',
},
description: 'The minimum recorded event loop delay.',
},
[NodeJsEventLoopDelay.max]: {
description:
'The maximum recorded event loop delay.',
}
,
description: 'The maximum recorded event loop delay.',
},
[NodeJsEventLoopDelay.mean]: {
description:
'The mean of the recorded event loop delays.',
}
,
description: 'The mean of the recorded event loop delays.',
},
[NodeJsEventLoopDelay.stddev]: {
description:
'The standard deviation of the recorded event loop delays.',
}
,
description: 'The standard deviation of the recorded event loop delays.',
},
[NodeJsEventLoopDelay.p50]: {
description:
'The 50th percentile of the recorded event loop delays.',
}
,
description: 'The 50th percentile of the recorded event loop delays.',
},
[NodeJsEventLoopDelay.p90]: {
description:
'The 90th percentile of the recorded event loop delays.',
}
,
description: 'The 90th percentile of the recorded event loop delays.',
},
[NodeJsEventLoopDelay.p99]: {
description:
'The 99th percentile of the recorded event loop delays.',
}
,
description: 'The 99th percentile of the recorded event loop delays.',
},
};

export interface EventLoopLagInformation {
Expand All @@ -84,7 +73,6 @@ export interface EventLoopLagInformation {
export class EventLoopDelayCollector extends BaseCollector<EventLoopLagInformation> {
private _histogram: IntervalHistogram;


constructor(
config: RuntimeNodeInstrumentationConfig = {},
namePrefix: string
Expand Down Expand Up @@ -160,25 +148,38 @@ export class EventLoopDelayCollector extends BaseCollector<EventLoopLagInformati
const data = this._scrapeQueue.shift();
if (data === undefined) return;

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

this._histogram.reset();
},
[delay, delayMin, delayMax, delayMean, delayStddev, delayp50, delayp90, delayp99]
[
delay,
delayMin,
delayMax,
delayMean,
delayStddev,
delayp50,
delayp90,
delayp99,
]
);
}

Expand All @@ -205,8 +206,7 @@ export class EventLoopDelayCollector extends BaseCollector<EventLoopLagInformati
private _reportEventloopLag(start: [number, number]): number {
const delta = process.hrtime(start);
const nanosec = delta[0] * 1e9 + delta[1];
const seconds = nanosec / 1e9;
return seconds;
return nanosec / 1e9;
}

private checkNan(value: number) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {RuntimeNodeInstrumentationConfig} from '../types';
import {Meter} from '@opentelemetry/api';
import {Histogram, ValueType} from '@opentelemetry/api';
import {BaseCollector} from './baseCollector';
import { RuntimeNodeInstrumentationConfig } from '../types';
import { Meter } from '@opentelemetry/api';
import { Histogram, ValueType } from '@opentelemetry/api';
import { BaseCollector } from './baseCollector';
import * as perf_hooks from 'node:perf_hooks';
import {PerformanceObserver} from 'node:perf_hooks';
import { PerformanceObserver } from 'node:perf_hooks';

const NODEJS_GC_DURATION_SECONDS = 'gc.duration';
const DEFAULT_GC_DURATION_BUCKETS = [0.01, 0.1, 1, 10];
Expand All @@ -43,11 +43,15 @@ export class GCCollector extends BaseCollector<null> {
// Node < 16 uses entry.kind
// Node >= 16 uses entry.detail.kind
// See: https://nodejs.org/docs/latest-v16.x/api/deprecations.html#deprecations_dep0152_extension_performanceentry_properties
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const kind = entry.detail ? kinds[entry.detail.kind] : kinds[entry.kind];
this._gcDurationByKindHistogram?.record(
entry.duration / 1000,
Object.assign({ [`${this.namePrefix}.gc.type`]: kind }, this.versionAttribute)
Object.assign(
{ [`${this.namePrefix}.gc.type`]: kind },
this.versionAttribute
)
);
});
}
Expand All @@ -68,7 +72,7 @@ export class GCCollector extends BaseCollector<null> {
}

internalEnable(): void {
this._observer.observe({entryTypes: ['gc']});
this._observer.observe({ entryTypes: ['gc'] });
}

internalDisable(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
import { RuntimeNodeInstrumentationConfig } from '../types';
import { Meter } from '@opentelemetry/api';
import { BaseCollector } from './baseCollector';
import {HeapSizes} from "../types/heapSizes";
import {V8_HEAP_SIZE, V8_HEAP_SIZE_STATE_ATTRIBUTE} from "../consts/attributes";

import { HeapSizes } from '../types/heapSizes';
import {
V8_HEAP_SIZE,
V8_HEAP_SIZE_STATE_ATTRIBUTE,
} from '../consts/attributes';

export class HeapSizeAndUsedCollector extends BaseCollector<NodeJS.MemoryUsage> {
constructor(
Expand All @@ -29,26 +31,27 @@ export class HeapSizeAndUsedCollector extends BaseCollector<NodeJS.MemoryUsage>
}

updateMetricInstruments(meter: Meter): void {
meter.createObservableGauge(
`${this.namePrefix}.${V8_HEAP_SIZE}`,
{
description: "Process heap size from Node.js in bytes.",
meter
.createObservableGauge(`${this.namePrefix}.${V8_HEAP_SIZE}`, {
description: 'Process heap size from Node.js in bytes.',
unit: 'By',
}
).addCallback(async observableResult => {
if (this._scrapeQueue.length === 0) return;
})
.addCallback(async observableResult => {
if (this._scrapeQueue.length === 0) return;

const data = this._scrapeQueue.shift();
if (data === undefined) return;
observableResult.observe(data.heapTotal, {
[`${this.namePrefix}.${V8_HEAP_SIZE_STATE_ATTRIBUTE}`]: HeapSizes.Total,
...this.versionAttribute
});
observableResult.observe(data.heapUsed, {
[`${this.namePrefix}.${V8_HEAP_SIZE_STATE_ATTRIBUTE}`]: HeapSizes.Used,
...this.versionAttribute
const data = this._scrapeQueue.shift();
if (data === undefined) return;
observableResult.observe(data.heapTotal, {
[`${this.namePrefix}.${V8_HEAP_SIZE_STATE_ATTRIBUTE}`]:
HeapSizes.Total,
...this.versionAttribute,
});
observableResult.observe(data.heapUsed, {
[`${this.namePrefix}.${V8_HEAP_SIZE_STATE_ATTRIBUTE}`]:
HeapSizes.Used,
...this.versionAttribute,
});
});
});
}

internalEnable(): void {}
Expand Down
Loading

0 comments on commit dbb34ff

Please sign in to comment.