@platformatic/watt-extra 1.11.0-alpha.0 → 1.11.0-alpha.2
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/package.json +1 -1
- package/plugins/env.js +2 -2
- package/plugins/health-signals.js +1 -36
package/package.json
CHANGED
package/plugins/env.js
CHANGED
|
@@ -28,8 +28,8 @@ const schema = {
|
|
|
28
28
|
PLT_ELU_HEALTH_SIGNAL_THRESHOLD: { type: 'number', default: 0.8 },
|
|
29
29
|
PLT_HEAP_HEALTH_SIGNAL_THRESHOLD: { type: ['number', 'string'], default: '200MB' },
|
|
30
30
|
PLT_ALERTS_GRACE_PERIOD_SEC: { type: 'number', default: 30 },
|
|
31
|
-
PLT_HEALTH_SIGNALS_SHORT_BATCH_TIMEOUT: { type: 'number', default:
|
|
32
|
-
PLT_HEALTH_SIGNALS_LONG_BATCH_TIMEOUT: { type: 'number', default:
|
|
31
|
+
PLT_HEALTH_SIGNALS_SHORT_BATCH_TIMEOUT: { type: 'number', default: 2000 },
|
|
32
|
+
PLT_HEALTH_SIGNALS_LONG_BATCH_TIMEOUT: { type: 'number', default: 2000 }
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -36,7 +36,6 @@ async function healthSignals (app, _opts) {
|
|
|
36
36
|
app.getRuntimeId = () => {
|
|
37
37
|
if (!app.runtimeId) {
|
|
38
38
|
app.runtimeId = randomUUID()
|
|
39
|
-
process._rawDebug(`[health-signals] Generated new runtimeId: ${app.runtimeId}`)
|
|
40
39
|
}
|
|
41
40
|
return app.runtimeId
|
|
42
41
|
}
|
|
@@ -98,8 +97,6 @@ async function healthSignals (app, _opts) {
|
|
|
98
97
|
}
|
|
99
98
|
heapThresholdMb = Math.round(heapThreshold / 1024 / 1024)
|
|
100
99
|
|
|
101
|
-
process._rawDebug(`[health-signals] Config: eluThreshold=${eluThreshold}, heapThresholdMb=${heapThresholdMb}, batchShortTimeout=${batchShortTimeout}ms, batchLongTimeout=${batchLongTimeout}ms`)
|
|
102
|
-
|
|
103
100
|
let batchHasHighValue = false
|
|
104
101
|
let batchStartedAt = null
|
|
105
102
|
setInterval(() => {
|
|
@@ -108,13 +105,7 @@ async function healthSignals (app, _opts) {
|
|
|
108
105
|
? batchShortTimeout
|
|
109
106
|
: batchLongTimeout
|
|
110
107
|
|
|
111
|
-
if (batchStartedAt !== null) {
|
|
112
|
-
const elapsed = now - batchStartedAt
|
|
113
|
-
process._rawDebug(`[health-signals] Batch check: elapsed=${elapsed}ms, timeout=${batchTimeout}ms, hasHighValue=${batchHasHighValue}`)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
108
|
if (now - batchStartedAt >= batchTimeout) {
|
|
117
|
-
process._rawDebug(`[health-signals] Batch timeout reached, sending signals. hasHighValue=${batchHasHighValue}`)
|
|
118
109
|
batchHasHighValue = false
|
|
119
110
|
batchStartedAt = null
|
|
120
111
|
|
|
@@ -122,9 +113,6 @@ async function healthSignals (app, _opts) {
|
|
|
122
113
|
const metrics = servicesMetrics
|
|
123
114
|
servicesMetrics = {}
|
|
124
115
|
|
|
125
|
-
const serviceIds = Object.keys(signals)
|
|
126
|
-
process._rawDebug(`[health-signals] Sending signals for services: ${serviceIds.join(', ') || '(none)'}`)
|
|
127
|
-
|
|
128
116
|
sendHealthSignals(signals, metrics).catch(err => {
|
|
129
117
|
app.log.error({ err }, 'Failed to send health signals to scaler')
|
|
130
118
|
})
|
|
@@ -152,10 +140,6 @@ async function healthSignals (app, _opts) {
|
|
|
152
140
|
const heapUsedMb = Math.round(heapUsed / 1024 / 1024)
|
|
153
141
|
const now = Date.now()
|
|
154
142
|
|
|
155
|
-
const eluExceedsThreshold = elu > eluThreshold
|
|
156
|
-
const heapExceedsThreshold = heapUsedMb > heapThresholdMb
|
|
157
|
-
process._rawDebug(`[health-signals] Received metrics: service=${serviceId}, worker=${workerId}, elu=${(elu * 100).toFixed(2)}% (threshold=${(eluThreshold * 100).toFixed(2)}%, exceeds=${eluExceedsThreshold}), heap=${heapUsedMb}MB (threshold=${heapThresholdMb}MB, exceeds=${heapExceedsThreshold}), customSignals=${healthSignals.length}`)
|
|
158
|
-
|
|
159
143
|
signalsCache.addServiceSignal(serviceId, 'elu', {
|
|
160
144
|
workerId,
|
|
161
145
|
value: elu,
|
|
@@ -170,10 +154,7 @@ async function healthSignals (app, _opts) {
|
|
|
170
154
|
signalsCache.addServiceSignals(serviceId, healthSignals)
|
|
171
155
|
|
|
172
156
|
batchStartedAt ??= now
|
|
173
|
-
if (
|
|
174
|
-
if (!batchHasHighValue) {
|
|
175
|
-
process._rawDebug(`[health-signals] High value detected! Switching to short batch timeout`)
|
|
176
|
-
}
|
|
157
|
+
if (elu > eluThreshold || heapUsedMb > heapThresholdMb) {
|
|
177
158
|
batchHasHighValue = true
|
|
178
159
|
}
|
|
179
160
|
|
|
@@ -214,16 +195,9 @@ async function healthSignals (app, _opts) {
|
|
|
214
195
|
}
|
|
215
196
|
}
|
|
216
197
|
}
|
|
217
|
-
process._rawDebug(`[health-signals] Prepared signals for ${serviceId}: eluValues=${signals[serviceId].elu.values.length}, heapValues=${signals[serviceId].heap.values.length}, heapTotal=${signals[serviceId].heap.options.heapTotal}`)
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (Object.keys(signals).length === 0) {
|
|
221
|
-
process._rawDebug(`[health-signals] No signals to send, skipping request`)
|
|
222
|
-
return
|
|
223
198
|
}
|
|
224
199
|
|
|
225
200
|
const runtimeId = app.getRuntimeId()
|
|
226
|
-
process._rawDebug(`[health-signals] Sending to ${scalerUrl}/signals: applicationId=${applicationId}, runtimeId=${runtimeId}`)
|
|
227
201
|
|
|
228
202
|
const { statusCode, body } = await request(`${scalerUrl}/signals`, {
|
|
229
203
|
method: 'POST',
|
|
@@ -234,23 +208,17 @@ async function healthSignals (app, _opts) {
|
|
|
234
208
|
body: JSON.stringify({ applicationId, runtimeId, signals })
|
|
235
209
|
})
|
|
236
210
|
|
|
237
|
-
process._rawDebug(`[health-signals] Scaler response: statusCode=${statusCode}`)
|
|
238
|
-
|
|
239
211
|
if (statusCode !== 200) {
|
|
240
212
|
const error = await body.text()
|
|
241
|
-
process._rawDebug(`[health-signals] Scaler error response: ${error}`)
|
|
242
213
|
app.log.error({ error }, 'Failed to send health signals to scaler')
|
|
243
214
|
return
|
|
244
215
|
}
|
|
245
216
|
|
|
246
217
|
const { alerts = [] } = await body.json()
|
|
247
|
-
process._rawDebug(`[health-signals] Received ${alerts.length} alerts from scaler`)
|
|
248
|
-
|
|
249
218
|
const promises = []
|
|
250
219
|
|
|
251
220
|
for (const alert of alerts) {
|
|
252
221
|
const { serviceId, workerId, alertId } = alert
|
|
253
|
-
process._rawDebug(`[health-signals] Processing alert: alertId=${alertId}, serviceId=${serviceId}, workerId=${workerId}`)
|
|
254
222
|
const promise = app.sendFlamegraphs({
|
|
255
223
|
serviceIds: [serviceId],
|
|
256
224
|
workerIds: [workerId],
|
|
@@ -262,10 +230,7 @@ async function healthSignals (app, _opts) {
|
|
|
262
230
|
|
|
263
231
|
for (const result of results) {
|
|
264
232
|
if (result.status === 'rejected') {
|
|
265
|
-
process._rawDebug(`[health-signals] Flamegraph send failed: ${result.reason}`)
|
|
266
233
|
app.log.error({ err: result.reason }, 'Failed to send a flamegraph')
|
|
267
|
-
} else {
|
|
268
|
-
process._rawDebug(`[health-signals] Flamegraph sent successfully`)
|
|
269
234
|
}
|
|
270
235
|
}
|
|
271
236
|
}
|