@platformatic/runtime 3.53.0-alpha.0 → 3.54.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 +4 -0
- package/lib/runtime.js +72 -0
- package/lib/worker/itc.js +4 -2
- package/lib/worker/main.js +1 -1
- package/lib/worker/messaging.js +97 -46
- package/package.json +16 -16
- package/schema.json +12 -1
package/config.d.ts
CHANGED
|
@@ -493,6 +493,10 @@ export type PlatformaticRuntimeConfig = {
|
|
|
493
493
|
additionalProperties?: never;
|
|
494
494
|
[k: string]: unknown;
|
|
495
495
|
};
|
|
496
|
+
/**
|
|
497
|
+
* Enable the OpenTelemetry diagnostic logger. Diagnostic messages are forwarded to the Platformatic global logger using the current logger level.
|
|
498
|
+
*/
|
|
499
|
+
diagLogger?: boolean | string;
|
|
496
500
|
};
|
|
497
501
|
verticalScaler?: {
|
|
498
502
|
enabled?: boolean;
|
package/lib/runtime.js
CHANGED
|
@@ -77,6 +77,8 @@ const kInspectorOptions = Symbol('plt.runtime.worker.inspectorOptions')
|
|
|
77
77
|
const kHeapCheckCounter = Symbol('plt.runtime.worker.heapCheckCounter')
|
|
78
78
|
const kLastHeapStats = Symbol('plt.runtime.worker.lastHeapStats')
|
|
79
79
|
const kHealthITCTimeoutMs = 5000
|
|
80
|
+
const kApplicationRestartsMetricName = 'platformatic_application_restarts_total'
|
|
81
|
+
const kApplicationRestartsMetricHelp = 'Total number of restarts triggered by the runtime for an application.'
|
|
80
82
|
|
|
81
83
|
const MAX_LISTENERS_COUNT = 100
|
|
82
84
|
|
|
@@ -133,6 +135,7 @@ export class Runtime extends EventEmitter {
|
|
|
133
135
|
|
|
134
136
|
#applicationsConfigsPatches
|
|
135
137
|
#applications
|
|
138
|
+
#applicationRestartCounts
|
|
136
139
|
#workers
|
|
137
140
|
#workersBroadcastChannel
|
|
138
141
|
#workerITCHandlers
|
|
@@ -158,6 +161,7 @@ export class Runtime extends EventEmitter {
|
|
|
158
161
|
this.#isProduction = this.#context.isProduction ?? this.#context.production ?? false
|
|
159
162
|
this.#concurrency = Math.max(1, config.startupConcurrency ?? this.#context.concurrency ?? DEFAULT_CONCURRENCY)
|
|
160
163
|
this.#applications = new Map()
|
|
164
|
+
this.#applicationRestartCounts = new Map()
|
|
161
165
|
this.#workers = new RoundRobinMap()
|
|
162
166
|
this.#url = undefined
|
|
163
167
|
this.#entrypointPort = undefined
|
|
@@ -501,6 +505,7 @@ export class Runtime extends EventEmitter {
|
|
|
501
505
|
}
|
|
502
506
|
|
|
503
507
|
this.#applications.set(application.id, application)
|
|
508
|
+
this.#applicationRestartCounts.set(application.id, this.#applicationRestartCounts.get(application.id) ?? 0)
|
|
504
509
|
setupInvocations.push([application])
|
|
505
510
|
toStart.push(application.id)
|
|
506
511
|
}
|
|
@@ -542,6 +547,7 @@ export class Runtime extends EventEmitter {
|
|
|
542
547
|
for (const application of applications) {
|
|
543
548
|
this.#dynamicWorkersScaler?.remove(application)
|
|
544
549
|
this.#applications.delete(application)
|
|
550
|
+
this.#applicationRestartCounts.delete(application)
|
|
545
551
|
}
|
|
546
552
|
|
|
547
553
|
for (const application of applications) {
|
|
@@ -712,6 +718,7 @@ export class Runtime extends EventEmitter {
|
|
|
712
718
|
await this.#replaceWorker(config, applicationConfig, workersCount, id, i, worker, true)
|
|
713
719
|
}
|
|
714
720
|
|
|
721
|
+
this.#incrementApplicationRestartCount(id)
|
|
715
722
|
this.emitAndNotify('application:restarted', id)
|
|
716
723
|
} finally {
|
|
717
724
|
this.#restartingApplications.delete(id)
|
|
@@ -1151,6 +1158,10 @@ export class Runtime extends EventEmitter {
|
|
|
1151
1158
|
async getMetrics (format = 'json') {
|
|
1152
1159
|
let metrics = null
|
|
1153
1160
|
|
|
1161
|
+
const applicationRestartMetrics = format === 'json'
|
|
1162
|
+
? this.#getApplicationRestartMetricsJson()
|
|
1163
|
+
: this.#formatApplicationRestartMetricsText()
|
|
1164
|
+
|
|
1154
1165
|
// Get process-level metrics once from main thread registry (if available)
|
|
1155
1166
|
let processMetricsJson = null
|
|
1156
1167
|
if (this.#processMetricsRegistry) {
|
|
@@ -1216,9 +1227,68 @@ export class Runtime extends EventEmitter {
|
|
|
1216
1227
|
}
|
|
1217
1228
|
}
|
|
1218
1229
|
|
|
1230
|
+
if (metrics !== null && applicationRestartMetrics.length > 0) {
|
|
1231
|
+
metrics = format === 'json'
|
|
1232
|
+
? [...applicationRestartMetrics, ...metrics]
|
|
1233
|
+
: applicationRestartMetrics + metrics
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1219
1236
|
return { metrics }
|
|
1220
1237
|
}
|
|
1221
1238
|
|
|
1239
|
+
#incrementApplicationRestartCount (applicationId) {
|
|
1240
|
+
this.#applicationRestartCounts.set(applicationId, (this.#applicationRestartCounts.get(applicationId) ?? 0) + 1)
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
#getApplicationRestartMetricLabels (applicationId) {
|
|
1244
|
+
return {
|
|
1245
|
+
...this.#config.metrics?.labels,
|
|
1246
|
+
[this.#metricsLabelName]: applicationId
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
#getApplicationRestartMetricsJson () {
|
|
1251
|
+
const metrics = []
|
|
1252
|
+
|
|
1253
|
+
for (const applicationId of this.#applications.keys()) {
|
|
1254
|
+
metrics.push({
|
|
1255
|
+
name: kApplicationRestartsMetricName,
|
|
1256
|
+
help: kApplicationRestartsMetricHelp,
|
|
1257
|
+
type: 'counter',
|
|
1258
|
+
aggregator: 'sum',
|
|
1259
|
+
values: [{
|
|
1260
|
+
value: this.#applicationRestartCounts.get(applicationId) ?? 0,
|
|
1261
|
+
labels: this.#getApplicationRestartMetricLabels(applicationId),
|
|
1262
|
+
metricName: kApplicationRestartsMetricName
|
|
1263
|
+
}]
|
|
1264
|
+
})
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
return metrics
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
#formatApplicationRestartMetricsText () {
|
|
1271
|
+
let output = ''
|
|
1272
|
+
|
|
1273
|
+
for (const applicationId of this.#applications.keys()) {
|
|
1274
|
+
const labelParts = []
|
|
1275
|
+
const labels = this.#getApplicationRestartMetricLabels(applicationId)
|
|
1276
|
+
|
|
1277
|
+
for (const [key, val] of Object.entries(labels)) {
|
|
1278
|
+
const escapedVal = String(val).replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n')
|
|
1279
|
+
labelParts.push(`${key}="${escapedVal}"`)
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
const labelStr = labelParts.length > 0 ? `{${labelParts.join(',')}}` : ''
|
|
1283
|
+
|
|
1284
|
+
output += `# HELP ${kApplicationRestartsMetricName} ${kApplicationRestartsMetricHelp}\n`
|
|
1285
|
+
output += `# TYPE ${kApplicationRestartsMetricName} counter\n`
|
|
1286
|
+
output += `${kApplicationRestartsMetricName}${labelStr} ${this.#applicationRestartCounts.get(applicationId) ?? 0}\n`
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
return output
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1222
1292
|
// Apply labels to process metrics and push to output array (for JSON format)
|
|
1223
1293
|
#applyLabelsToMetrics (processMetrics, labels, outputArray) {
|
|
1224
1294
|
for (let i = 0; i < processMetrics.length; i++) {
|
|
@@ -2152,6 +2222,7 @@ export class Runtime extends EventEmitter {
|
|
|
2152
2222
|
)
|
|
2153
2223
|
|
|
2154
2224
|
await this.#replaceWorker(config, applicationConfig, workersCount, id, index, worker)
|
|
2225
|
+
this.#incrementApplicationRestartCount(id)
|
|
2155
2226
|
} catch (e) {
|
|
2156
2227
|
this.logger.error(
|
|
2157
2228
|
`Cannot replace the ${errorLabel}. Forcefully terminating it ...`
|
|
@@ -2477,6 +2548,7 @@ export class Runtime extends EventEmitter {
|
|
|
2477
2548
|
try {
|
|
2478
2549
|
await this.#setupWorker(config, applicationConfig, workersCount, id, index)
|
|
2479
2550
|
await this.#startWorker(config, applicationConfig, workersCount, id, index, silent, bootstrapAttempt)
|
|
2551
|
+
this.#incrementApplicationRestartCount(id)
|
|
2480
2552
|
|
|
2481
2553
|
this.logger.info(
|
|
2482
2554
|
`The ${this.#workerExtendedLabel(id, index, workersCount)} has been successfully restarted ...`
|
package/lib/worker/itc.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ensureLoggableError, executeInParallel, executeWithTimeout, kTimeout } from '@platformatic/foundation'
|
|
2
|
-
import { ITC } from '@platformatic/itc'
|
|
2
|
+
import { initializeITCTelemetry, ITC } from '@platformatic/itc'
|
|
3
3
|
import { Unpromise } from '@watchable/unpromise'
|
|
4
4
|
import { once } from 'node:events'
|
|
5
5
|
import { createRequire } from 'node:module'
|
|
@@ -147,7 +147,9 @@ export async function waitEventFromITC (worker, event) {
|
|
|
147
147
|
return safeHandleInITC(worker, () => once(worker[kITC], event))
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
export function setupITC (controller, application, dispatcher, sharedContext) {
|
|
150
|
+
export async function setupITC (controller, application, dispatcher, sharedContext) {
|
|
151
|
+
await initializeITCTelemetry()
|
|
152
|
+
|
|
151
153
|
const logger = globalThis.platformatic.logger
|
|
152
154
|
const messaging = new MessagingITC(controller.applicationConfig.id, workerData.config, logger)
|
|
153
155
|
|
package/lib/worker/main.js
CHANGED
|
@@ -271,7 +271,7 @@ async function main () {
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
// Setup interaction with parent port
|
|
274
|
-
const itc = setupITC(controller, applicationConfig, threadDispatcher, sharedContext)
|
|
274
|
+
const itc = await setupITC(controller, applicationConfig, threadDispatcher, sharedContext)
|
|
275
275
|
globalThis[kITC] = itc
|
|
276
276
|
globalThis.platformatic.itc = itc
|
|
277
277
|
|
package/lib/worker/messaging.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { ensureLoggableError, executeWithTimeout, kTimeout } from '@platformatic/foundation'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
errors,
|
|
4
|
+
generateRequest,
|
|
5
|
+
generateResponse,
|
|
6
|
+
ITC,
|
|
7
|
+
parseRequest,
|
|
8
|
+
sanitize,
|
|
9
|
+
startOutgoingMessagingSpan,
|
|
10
|
+
startOutgoingMessagingSpanSync,
|
|
11
|
+
traceIncomingMessagingHandler
|
|
12
|
+
} from '@platformatic/itc'
|
|
3
13
|
import { MessagingError } from '../errors.js'
|
|
4
14
|
import { RoundRobinMap } from './round-robin-map.js'
|
|
5
15
|
import { kITC, kWorkersBroadcast } from './symbols.js'
|
|
@@ -50,69 +60,106 @@ export class MessagingITC extends ITC {
|
|
|
50
60
|
handle (message, handler) {
|
|
51
61
|
if (typeof message === 'object') {
|
|
52
62
|
for (const [name, fn] of Object.entries(message)) {
|
|
53
|
-
super.handle(name, fn)
|
|
63
|
+
super.handle(name, this.#wrapHandler(name, fn))
|
|
54
64
|
}
|
|
55
65
|
} else {
|
|
56
|
-
super.handle(message, handler)
|
|
66
|
+
super.handle(message, this.#wrapHandler(message, handler))
|
|
57
67
|
}
|
|
58
68
|
}
|
|
59
69
|
|
|
60
70
|
async send (application, name, message, options) {
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
const telemetry = startOutgoingMessagingSpan('send', this.#id, application, name, {
|
|
72
|
+
telemetryContext: options?.telemetryContext,
|
|
73
|
+
telemetryMetadata: options?.telemetryMetadata
|
|
74
|
+
})
|
|
75
|
+
let error = null
|
|
63
76
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
77
|
+
try {
|
|
78
|
+
// Get the next worker for the application
|
|
79
|
+
const worker = this.#workers.next(application)
|
|
67
80
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
if (!worker) {
|
|
82
|
+
throw new MessagingError(application, 'No workers available')
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!worker.channel) {
|
|
86
|
+
// Use twice the value here as a fallback measure. The target handler in the main thread is forwarding
|
|
87
|
+
// the request to the worker, using executeWithTimeout with the user set timeout value.
|
|
88
|
+
const channel = await executeWithTimeout(
|
|
89
|
+
globalThis[kITC].send('getWorkerMessagingChannel', {
|
|
90
|
+
id: this.#id,
|
|
91
|
+
application: worker.application,
|
|
92
|
+
worker: worker.worker
|
|
93
|
+
}),
|
|
94
|
+
this.#timeout * 2
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
/* c8 ignore next 3 - Hard to test */
|
|
98
|
+
if (channel === kTimeout) {
|
|
99
|
+
throw new MessagingError(application, 'Timeout while waiting for a communication channel.')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
worker.channel = channel
|
|
103
|
+
this.#setupChannel(channel)
|
|
79
104
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
throw new MessagingError(application, 'Timeout while waiting for a communication channel.')
|
|
105
|
+
channel[kPendingResponses] = new Map()
|
|
106
|
+
channel.on('close', this.#handlePendingResponse.bind(this, channel))
|
|
83
107
|
}
|
|
84
108
|
|
|
85
|
-
|
|
86
|
-
|
|
109
|
+
const context = { ...options }
|
|
110
|
+
context.channel = worker.channel
|
|
111
|
+
context.application = worker.application
|
|
112
|
+
context.trackResponse = true
|
|
87
113
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
114
|
+
if (options?.meta || telemetry?.meta) {
|
|
115
|
+
context.meta = { ...options?.meta, ...telemetry?.meta }
|
|
116
|
+
}
|
|
91
117
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
context.application = worker.application
|
|
95
|
-
context.trackResponse = true
|
|
118
|
+
const send = () => executeWithTimeout(super.send(name, message, context), this.#timeout)
|
|
119
|
+
const response = telemetry ? await telemetry.run(send) : await send()
|
|
96
120
|
|
|
97
|
-
|
|
121
|
+
if (response === kTimeout) {
|
|
122
|
+
throw new MessagingError(application, 'Timeout while waiting for a response.')
|
|
123
|
+
}
|
|
98
124
|
|
|
99
|
-
|
|
100
|
-
|
|
125
|
+
return response
|
|
126
|
+
} catch (err) {
|
|
127
|
+
error = err
|
|
128
|
+
throw err
|
|
129
|
+
} finally {
|
|
130
|
+
telemetry?.end(error)
|
|
101
131
|
}
|
|
102
|
-
|
|
103
|
-
return response
|
|
104
132
|
}
|
|
105
133
|
|
|
106
|
-
notify (application, name, message) {
|
|
107
|
-
const
|
|
134
|
+
notify (application, name, message, options) {
|
|
135
|
+
const telemetry = startOutgoingMessagingSpanSync('notify', this.#id, application, name, {
|
|
136
|
+
telemetryContext: options?.telemetryContext,
|
|
137
|
+
telemetryMetadata: options?.telemetryMetadata
|
|
138
|
+
})
|
|
139
|
+
const metadata = options?.meta || telemetry?.meta ? { ...options?.meta, ...telemetry?.meta } : undefined
|
|
140
|
+
const request = generateRequest(name, message, metadata)
|
|
141
|
+
|
|
142
|
+
let error = null
|
|
108
143
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
channel
|
|
112
|
-
|
|
113
|
-
|
|
144
|
+
try {
|
|
145
|
+
let channel = this.#notificationsChannels.get(application)
|
|
146
|
+
if (!channel) {
|
|
147
|
+
channel = new BroadcastChannel(`plt.messaging.notifications-${application}`)
|
|
148
|
+
this.#notificationsChannels.set(application, channel)
|
|
149
|
+
}
|
|
114
150
|
|
|
115
|
-
|
|
151
|
+
const postMessage = () => channel.postMessage(sanitize(request))
|
|
152
|
+
if (telemetry) {
|
|
153
|
+
telemetry.run(postMessage)
|
|
154
|
+
} else {
|
|
155
|
+
postMessage()
|
|
156
|
+
}
|
|
157
|
+
} catch (err) {
|
|
158
|
+
error = err
|
|
159
|
+
throw err
|
|
160
|
+
} finally {
|
|
161
|
+
telemetry?.end(error)
|
|
162
|
+
}
|
|
116
163
|
}
|
|
117
164
|
|
|
118
165
|
async addSource (channel) {
|
|
@@ -165,7 +212,7 @@ export class MessagingITC extends ITC {
|
|
|
165
212
|
#setupChannel (channel) {
|
|
166
213
|
// Setup the message for processing
|
|
167
214
|
channel.on('message', event => {
|
|
168
|
-
this.#listener(event, { channel })
|
|
215
|
+
this.#listener(event, { channel, message: event })
|
|
169
216
|
})
|
|
170
217
|
}
|
|
171
218
|
|
|
@@ -207,12 +254,16 @@ export class MessagingITC extends ITC {
|
|
|
207
254
|
throw new errors.HandlerNotFoundError(request.name)
|
|
208
255
|
}
|
|
209
256
|
|
|
210
|
-
await handler(request.data)
|
|
257
|
+
await handler(request.data, { application: this.#id, message: request, notification: true })
|
|
211
258
|
} catch (error) {
|
|
212
259
|
this.#logger.error({ error }, `"Handler for the "${request.name}" message failed.`)
|
|
213
260
|
}
|
|
214
261
|
}
|
|
215
262
|
|
|
263
|
+
#wrapHandler (messageName, handler) {
|
|
264
|
+
return (data, context) => traceIncomingMessagingHandler(this.#id, messageName, handler, data, context)
|
|
265
|
+
}
|
|
266
|
+
|
|
216
267
|
#handlePendingResponse (channel) {
|
|
217
268
|
for (const { application, request } of channel[kPendingResponses].values()) {
|
|
218
269
|
this._emitResponse(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/runtime",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.54.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
"typescript": "^5.5.4",
|
|
37
37
|
"undici-oidc-interceptor": "^0.5.0",
|
|
38
38
|
"why-is-node-running": "^2.2.2",
|
|
39
|
-
"@platformatic/
|
|
40
|
-
"@platformatic/gateway": "3.
|
|
41
|
-
"@platformatic/
|
|
42
|
-
"@platformatic/service": "3.
|
|
43
|
-
"@platformatic/
|
|
44
|
-
"@platformatic/
|
|
45
|
-
"@platformatic/sql-
|
|
46
|
-
"@platformatic/wattpm-pprof-capture": "3.
|
|
39
|
+
"@platformatic/db": "3.54.0",
|
|
40
|
+
"@platformatic/gateway": "3.54.0",
|
|
41
|
+
"@platformatic/node": "3.54.0",
|
|
42
|
+
"@platformatic/service": "3.54.0",
|
|
43
|
+
"@platformatic/composer": "3.54.0",
|
|
44
|
+
"@platformatic/sql-mapper": "3.54.0",
|
|
45
|
+
"@platformatic/sql-graphql": "3.54.0",
|
|
46
|
+
"@platformatic/wattpm-pprof-capture": "3.54.0"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@fastify/accepts": "^5.0.0",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"help-me": "^5.0.0",
|
|
66
66
|
"minimist": "^1.2.8",
|
|
67
67
|
"pino": "^10.1.0",
|
|
68
|
-
"pino-opentelemetry-transport": "^
|
|
68
|
+
"pino-opentelemetry-transport": "^3.0.0",
|
|
69
69
|
"pino-pretty": "^13.0.0",
|
|
70
70
|
"semgrator": "^0.3.0",
|
|
71
71
|
"sonic-boom": "^4.2.0",
|
|
@@ -73,12 +73,12 @@
|
|
|
73
73
|
"undici": "^7.0.0",
|
|
74
74
|
"undici-thread-interceptor": "^1.3.1",
|
|
75
75
|
"ws": "^8.16.0",
|
|
76
|
-
"@platformatic/
|
|
77
|
-
"@platformatic/
|
|
78
|
-
"@platformatic/
|
|
79
|
-
"@platformatic/metrics": "3.
|
|
80
|
-
"@platformatic/
|
|
81
|
-
"@platformatic/telemetry": "3.
|
|
76
|
+
"@platformatic/basic": "3.54.0",
|
|
77
|
+
"@platformatic/foundation": "3.54.0",
|
|
78
|
+
"@platformatic/itc": "3.54.0",
|
|
79
|
+
"@platformatic/metrics": "3.54.0",
|
|
80
|
+
"@platformatic/generators": "3.54.0",
|
|
81
|
+
"@platformatic/telemetry": "3.54.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.54.0.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"title": "Platformatic Runtime Config",
|
|
5
5
|
"type": "object",
|
|
@@ -2595,6 +2595,17 @@
|
|
|
2595
2595
|
}
|
|
2596
2596
|
}
|
|
2597
2597
|
]
|
|
2598
|
+
},
|
|
2599
|
+
"diagLogger": {
|
|
2600
|
+
"anyOf": [
|
|
2601
|
+
{
|
|
2602
|
+
"type": "boolean"
|
|
2603
|
+
},
|
|
2604
|
+
{
|
|
2605
|
+
"type": "string"
|
|
2606
|
+
}
|
|
2607
|
+
],
|
|
2608
|
+
"description": "Enable the OpenTelemetry diagnostic logger. Diagnostic messages are forwarded to the Platformatic global logger using the current logger level."
|
|
2598
2609
|
}
|
|
2599
2610
|
},
|
|
2600
2611
|
"required": [
|