@platformatic/runtime 3.13.1 → 3.14.0
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 +71 -4
- package/index.d.ts +4 -0
- package/index.js +1 -1
- package/lib/config.js +118 -72
- package/lib/dynamic-workers-scaler.js +218 -0
- package/lib/errors.js +17 -0
- package/lib/logger.js +4 -2
- package/lib/runtime.js +381 -421
- package/lib/scaling-algorithm.js +26 -31
- package/lib/worker/controller.js +14 -4
- package/lib/worker/health-signals.js +80 -0
- package/lib/worker/main.js +6 -0
- package/lib/worker/symbols.js +2 -0
- package/package.json +15 -15
- package/schema.json +180 -22
package/lib/scaling-algorithm.js
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export const scaleUpELUThreshold = 0.8
|
|
2
|
+
export const scaleDownELUThreshold = 0.2
|
|
3
|
+
export const scaleUpTimeWindow = 10_000
|
|
4
|
+
export const scaleDownTimeWindow = 60_000
|
|
5
|
+
|
|
6
|
+
export class ScalingAlgorithm {
|
|
4
7
|
#maxTotalWorkers
|
|
5
|
-
#scaleUpTimeWindowSec
|
|
6
|
-
#scaleDownTimeWindowSec
|
|
7
8
|
#appsMetrics
|
|
8
9
|
#appsConfigs
|
|
9
10
|
|
|
10
11
|
constructor (options = {}) {
|
|
11
|
-
this.#scaleUpELU = options.scaleUpELU ?? 0.8
|
|
12
|
-
this.#scaleDownELU = options.scaleDownELU ?? 0.2
|
|
13
12
|
this.#maxTotalWorkers = options.maxTotalWorkers ?? Infinity
|
|
14
|
-
this.#scaleUpTimeWindowSec = options.scaleUpTimeWindowSec ?? 10
|
|
15
|
-
this.#scaleDownTimeWindowSec = options.scaleDownTimeWindowSec ?? 60
|
|
16
13
|
this.#appsConfigs = options.applications ?? {}
|
|
17
|
-
|
|
18
14
|
this.#appsMetrics = {}
|
|
19
15
|
}
|
|
20
16
|
|
|
17
|
+
addApplication (id, config) {
|
|
18
|
+
this.#appsConfigs[id] = config
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
removeApplication (id) {
|
|
22
|
+
delete this.#appsConfigs[id]
|
|
23
|
+
delete this.#appsMetrics[id]
|
|
24
|
+
}
|
|
25
|
+
|
|
21
26
|
addWorkerHealthInfo (healthInfo) {
|
|
22
27
|
const { workerId, applicationId, elu, heapUsed } = healthInfo
|
|
23
28
|
const timestamp = Date.now()
|
|
@@ -50,7 +55,7 @@ class ScalingAlgorithm {
|
|
|
50
55
|
appsInfo.push({
|
|
51
56
|
applicationId,
|
|
52
57
|
workersCount,
|
|
53
|
-
avgHeapUsed: heapUsed
|
|
58
|
+
avgHeapUsed: heapUsed
|
|
54
59
|
})
|
|
55
60
|
|
|
56
61
|
totalWorkersCount += workersCount
|
|
@@ -112,9 +117,7 @@ class ScalingAlgorithm {
|
|
|
112
117
|
if (workersCount >= appMaxWorkers) continue
|
|
113
118
|
if (avgHeapUsed >= totalAvailableMemory) continue
|
|
114
119
|
|
|
115
|
-
const isScaled = recommendations.some(
|
|
116
|
-
r => r.applicationId === applicationId
|
|
117
|
-
)
|
|
120
|
+
const isScaled = recommendations.some(r => r.applicationId === applicationId)
|
|
118
121
|
if (isScaled) continue
|
|
119
122
|
|
|
120
123
|
const recommendation = this.#getApplicationScaleRecommendation(applicationId)
|
|
@@ -122,10 +125,8 @@ class ScalingAlgorithm {
|
|
|
122
125
|
|
|
123
126
|
if (
|
|
124
127
|
!scaleUpCandidate ||
|
|
125
|
-
|
|
126
|
-
(recommendation.scaleUpELU === scaleUpCandidate.scaleUpELU &&
|
|
127
|
-
workersCount < scaleUpCandidate.workersCount
|
|
128
|
-
)
|
|
128
|
+
recommendation.scaleUpELU > scaleUpCandidate.scaleUpELU ||
|
|
129
|
+
(recommendation.scaleUpELU === scaleUpCandidate.scaleUpELU && workersCount < scaleUpCandidate.workersCount)
|
|
129
130
|
) {
|
|
130
131
|
scaleUpCandidate = {
|
|
131
132
|
applicationId,
|
|
@@ -186,8 +187,8 @@ class ScalingAlgorithm {
|
|
|
186
187
|
count++
|
|
187
188
|
}
|
|
188
189
|
|
|
189
|
-
const elu = Math.round(eluSum / count * 100) / 100
|
|
190
|
-
const heapUsed = Math.round(heapUsedSum / count * 100) / 100
|
|
190
|
+
const elu = Math.round((eluSum / count) * 100) / 100
|
|
191
|
+
const heapUsed = Math.round((heapUsedSum / count) * 100) / 100
|
|
191
192
|
return { elu, heapUsed }
|
|
192
193
|
}
|
|
193
194
|
|
|
@@ -226,28 +227,22 @@ class ScalingAlgorithm {
|
|
|
226
227
|
}
|
|
227
228
|
|
|
228
229
|
#getMetricsTimeWindow () {
|
|
229
|
-
return Math.max(
|
|
230
|
+
return Math.max(scaleUpTimeWindow, scaleDownTimeWindow) * 1000
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
#getApplicationScaleRecommendation (applicationId) {
|
|
233
|
-
const { elu: scaleUpELU } = this.#calculateAppAvgMetrics(applicationId, {
|
|
234
|
-
|
|
235
|
-
})
|
|
236
|
-
const { elu: scaleDownELU } = this.#calculateAppAvgMetrics(applicationId, {
|
|
237
|
-
timeWindow: this.#scaleDownTimeWindowSec * 1000
|
|
238
|
-
})
|
|
234
|
+
const { elu: scaleUpELU } = this.#calculateAppAvgMetrics(applicationId, { timeWindow: scaleUpTimeWindow })
|
|
235
|
+
const { elu: scaleDownELU } = this.#calculateAppAvgMetrics(applicationId, { timeWindow: scaleDownTimeWindow })
|
|
239
236
|
const { heapUsed: avgHeapUsage } = this.#calculateAppAvgMetrics(applicationId)
|
|
240
237
|
|
|
241
238
|
let recommendation = null
|
|
242
|
-
if (scaleUpELU >
|
|
239
|
+
if (scaleUpELU > scaleUpELUThreshold) {
|
|
243
240
|
recommendation = 'scaleUp'
|
|
244
241
|
}
|
|
245
|
-
if (scaleDownELU <
|
|
242
|
+
if (scaleDownELU < scaleDownELUThreshold) {
|
|
246
243
|
recommendation = 'scaleDown'
|
|
247
244
|
}
|
|
248
245
|
|
|
249
246
|
return { recommendation, scaleUpELU, scaleDownELU, avgHeapUsage }
|
|
250
247
|
}
|
|
251
248
|
}
|
|
252
|
-
|
|
253
|
-
export default ScalingAlgorithm
|
package/lib/worker/controller.js
CHANGED
|
@@ -161,7 +161,7 @@ export class Controller extends EventEmitter {
|
|
|
161
161
|
return
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
this
|
|
164
|
+
this.#updateCapabilityStatus('starting')
|
|
165
165
|
this.emit('starting')
|
|
166
166
|
|
|
167
167
|
if (this.#watch) {
|
|
@@ -185,7 +185,7 @@ export class Controller extends EventEmitter {
|
|
|
185
185
|
this.#listening = listen
|
|
186
186
|
/* c8 ignore next 5 */
|
|
187
187
|
} catch (err) {
|
|
188
|
-
this
|
|
188
|
+
this.#updateCapabilityStatus('start:error')
|
|
189
189
|
this.emit('start:error', err)
|
|
190
190
|
|
|
191
191
|
this.capability.log({ message: err.message, level: 'debug' })
|
|
@@ -196,7 +196,7 @@ export class Controller extends EventEmitter {
|
|
|
196
196
|
this.#started = true
|
|
197
197
|
this.#starting = false
|
|
198
198
|
|
|
199
|
-
this
|
|
199
|
+
this.#updateCapabilityStatus('started')
|
|
200
200
|
this.emit('started')
|
|
201
201
|
}
|
|
202
202
|
|
|
@@ -218,7 +218,7 @@ export class Controller extends EventEmitter {
|
|
|
218
218
|
this.#starting = false
|
|
219
219
|
this.#listening = false
|
|
220
220
|
|
|
221
|
-
this
|
|
221
|
+
this.#updateCapabilityStatus('stopped')
|
|
222
222
|
this.emit('stopped')
|
|
223
223
|
}
|
|
224
224
|
|
|
@@ -333,4 +333,14 @@ export class Controller extends EventEmitter {
|
|
|
333
333
|
}
|
|
334
334
|
})
|
|
335
335
|
}
|
|
336
|
+
|
|
337
|
+
#updateCapabilityStatus (status) {
|
|
338
|
+
if (typeof this.capability.updateStatus === 'function') {
|
|
339
|
+
this.capability.updateStatus(status)
|
|
340
|
+
} else {
|
|
341
|
+
// This is horrible but needed for backward compatibility
|
|
342
|
+
this.capability.status = status
|
|
343
|
+
this.capability.emit(status)
|
|
344
|
+
}
|
|
345
|
+
}
|
|
336
346
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HealthSignalMustBeObjectError,
|
|
3
|
+
HealthSignalTypeMustBeStringError
|
|
4
|
+
} from '../errors.js'
|
|
5
|
+
|
|
6
|
+
export class HealthSignalsQueue {
|
|
7
|
+
#size
|
|
8
|
+
#values
|
|
9
|
+
|
|
10
|
+
constructor (options = {}) {
|
|
11
|
+
this.#size = options.size ?? 100
|
|
12
|
+
this.#values = []
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
add (value) {
|
|
16
|
+
if (Array.isArray(value)) {
|
|
17
|
+
for (const v of value) {
|
|
18
|
+
this.#values.push(v)
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
this.#values.push(value)
|
|
22
|
+
}
|
|
23
|
+
if (this.#values.length > this.#size) {
|
|
24
|
+
this.#values.splice(0, this.#values.length - this.#size)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getAll () {
|
|
29
|
+
const values = this.#values
|
|
30
|
+
this.#values = []
|
|
31
|
+
return values
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function initHealthSignalsApi (options = {}) {
|
|
36
|
+
const queue = new HealthSignalsQueue()
|
|
37
|
+
const timeout = options.timeout ?? 1000
|
|
38
|
+
const workerId = options.workerId
|
|
39
|
+
|
|
40
|
+
let isSending = false
|
|
41
|
+
let promise = null
|
|
42
|
+
|
|
43
|
+
async function sendHealthSignal (signal) {
|
|
44
|
+
if (typeof signal !== 'object') {
|
|
45
|
+
throw new HealthSignalMustBeObjectError()
|
|
46
|
+
}
|
|
47
|
+
if (typeof signal.type !== 'string') {
|
|
48
|
+
throw new HealthSignalTypeMustBeStringError(signal.type)
|
|
49
|
+
}
|
|
50
|
+
if (!signal.timestamp || typeof signal.timestamp !== 'number') {
|
|
51
|
+
signal.timestamp = Date.now()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
queue.add(signal)
|
|
55
|
+
|
|
56
|
+
if (!isSending) {
|
|
57
|
+
isSending = true
|
|
58
|
+
promise = new Promise((resolve, reject) => {
|
|
59
|
+
setTimeout(async () => {
|
|
60
|
+
isSending = false
|
|
61
|
+
try {
|
|
62
|
+
const signals = queue.getAll()
|
|
63
|
+
await globalThis.platformatic.itc.send('sendHealthSignals', {
|
|
64
|
+
workerId,
|
|
65
|
+
signals
|
|
66
|
+
})
|
|
67
|
+
} catch (err) {
|
|
68
|
+
reject(err)
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
resolve()
|
|
72
|
+
}, timeout)
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return promise
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
globalThis.platformatic.sendHealthSignal = sendHealthSignal
|
|
80
|
+
}
|
package/lib/worker/main.js
CHANGED
|
@@ -20,6 +20,7 @@ import { setDispatcher } from './interceptors.js'
|
|
|
20
20
|
import { setupITC } from './itc.js'
|
|
21
21
|
import { SharedContext } from './shared-context.js'
|
|
22
22
|
import { kId, kITC, kStderrMarker } from './symbols.js'
|
|
23
|
+
import { initHealthSignalsApi } from './health-signals.js'
|
|
23
24
|
|
|
24
25
|
class ForwardingEventEmitter extends EventEmitter {
|
|
25
26
|
emitAndNotify (event, ...args) {
|
|
@@ -190,6 +191,11 @@ async function main () {
|
|
|
190
191
|
globalThis[kITC] = itc
|
|
191
192
|
globalThis.platformatic.itc = itc
|
|
192
193
|
|
|
194
|
+
initHealthSignalsApi({
|
|
195
|
+
workerId: workerData.worker.id,
|
|
196
|
+
applicationId: applicationConfig.id
|
|
197
|
+
})
|
|
198
|
+
|
|
193
199
|
itc.notify('init')
|
|
194
200
|
}
|
|
195
201
|
|
package/lib/worker/symbols.js
CHANGED
|
@@ -5,7 +5,9 @@ export const kApplicationId = Symbol.for('plt.runtime.application.id')
|
|
|
5
5
|
export const kWorkerId = Symbol.for('plt.runtime.worker.id')
|
|
6
6
|
export const kITC = Symbol.for('plt.runtime.itc')
|
|
7
7
|
export const kHealthCheckTimer = Symbol.for('plt.runtime.worker.healthCheckTimer')
|
|
8
|
+
export const kHealthMetricsTimer = Symbol.for('plt.runtime.worker.healthMetricsTimer')
|
|
8
9
|
export const kWorkerStatus = Symbol('plt.runtime.worker.status')
|
|
10
|
+
export const kWorkerHealthSignals = Symbol.for('plt.runtime.worker.healthSignals')
|
|
9
11
|
export const kWorkerStartTime = Symbol.for('plt.runtime.worker.startTime')
|
|
10
12
|
export const kInterceptors = Symbol.for('plt.runtime.worker.interceptors')
|
|
11
13
|
export const kLastHealthCheckELU = Symbol.for('plt.runtime.worker.lastHealthCheckELU')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/runtime",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.14.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
"typescript": "^5.5.4",
|
|
36
36
|
"undici-oidc-interceptor": "^0.5.0",
|
|
37
37
|
"why-is-node-running": "^2.2.2",
|
|
38
|
-
"@platformatic/
|
|
39
|
-
"@platformatic/
|
|
40
|
-
"@platformatic/
|
|
41
|
-
"@platformatic/node": "3.
|
|
42
|
-
"@platformatic/service": "3.
|
|
43
|
-
"@platformatic/sql-graphql": "3.
|
|
44
|
-
"@platformatic/sql-mapper": "3.
|
|
45
|
-
"@platformatic/wattpm-pprof-capture": "3.
|
|
38
|
+
"@platformatic/db": "3.14.0",
|
|
39
|
+
"@platformatic/gateway": "3.14.0",
|
|
40
|
+
"@platformatic/composer": "3.14.0",
|
|
41
|
+
"@platformatic/node": "3.14.0",
|
|
42
|
+
"@platformatic/service": "3.14.0",
|
|
43
|
+
"@platformatic/sql-graphql": "3.14.0",
|
|
44
|
+
"@platformatic/sql-mapper": "3.14.0",
|
|
45
|
+
"@platformatic/wattpm-pprof-capture": "3.14.0"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@fastify/accepts": "^5.0.0",
|
|
@@ -73,12 +73,12 @@
|
|
|
73
73
|
"undici": "^7.0.0",
|
|
74
74
|
"undici-thread-interceptor": "^0.15.0",
|
|
75
75
|
"ws": "^8.16.0",
|
|
76
|
-
"@platformatic/basic": "3.
|
|
77
|
-
"@platformatic/
|
|
78
|
-
"@platformatic/foundation": "3.
|
|
79
|
-
"@platformatic/
|
|
80
|
-
"@platformatic/
|
|
81
|
-
"@platformatic/
|
|
76
|
+
"@platformatic/basic": "3.14.0",
|
|
77
|
+
"@platformatic/metrics": "3.14.0",
|
|
78
|
+
"@platformatic/foundation": "3.14.0",
|
|
79
|
+
"@platformatic/generators": "3.14.0",
|
|
80
|
+
"@platformatic/telemetry": "3.14.0",
|
|
81
|
+
"@platformatic/itc": "3.14.0"
|
|
82
82
|
},
|
|
83
83
|
"engines": {
|
|
84
84
|
"node": ">=22.19.0"
|
package/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/@platformatic/runtime/3.
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/runtime/3.14.0.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"title": "Platformatic Runtime Config",
|
|
5
5
|
"type": "object",
|
|
@@ -67,11 +67,27 @@
|
|
|
67
67
|
"workers": {
|
|
68
68
|
"anyOf": [
|
|
69
69
|
{
|
|
70
|
-
"type": "number"
|
|
71
|
-
"minimum": 1
|
|
70
|
+
"type": "number"
|
|
72
71
|
},
|
|
73
72
|
{
|
|
74
73
|
"type": "string"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"type": "object",
|
|
77
|
+
"properties": {
|
|
78
|
+
"static": {
|
|
79
|
+
"type": "number",
|
|
80
|
+
"minimum": 1
|
|
81
|
+
},
|
|
82
|
+
"minimum": {
|
|
83
|
+
"type": "number",
|
|
84
|
+
"minimum": 1
|
|
85
|
+
},
|
|
86
|
+
"maximum": {
|
|
87
|
+
"type": "number",
|
|
88
|
+
"minimum": 0
|
|
89
|
+
}
|
|
90
|
+
}
|
|
75
91
|
}
|
|
76
92
|
]
|
|
77
93
|
},
|
|
@@ -329,11 +345,27 @@
|
|
|
329
345
|
"workers": {
|
|
330
346
|
"anyOf": [
|
|
331
347
|
{
|
|
332
|
-
"type": "number"
|
|
333
|
-
"minimum": 1
|
|
348
|
+
"type": "number"
|
|
334
349
|
},
|
|
335
350
|
{
|
|
336
351
|
"type": "string"
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
"type": "object",
|
|
355
|
+
"properties": {
|
|
356
|
+
"static": {
|
|
357
|
+
"type": "number",
|
|
358
|
+
"minimum": 1
|
|
359
|
+
},
|
|
360
|
+
"minimum": {
|
|
361
|
+
"type": "number",
|
|
362
|
+
"minimum": 1
|
|
363
|
+
},
|
|
364
|
+
"maximum": {
|
|
365
|
+
"type": "number",
|
|
366
|
+
"minimum": 0
|
|
367
|
+
}
|
|
368
|
+
}
|
|
337
369
|
}
|
|
338
370
|
]
|
|
339
371
|
},
|
|
@@ -589,11 +621,27 @@
|
|
|
589
621
|
"workers": {
|
|
590
622
|
"anyOf": [
|
|
591
623
|
{
|
|
592
|
-
"type": "number"
|
|
593
|
-
"minimum": 1
|
|
624
|
+
"type": "number"
|
|
594
625
|
},
|
|
595
626
|
{
|
|
596
627
|
"type": "string"
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
"type": "object",
|
|
631
|
+
"properties": {
|
|
632
|
+
"static": {
|
|
633
|
+
"type": "number",
|
|
634
|
+
"minimum": 1
|
|
635
|
+
},
|
|
636
|
+
"minimum": {
|
|
637
|
+
"type": "number",
|
|
638
|
+
"minimum": 1
|
|
639
|
+
},
|
|
640
|
+
"maximum": {
|
|
641
|
+
"type": "number",
|
|
642
|
+
"minimum": 0
|
|
643
|
+
}
|
|
644
|
+
}
|
|
597
645
|
}
|
|
598
646
|
]
|
|
599
647
|
},
|
|
@@ -849,11 +897,27 @@
|
|
|
849
897
|
"workers": {
|
|
850
898
|
"anyOf": [
|
|
851
899
|
{
|
|
852
|
-
"type": "number"
|
|
853
|
-
"minimum": 1
|
|
900
|
+
"type": "number"
|
|
854
901
|
},
|
|
855
902
|
{
|
|
856
903
|
"type": "string"
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
"type": "object",
|
|
907
|
+
"properties": {
|
|
908
|
+
"static": {
|
|
909
|
+
"type": "number",
|
|
910
|
+
"minimum": 1
|
|
911
|
+
},
|
|
912
|
+
"minimum": {
|
|
913
|
+
"type": "number",
|
|
914
|
+
"minimum": 1
|
|
915
|
+
},
|
|
916
|
+
"maximum": {
|
|
917
|
+
"type": "number",
|
|
918
|
+
"minimum": 0
|
|
919
|
+
}
|
|
920
|
+
}
|
|
857
921
|
}
|
|
858
922
|
]
|
|
859
923
|
},
|
|
@@ -1074,6 +1138,43 @@
|
|
|
1074
1138
|
},
|
|
1075
1139
|
{
|
|
1076
1140
|
"type": "string"
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
"type": "object",
|
|
1144
|
+
"properties": {
|
|
1145
|
+
"static": {
|
|
1146
|
+
"type": "number",
|
|
1147
|
+
"minimum": 1
|
|
1148
|
+
},
|
|
1149
|
+
"dynamic": {
|
|
1150
|
+
"type": "boolean",
|
|
1151
|
+
"default": false
|
|
1152
|
+
},
|
|
1153
|
+
"minimum": {
|
|
1154
|
+
"type": "number",
|
|
1155
|
+
"minimum": 1
|
|
1156
|
+
},
|
|
1157
|
+
"maximum": {
|
|
1158
|
+
"type": "number",
|
|
1159
|
+
"minimum": 0
|
|
1160
|
+
},
|
|
1161
|
+
"total": {
|
|
1162
|
+
"type": "number",
|
|
1163
|
+
"minimum": 1
|
|
1164
|
+
},
|
|
1165
|
+
"maxMemory": {
|
|
1166
|
+
"type": "number",
|
|
1167
|
+
"minimum": 0
|
|
1168
|
+
},
|
|
1169
|
+
"cooldown": {
|
|
1170
|
+
"type": "number",
|
|
1171
|
+
"minimum": 0
|
|
1172
|
+
},
|
|
1173
|
+
"gracePeriod": {
|
|
1174
|
+
"type": "number",
|
|
1175
|
+
"minimum": 0
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1077
1178
|
}
|
|
1078
1179
|
]
|
|
1079
1180
|
},
|
|
@@ -1854,6 +1955,58 @@
|
|
|
1854
1955
|
}
|
|
1855
1956
|
],
|
|
1856
1957
|
"default": 10000
|
|
1958
|
+
},
|
|
1959
|
+
"otlpExporter": {
|
|
1960
|
+
"type": "object",
|
|
1961
|
+
"description": "Configuration for exporting metrics to an OTLP endpoint",
|
|
1962
|
+
"properties": {
|
|
1963
|
+
"enabled": {
|
|
1964
|
+
"anyOf": [
|
|
1965
|
+
{
|
|
1966
|
+
"type": "boolean"
|
|
1967
|
+
},
|
|
1968
|
+
{
|
|
1969
|
+
"type": "string"
|
|
1970
|
+
}
|
|
1971
|
+
],
|
|
1972
|
+
"description": "Enable or disable OTLP metrics export"
|
|
1973
|
+
},
|
|
1974
|
+
"endpoint": {
|
|
1975
|
+
"type": "string",
|
|
1976
|
+
"description": "OTLP endpoint URL (e.g., http://collector:4318/v1/metrics)"
|
|
1977
|
+
},
|
|
1978
|
+
"interval": {
|
|
1979
|
+
"anyOf": [
|
|
1980
|
+
{
|
|
1981
|
+
"type": "integer"
|
|
1982
|
+
},
|
|
1983
|
+
{
|
|
1984
|
+
"type": "string"
|
|
1985
|
+
}
|
|
1986
|
+
],
|
|
1987
|
+
"default": 60000,
|
|
1988
|
+
"description": "Interval in milliseconds between metric pushes"
|
|
1989
|
+
},
|
|
1990
|
+
"headers": {
|
|
1991
|
+
"type": "object",
|
|
1992
|
+
"additionalProperties": {
|
|
1993
|
+
"type": "string"
|
|
1994
|
+
},
|
|
1995
|
+
"description": "Additional HTTP headers for authentication"
|
|
1996
|
+
},
|
|
1997
|
+
"serviceName": {
|
|
1998
|
+
"type": "string",
|
|
1999
|
+
"description": "Service name for OTLP resource attributes"
|
|
2000
|
+
},
|
|
2001
|
+
"serviceVersion": {
|
|
2002
|
+
"type": "string",
|
|
2003
|
+
"description": "Service version for OTLP resource attributes"
|
|
2004
|
+
}
|
|
2005
|
+
},
|
|
2006
|
+
"required": [
|
|
2007
|
+
"endpoint"
|
|
2008
|
+
],
|
|
2009
|
+
"additionalProperties": false
|
|
1857
2010
|
}
|
|
1858
2011
|
},
|
|
1859
2012
|
"additionalProperties": false
|
|
@@ -2013,35 +2166,40 @@
|
|
|
2013
2166
|
"type": "number",
|
|
2014
2167
|
"minimum": 1
|
|
2015
2168
|
},
|
|
2169
|
+
"cooldownSec": {
|
|
2170
|
+
"type": "number",
|
|
2171
|
+
"minimum": 0
|
|
2172
|
+
},
|
|
2173
|
+
"gracePeriod": {
|
|
2174
|
+
"type": "number",
|
|
2175
|
+
"minimum": 0
|
|
2176
|
+
},
|
|
2016
2177
|
"scaleUpELU": {
|
|
2017
2178
|
"type": "number",
|
|
2018
2179
|
"minimum": 0,
|
|
2019
|
-
"maximum": 1
|
|
2180
|
+
"maximum": 1,
|
|
2181
|
+
"deprecated": true
|
|
2020
2182
|
},
|
|
2021
2183
|
"scaleDownELU": {
|
|
2022
2184
|
"type": "number",
|
|
2023
2185
|
"minimum": 0,
|
|
2024
|
-
"maximum": 1
|
|
2186
|
+
"maximum": 1,
|
|
2187
|
+
"deprecated": true
|
|
2025
2188
|
},
|
|
2026
2189
|
"timeWindowSec": {
|
|
2027
2190
|
"type": "number",
|
|
2028
|
-
"minimum": 0
|
|
2191
|
+
"minimum": 0,
|
|
2192
|
+
"deprecated": true
|
|
2029
2193
|
},
|
|
2030
2194
|
"scaleDownTimeWindowSec": {
|
|
2031
2195
|
"type": "number",
|
|
2032
|
-
"minimum": 0
|
|
2033
|
-
|
|
2034
|
-
"cooldownSec": {
|
|
2035
|
-
"type": "number",
|
|
2036
|
-
"minimum": 0
|
|
2196
|
+
"minimum": 0,
|
|
2197
|
+
"deprecated": true
|
|
2037
2198
|
},
|
|
2038
2199
|
"scaleIntervalSec": {
|
|
2039
2200
|
"type": "number",
|
|
2040
|
-
"minimum": 0
|
|
2041
|
-
|
|
2042
|
-
"gracePeriod": {
|
|
2043
|
-
"type": "number",
|
|
2044
|
-
"minimum": 0
|
|
2201
|
+
"minimum": 0,
|
|
2202
|
+
"deprecated": true
|
|
2045
2203
|
},
|
|
2046
2204
|
"applications": {
|
|
2047
2205
|
"type": "object",
|