@platformatic/runtime 2.5.1 → 2.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.d.ts +1 -1
- package/lib/worker/main.js +3 -1
- package/lib/worker/metrics.js +63 -9
- package/package.json +14 -13
- package/schema.json +1 -1
package/config.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* and run json-schema-to-typescript to regenerate this file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
export type
|
|
8
|
+
export type HttpsSchemasPlatformaticDevPlatformaticRuntime253Json = {
|
|
9
9
|
[k: string]: unknown;
|
|
10
10
|
} & {
|
|
11
11
|
$schema?: string;
|
package/lib/worker/main.js
CHANGED
|
@@ -85,7 +85,9 @@ async function main () {
|
|
|
85
85
|
setGlobalDispatcher(globalDispatcher)
|
|
86
86
|
|
|
87
87
|
// Setup mesh networker
|
|
88
|
-
|
|
88
|
+
// The timeout is set to 5 minutes to avoid long term memory leaks
|
|
89
|
+
// TODO: make this configurable
|
|
90
|
+
const threadDispatcher = wire({ port: parentPort, useNetwork: service.useHttp, timeout: 5 * 60 * 1000 })
|
|
89
91
|
|
|
90
92
|
// If the service is an entrypoint and runtime server config is defined, use it.
|
|
91
93
|
let serverConfig = null
|
package/lib/worker/metrics.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const os = require('node:os')
|
|
4
4
|
const { eventLoopUtilization } = require('node:perf_hooks').performance
|
|
5
|
-
const { Registry, Gauge, collectDefaultMetrics } = require('prom-client')
|
|
5
|
+
const { Registry, Gauge, Counter, collectDefaultMetrics } = require('prom-client')
|
|
6
6
|
const collectHttpMetrics = require('@platformatic/http-metrics')
|
|
7
7
|
|
|
8
8
|
async function collectMetrics (stackable, serviceId, opts = {}) {
|
|
@@ -23,13 +23,14 @@ async function collectMetrics (stackable, serviceId, opts = {}) {
|
|
|
23
23
|
if (metricsConfig.defaultMetrics) {
|
|
24
24
|
collectDefaultMetrics({ register: registry })
|
|
25
25
|
collectEluMetric(registry)
|
|
26
|
+
await collectThreadCpuMetrics(registry)
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
if (metricsConfig.httpMetrics) {
|
|
29
30
|
{
|
|
30
31
|
const { startTimer, endTimer } = collectHttpMetrics(registry, {
|
|
31
32
|
customLabels: ['telemetry_id'],
|
|
32
|
-
getCustomLabels:
|
|
33
|
+
getCustomLabels: req => {
|
|
33
34
|
const telemetryId = req.headers?.['x-plt-telemetry-id'] ?? 'unknown'
|
|
34
35
|
return { telemetry_id: telemetryId }
|
|
35
36
|
}
|
|
@@ -43,7 +44,7 @@ async function collectMetrics (stackable, serviceId, opts = {}) {
|
|
|
43
44
|
// Needed for the Meraki metrics
|
|
44
45
|
const { startTimer, endTimer } = collectHttpMetrics(registry, {
|
|
45
46
|
customLabels: ['telemetry_id'],
|
|
46
|
-
getCustomLabels:
|
|
47
|
+
getCustomLabels: req => {
|
|
47
48
|
const telemetryId = req.headers?.['x-plt-telemetry-id'] ?? 'unknown'
|
|
48
49
|
return { telemetry_id: telemetryId }
|
|
49
50
|
},
|
|
@@ -52,15 +53,15 @@ async function collectMetrics (stackable, serviceId, opts = {}) {
|
|
|
52
53
|
help: 'request duration in seconds summary for all requests',
|
|
53
54
|
collect: function () {
|
|
54
55
|
process.nextTick(() => this.reset())
|
|
55
|
-
}
|
|
56
|
+
}
|
|
56
57
|
},
|
|
57
58
|
summary: {
|
|
58
59
|
name: 'http_request_all_summary_seconds',
|
|
59
60
|
help: 'request duration in seconds histogram for all requests',
|
|
60
61
|
collect: function () {
|
|
61
62
|
process.nextTick(() => this.reset())
|
|
62
|
-
}
|
|
63
|
-
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
64
65
|
})
|
|
65
66
|
httpRequestCallbacks.push(startTimer)
|
|
66
67
|
httpResponseCallbacks.push(endTimer)
|
|
@@ -70,6 +71,59 @@ async function collectMetrics (stackable, serviceId, opts = {}) {
|
|
|
70
71
|
return registry
|
|
71
72
|
}
|
|
72
73
|
|
|
74
|
+
async function collectThreadCpuMetrics (registry) {
|
|
75
|
+
// We need until we switch to 22 as thread-cpu-usage is ESM
|
|
76
|
+
const { threadCpuUsage } = await import('thread-cpu-usage')
|
|
77
|
+
|
|
78
|
+
let lastSample = process.hrtime.bigint()
|
|
79
|
+
let lastUsage = threadCpuUsage()
|
|
80
|
+
|
|
81
|
+
const threadCpuUserUsageCounterMetric = new Counter({
|
|
82
|
+
name: 'thread_cpu_user_system_seconds_total',
|
|
83
|
+
help: 'Total user CPU time spent in seconds for the current thread.',
|
|
84
|
+
registers: [registry]
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const threadCpuSystemUsageCounterMetric = new Counter({
|
|
88
|
+
name: 'thread_cpu_system_seconds_total',
|
|
89
|
+
help: 'Total system CPU time spent in seconds for the current thread.',
|
|
90
|
+
registers: [registry]
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const threadCpuPercentUsageGaugeMetric = new Gauge({
|
|
94
|
+
name: 'thread_cpu_percent_usage',
|
|
95
|
+
help: 'The thread CPU percent usage.',
|
|
96
|
+
registers: [registry]
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
const threadCpuUsageCounterMetric = new Counter({
|
|
100
|
+
name: 'thread_cpu_seconds_total',
|
|
101
|
+
help: 'Total user and system CPU time spent in seconds for the current threads.',
|
|
102
|
+
// Use this one metric's `collect` to set all metrics' values.
|
|
103
|
+
collect () {
|
|
104
|
+
const newSample = process.hrtime.bigint()
|
|
105
|
+
const newUsage = threadCpuUsage()
|
|
106
|
+
const user = newUsage.user - lastUsage.user
|
|
107
|
+
const system = newUsage.system - lastUsage.system
|
|
108
|
+
const elapsed = Number(newSample - lastSample)
|
|
109
|
+
|
|
110
|
+
lastUsage = newUsage
|
|
111
|
+
lastSample = newSample
|
|
112
|
+
|
|
113
|
+
threadCpuSystemUsageCounterMetric.inc(system / 1e6)
|
|
114
|
+
threadCpuUserUsageCounterMetric.inc(user / 1e6)
|
|
115
|
+
threadCpuUsageCounterMetric.inc((user + system) / 1e6)
|
|
116
|
+
threadCpuPercentUsageGaugeMetric.set((100 * ((user + system) * 1000)) / elapsed)
|
|
117
|
+
},
|
|
118
|
+
registers: [registry]
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
registry.registerMetric(threadCpuUserUsageCounterMetric)
|
|
122
|
+
registry.registerMetric(threadCpuSystemUsageCounterMetric)
|
|
123
|
+
registry.registerMetric(threadCpuUsageCounterMetric)
|
|
124
|
+
registry.registerMetric(threadCpuPercentUsageGaugeMetric)
|
|
125
|
+
}
|
|
126
|
+
|
|
73
127
|
function collectEluMetric (register) {
|
|
74
128
|
let startELU = eventLoopUtilization()
|
|
75
129
|
const eluMetric = new Gauge({
|
|
@@ -81,7 +135,7 @@ function collectEluMetric (register) {
|
|
|
81
135
|
eluMetric.set(result)
|
|
82
136
|
startELU = endELU
|
|
83
137
|
},
|
|
84
|
-
registers: [register]
|
|
138
|
+
registers: [register]
|
|
85
139
|
})
|
|
86
140
|
register.registerMetric(eluMetric)
|
|
87
141
|
|
|
@@ -107,14 +161,14 @@ function collectEluMetric (register) {
|
|
|
107
161
|
const idleDiff = idleTime - previousIdleTime
|
|
108
162
|
const totalDiff = totalTime - previousTotalTime
|
|
109
163
|
|
|
110
|
-
const usagePercent = 100 - (
|
|
164
|
+
const usagePercent = 100 - (100 * idleDiff) / totalDiff
|
|
111
165
|
const roundedUsage = Math.round(usagePercent * 100) / 100
|
|
112
166
|
cpuMetric.set(roundedUsage)
|
|
113
167
|
|
|
114
168
|
previousIdleTime = idleTime
|
|
115
169
|
previousTotalTime = totalTime
|
|
116
170
|
},
|
|
117
|
-
registers: [register]
|
|
171
|
+
registers: [register]
|
|
118
172
|
})
|
|
119
173
|
register.registerMetric(cpuMetric)
|
|
120
174
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/runtime",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"typescript": "^5.5.4",
|
|
35
35
|
"undici-oidc-interceptor": "^0.5.0",
|
|
36
36
|
"why-is-node-running": "^2.2.2",
|
|
37
|
-
"@platformatic/composer": "2.5.
|
|
38
|
-
"@platformatic/db": "2.5.
|
|
39
|
-
"@platformatic/service": "2.5.
|
|
40
|
-
"@platformatic/sql-graphql": "2.5.
|
|
41
|
-
"@platformatic/sql-mapper": "2.5.
|
|
37
|
+
"@platformatic/composer": "2.5.3",
|
|
38
|
+
"@platformatic/db": "2.5.3",
|
|
39
|
+
"@platformatic/service": "2.5.3",
|
|
40
|
+
"@platformatic/sql-graphql": "2.5.3",
|
|
41
|
+
"@platformatic/sql-mapper": "2.5.3"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@fastify/error": "^4.0.0",
|
|
@@ -65,16 +65,17 @@
|
|
|
65
65
|
"prom-client": "^15.1.2",
|
|
66
66
|
"semgrator": "^0.3.0",
|
|
67
67
|
"tail-file-stream": "^0.2.0",
|
|
68
|
+
"thread-cpu-usage": "^0.2.0",
|
|
68
69
|
"undici": "^6.9.0",
|
|
69
70
|
"undici-thread-interceptor": "^0.7.0",
|
|
70
71
|
"ws": "^8.16.0",
|
|
71
|
-
"@platformatic/basic": "2.5.
|
|
72
|
-
"@platformatic/config": "2.5.
|
|
73
|
-
"@platformatic/generators": "2.5.
|
|
74
|
-
"@platformatic/itc": "2.5.
|
|
75
|
-
"@platformatic/
|
|
76
|
-
"@platformatic/
|
|
77
|
-
"@platformatic/utils": "2.5.
|
|
72
|
+
"@platformatic/basic": "2.5.3",
|
|
73
|
+
"@platformatic/config": "2.5.3",
|
|
74
|
+
"@platformatic/generators": "2.5.3",
|
|
75
|
+
"@platformatic/itc": "2.5.3",
|
|
76
|
+
"@platformatic/telemetry": "2.5.3",
|
|
77
|
+
"@platformatic/ts-compiler": "2.5.3",
|
|
78
|
+
"@platformatic/utils": "2.5.3"
|
|
78
79
|
},
|
|
79
80
|
"scripts": {
|
|
80
81
|
"test": "npm run lint && borp --concurrency=1 --timeout=180000 && tsd",
|
package/schema.json
CHANGED