Skip to content

Commit 55983c8

Browse files
committed
added metrics scrap in interval
1 parent 426b2fc commit 55983c8

11 files changed

Lines changed: 213 additions & 149 deletions

File tree

lib/core/http.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import * as http from "http";
22
import { EventResponse, Incident } from "../transport/events";
3-
import { TraceoIncomingMessage, RequestOptions, HTTP_ENDPOINT, RequestStatus } from "../transport/http";
3+
import {
4+
TraceoIncomingMessage,
5+
RequestOptions,
6+
HTTP_ENDPOINT,
7+
} from "../transport/http";
48
import { TraceoLog } from "../transport/logger";
9+
import { Metrics } from "../transport/metrics";
510
import { RequestType } from "../transport/types";
611
import { getGlobalClientData } from "./global";
712
import { TRACEO_SDK_VERSION } from "./version";
@@ -12,8 +17,7 @@ const createHttpOptions = (
1217
): http.RequestOptions => {
1318
const client = getGlobalClientData();
1419

15-
const { host, port } = client;
16-
20+
const { host, port } = client.connection;
1721
const baseOptions: RequestOptions = {
1822
hostname: host,
1923
port,
@@ -39,6 +43,11 @@ const sendRuntimeMetrics = async (data: {}) => {
3943
await sendEvent(data, httpOptions);
4044
};
4145

46+
const sendMetrics = async (data: Metrics) => {
47+
const httpOptions = createHttpOptions(HTTP_ENDPOINT.METRICS);
48+
await sendEvent(data, httpOptions);
49+
};
50+
4251
const sendIncident = async (incident: Incident) => {
4352
const version = TRACEO_SDK_VERSION;
4453
const baseData = { version };
@@ -53,24 +62,24 @@ const sendEvent = async (
5362
payload: any,
5463
httpOptions: http.RequestOptions
5564
): Promise<EventResponse | void> => {
56-
const { host, appId } = getGlobalClientData();
65+
const { connection, appId } = getGlobalClientData();
5766

58-
if (!host || !appId) {
67+
if (!connection || !appId) {
5968
return;
6069
}
6170

6271
return new Promise<EventResponse>((_, reject) => {
63-
const options = {
72+
const options: http.RequestOptions = {
6473
...httpOptions,
65-
path: httpOptions.path + `/${appId}`
66-
}
74+
path: `${httpOptions.path}/${appId}`,
75+
};
6776

6877
const request = http.request(options, (res: TraceoIncomingMessage) => {
6978
res.setEncoding("utf8");
7079
res.on("error", reject);
7180
});
7281

73-
request.on("error", reject);
82+
request.on("error", () => { });
7483

7584
request.on("timeout", () => {
7685
request.destroy();
@@ -87,5 +96,8 @@ const sendEvent = async (
8796
};
8897

8998
export const httpService = {
90-
sendLog, sendIncident, sendRuntimeMetrics
91-
}
99+
sendLog,
100+
sendIncident,
101+
sendRuntimeMetrics,
102+
sendMetrics,
103+
};

lib/node/metrics.ts

Lines changed: 17 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,28 @@
1-
import * as os from "os";
2-
import * as v8 from "v8";
31
import { httpService } from "../core/http";
2+
import { Metrics } from "../transport/metrics";
3+
import { TraceoOptions } from "../transport/options";
4+
import { cpu } from "./metrics/cpu-usage";
5+
import { loadRuntimeMetrics } from "./metrics/runtime-data";
46

5-
const sanitizePackageName = (pkg: string, pkgType: string) => {
6-
let targetKey = pkg.replace(pkgType, "").replace("__", "@");
7-
if (targetKey.includes("@")) {
8-
const [lib, pkg] = targetKey.split("_");
9-
targetKey = `${lib}/${pkg}`;
10-
}
7+
const DEFAULT_INTERVAL = 30; //seconds
118

12-
targetKey = targetKey.replace("_", "").replace("_", "-");
9+
const collectMetrics = (options: TraceoOptions) => {
10+
const { metrics } = options;
1311

14-
return targetKey;
15-
};
16-
17-
const collectMetricsDataOnRuntime = () => {
18-
const traceoVersion =
19-
process.env["npm_package_dependencies_traceo"] ||
20-
process.env["npm_package_devDependencies_traceo"];
21-
22-
const packageEngineNode = process.env["npm_package_engines_node"];
23-
const packageName = process.env["npm_package_name"];
24-
const packageDescription = process.env["npm_package_description"];
25-
const packageVersion = process.env["npm_package_version"];
26-
27-
const dependencies = {};
28-
const devDependencies = {};
29-
const scripts = {};
30-
31-
for (const [key, value] of Object.entries(process.env)) {
32-
if (key?.startsWith("npm_package_dependencies_")) {
33-
const targetKey = sanitizePackageName(key, "npm_package_dependencies");
34-
dependencies[targetKey] = value;
35-
}
36-
37-
if (key?.startsWith("npm_package_devDependencies_")) {
38-
const targetKey = sanitizePackageName(key, "npm_package_devDependencies");
39-
devDependencies[targetKey] = value;
40-
}
41-
42-
if (key?.startsWith("npm_package_scripts_")) {
43-
const targetKey = key.replace("npm_package_scripts_", "");
44-
scripts[targetKey] = value;
45-
}
46-
}
47-
48-
const osDataToScrap = [
49-
"arch",
50-
"platform",
51-
"release",
52-
"version",
53-
"homedir",
54-
"tmpdir",
55-
"type",
56-
"hostname",
57-
];
58-
const osData = {};
59-
for (const [key, _] of Object.entries(os)) {
60-
if (osDataToScrap.includes(key)) {
61-
osData[key] = os[key]();
62-
}
63-
}
64-
65-
const heap = {};
66-
for (const [key, value] of Object.entries(v8.getHeapCodeStatistics())) {
67-
heap[key] = value;
68-
}
69-
70-
const heapStats = v8.getHeapStatistics();
71-
const heapStatistics = {
72-
heap_size_limit: heapStats.heap_size_limit,
73-
total_heap_size_executable: heapStats.total_heap_size_executable,
74-
total_physical_size: heapStats.total_physical_size,
75-
};
12+
loadRuntimeMetrics();
7613

77-
const nodeVersion = process.versions;
14+
const INTERVAL =
15+
(metrics?.interval < 15 ? DEFAULT_INTERVAL : metrics?.interval) * 1000;
7816

79-
const data = {
80-
node: {
81-
...heap,
82-
...heapStatistics,
83-
...nodeVersion,
84-
},
85-
os: osData,
86-
scripts,
87-
dependencies,
88-
devDependencies,
89-
npm: {
90-
packageEngineNode,
91-
packageName,
92-
packageDescription,
93-
packageVersion,
94-
},
95-
traceo: {
96-
version: traceoVersion,
97-
},
98-
};
17+
setInterval(() => {
18+
const metrics: Metrics = {
19+
cpuUsage: cpu.usage(),
20+
};
9921

100-
httpService.sendRuntimeMetrics(data);
22+
httpService.sendMetrics(metrics);
23+
}, INTERVAL);
10124
};
10225

10326
export const metrics = {
104-
collectMetricsDataOnRuntime,
27+
collectMetrics,
10528
};

lib/node/metrics/cpu-usage.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as os from "node:os";
2+
3+
const averageCpu = (): { idle: number; total: number } => {
4+
let totalIdle = 0;
5+
let totalTick = 0;
6+
const cpus = os.cpus();
7+
8+
for (let i = 0, len = cpus.length; i < len; i++) {
9+
const cpu = cpus[i];
10+
for (const type in cpu.times) {
11+
totalTick += cpu.times[type];
12+
}
13+
14+
totalIdle += cpu.times.idle;
15+
}
16+
17+
return { idle: totalIdle / cpus.length, total: totalTick / cpus.length };
18+
};
19+
20+
const startMeasure = averageCpu();
21+
22+
const getCpuUsage = () => {
23+
const endMeasure = averageCpu();
24+
25+
const idleDifference = endMeasure.idle - startMeasure.idle;
26+
const totalDifference = endMeasure.total - startMeasure.total;
27+
28+
const cpuUsage =
29+
Math.round((100 - (100 * idleDifference) / totalDifference) * 100) / 100;
30+
31+
return cpuUsage;
32+
};
33+
34+
export const cpu = {
35+
usage: getCpuUsage
36+
}

lib/node/metrics/runtime-data.ts

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { httpService } from "../../core/http";
2+
import * as os from "node:os";
3+
import * as v8 from "node:v8";
4+
5+
const normalizePackageName = (pkg: string, pkgType: string) => {
6+
let targetKey = pkg.replace(pkgType, "").replace("__", "@");
7+
if (targetKey.includes("@")) {
8+
const [lib, pkg] = targetKey.split("_");
9+
targetKey = `${lib}/${pkg}`;
10+
}
11+
12+
targetKey = targetKey.replace("_", "").replace("_", "-");
13+
14+
return targetKey;
15+
};
16+
17+
export const loadRuntimeMetrics = () => {
18+
const traceoVersion =
19+
process.env["npm_package_dependencies_traceo"] ||
20+
process.env["npm_package_devDependencies_traceo"];
21+
22+
const packageEngineNode = process.env["npm_package_engines_node"];
23+
const packageName = process.env["npm_package_name"];
24+
const packageDescription = process.env["npm_package_description"];
25+
const packageVersion = process.env["npm_package_version"];
26+
27+
const dependencies = {};
28+
const devDependencies = {};
29+
const scripts = {};
30+
31+
for (const [key, value] of Object.entries(process.env)) {
32+
if (key?.startsWith("npm_package_dependencies_")) {
33+
const targetKey = normalizePackageName(key, "npm_package_dependencies");
34+
dependencies[targetKey] = value;
35+
}
36+
37+
if (key?.startsWith("npm_package_devDependencies_")) {
38+
const targetKey = normalizePackageName(key, "npm_package_devDependencies");
39+
devDependencies[targetKey] = value;
40+
}
41+
42+
if (key?.startsWith("npm_package_scripts_")) {
43+
const targetKey = key.replace("npm_package_scripts_", "");
44+
scripts[targetKey] = value;
45+
}
46+
}
47+
48+
const osDataToScrap = [
49+
"arch",
50+
"platform",
51+
"release",
52+
"version",
53+
"homedir",
54+
"tmpdir",
55+
"type",
56+
"hostname",
57+
];
58+
const osData = {};
59+
for (const [key, _] of Object.entries(os)) {
60+
if (osDataToScrap.includes(key)) {
61+
osData[key] = os[key]();
62+
}
63+
}
64+
65+
const heap = {};
66+
for (const [key, value] of Object.entries(v8.getHeapCodeStatistics())) {
67+
heap[key] = value;
68+
}
69+
70+
const heapStats = v8.getHeapStatistics();
71+
const heapStatistics = {
72+
heap_size_limit: heapStats.heap_size_limit,
73+
total_heap_size_executable: heapStats.total_heap_size_executable,
74+
total_physical_size: heapStats.total_physical_size,
75+
};
76+
77+
const nodeVersion = process.versions;
78+
79+
const data = {
80+
node: {
81+
...heap,
82+
...heapStatistics,
83+
...nodeVersion,
84+
},
85+
os: osData,
86+
scripts,
87+
dependencies,
88+
devDependencies,
89+
npm: {
90+
packageEngineNode,
91+
packageName,
92+
packageDescription,
93+
packageVersion,
94+
},
95+
traceo: {
96+
version: traceoVersion,
97+
},
98+
};
99+
100+
httpService.sendRuntimeMetrics(data);
101+
};

lib/node/process.ts

Lines changed: 0 additions & 31 deletions
This file was deleted.

lib/node/sdk.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ export const init = (options: TraceoOptions): void => {
2222
});
2323
}
2424

25-
if (options?.collectMetrics) {
26-
metrics.collectMetricsDataOnRuntime();
25+
if (options.metrics.collect) {
26+
metrics.collectMetrics(options);
2727
}
2828
};
2929

0 commit comments

Comments
 (0)