@platformatic/runtime 1.29.0 → 1.30.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/fixtures/configs/monorepo.json +1 -0
- package/fixtures/management-api/services/service-1/plugin.js +2 -2
- package/lib/generator/runtime-generator.js +29 -13
- package/lib/logs.js +14 -3
- package/lib/management-api.js +18 -8
- package/lib/schema.js +3 -1
- package/lib/utils.js +10 -0
- package/package.json +11 -11
|
@@ -7,8 +7,8 @@ module.exports = async function (app) {
|
|
|
7
7
|
})
|
|
8
8
|
|
|
9
9
|
app.get('/large-logs', async (req) => {
|
|
10
|
-
const largeLog = 'a'.repeat(
|
|
11
|
-
for (let i = 0; i <
|
|
10
|
+
const largeLog = 'a'.repeat(100)
|
|
11
|
+
for (let i = 0; i < 500000; i++) {
|
|
12
12
|
app.log.trace(largeLog)
|
|
13
13
|
}
|
|
14
14
|
})
|
|
@@ -14,6 +14,7 @@ const ComposerGenerator = require('@platformatic/composer/lib/generator/composer
|
|
|
14
14
|
const { CannotFindGeneratorForTemplateError, CannotRemoveServiceOnUpdateError } = require('../errors')
|
|
15
15
|
const { getServiceTemplateFromSchemaUrl } = require('@platformatic/generators/lib/utils')
|
|
16
16
|
const { DotEnvTool } = require('dotenv-tool')
|
|
17
|
+
const { getArrayDifference } = require('../utils')
|
|
17
18
|
|
|
18
19
|
class RuntimeGenerator extends BaseGenerator {
|
|
19
20
|
constructor (opts) {
|
|
@@ -91,7 +92,8 @@ class RuntimeGenerator extends BaseGenerator {
|
|
|
91
92
|
this.addEnvVars({
|
|
92
93
|
PLT_SERVER_HOSTNAME: '0.0.0.0',
|
|
93
94
|
PORT: this.config.port || 3042,
|
|
94
|
-
PLT_SERVER_LOGGER_LEVEL: this.config.logLevel || 'info'
|
|
95
|
+
PLT_SERVER_LOGGER_LEVEL: this.config.logLevel || 'info',
|
|
96
|
+
PLT_MANAGEMENT_API: true
|
|
95
97
|
}, { overwrite: false })
|
|
96
98
|
}
|
|
97
99
|
|
|
@@ -165,7 +167,8 @@ class RuntimeGenerator extends BaseGenerator {
|
|
|
165
167
|
logger: {
|
|
166
168
|
level: '{PLT_SERVER_LOGGER_LEVEL}'
|
|
167
169
|
}
|
|
168
|
-
}
|
|
170
|
+
},
|
|
171
|
+
managementApi: '{PLT_MANAGEMENT_API}'
|
|
169
172
|
}
|
|
170
173
|
|
|
171
174
|
return config
|
|
@@ -337,13 +340,11 @@ class RuntimeGenerator extends BaseGenerator {
|
|
|
337
340
|
|
|
338
341
|
async update (newConfig) {
|
|
339
342
|
let allServicesDependencies = {}
|
|
340
|
-
|
|
341
|
-
return a.filter(element => {
|
|
342
|
-
return !b.includes(element)
|
|
343
|
-
})
|
|
344
|
-
}
|
|
345
|
-
this.config.isUpdating = true
|
|
343
|
+
const runtimeAddedEnvKeys = []
|
|
346
344
|
|
|
345
|
+
this.config.isUpdating = true
|
|
346
|
+
const currrentPackageJson = JSON.parse(await readFile(join(this.targetDirectory, 'package.json'), 'utf-8'))
|
|
347
|
+
const currentRuntimeDependencies = currrentPackageJson.dependencies
|
|
347
348
|
// check all services are present with the same template
|
|
348
349
|
const allCurrentServicesNames = this.services.map((s) => s.name)
|
|
349
350
|
const allNewServicesNames = newConfig.services.map((s) => s.name)
|
|
@@ -354,7 +355,7 @@ class RuntimeGenerator extends BaseGenerator {
|
|
|
354
355
|
|
|
355
356
|
await envTool.load()
|
|
356
357
|
|
|
357
|
-
const removedServices =
|
|
358
|
+
const removedServices = getArrayDifference(allCurrentServicesNames, allNewServicesNames)
|
|
358
359
|
if (removedServices.length > 0) {
|
|
359
360
|
throw new CannotRemoveServiceOnUpdateError(removedServices.join(', '))
|
|
360
361
|
}
|
|
@@ -373,12 +374,22 @@ class RuntimeGenerator extends BaseGenerator {
|
|
|
373
374
|
// update existing services env values
|
|
374
375
|
// otherwise, is a new service
|
|
375
376
|
baseConfig.isUpdating = true
|
|
377
|
+
|
|
378
|
+
// handle service's plugin differences
|
|
379
|
+
const oldServiceMetadata = await serviceInstance.loadFromDir(newService.name, this.targetDirectory)
|
|
380
|
+
const oldServicePackages = oldServiceMetadata.plugins.map((meta) => meta.name)
|
|
381
|
+
const newServicePackages = newService.plugins.map((meta) => meta.name)
|
|
382
|
+
const pluginsToRemove = getArrayDifference(oldServicePackages, newServicePackages)
|
|
383
|
+
pluginsToRemove.forEach((p) => delete currentRuntimeDependencies[p])
|
|
376
384
|
}
|
|
377
385
|
serviceInstance.setConfig(baseConfig)
|
|
386
|
+
|
|
387
|
+
const serviceEnvPrefix = `PLT_${serviceInstance.config.envPrefix}`
|
|
378
388
|
for (const plug of newService.plugins) {
|
|
379
389
|
await serviceInstance.addPackage(plug)
|
|
380
390
|
for (const opt of plug.options) {
|
|
381
|
-
const key =
|
|
391
|
+
const key = `${serviceEnvPrefix}_${opt.name}`
|
|
392
|
+
runtimeAddedEnvKeys.push(key)
|
|
382
393
|
const value = opt.value
|
|
383
394
|
if (envTool.hasKey(key)) {
|
|
384
395
|
envTool.updateKey(key, value)
|
|
@@ -390,11 +401,16 @@ class RuntimeGenerator extends BaseGenerator {
|
|
|
390
401
|
allServicesDependencies = { ...allServicesDependencies, ...serviceInstance.config.dependencies }
|
|
391
402
|
await serviceInstance.prepare()
|
|
392
403
|
await serviceInstance.writeFiles()
|
|
404
|
+
// cleanup runtime env removing keys not present anymore in service plugins
|
|
405
|
+
const allKeys = envTool.getKeys()
|
|
406
|
+
allKeys.forEach((k) => {
|
|
407
|
+
if (k.startsWith('PLT_') && !runtimeAddedEnvKeys.includes(k)) {
|
|
408
|
+
envTool.deleteKey(k)
|
|
409
|
+
}
|
|
410
|
+
})
|
|
393
411
|
}
|
|
394
412
|
|
|
395
413
|
// update runtime package.json dependencies
|
|
396
|
-
// read current package.json file
|
|
397
|
-
const currrentPackageJson = JSON.parse(await readFile(join(this.targetDirectory, 'package.json'), 'utf-8'))
|
|
398
414
|
currrentPackageJson.dependencies = {
|
|
399
415
|
...currrentPackageJson.dependencies,
|
|
400
416
|
...allServicesDependencies
|
|
@@ -402,7 +418,7 @@ class RuntimeGenerator extends BaseGenerator {
|
|
|
402
418
|
this.addFile({
|
|
403
419
|
path: '',
|
|
404
420
|
file: 'package.json',
|
|
405
|
-
contents: JSON.stringify(currrentPackageJson)
|
|
421
|
+
contents: JSON.stringify(currrentPackageJson, null, 2)
|
|
406
422
|
})
|
|
407
423
|
|
|
408
424
|
await this.writeFiles()
|
package/lib/logs.js
CHANGED
|
@@ -21,7 +21,9 @@ async function getLogFiles () {
|
|
|
21
21
|
return runtimeLogFiles
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
async function
|
|
24
|
+
async function pipeLogsStream (writableStream, logger, startLogIndex, endLogIndex) {
|
|
25
|
+
endLogIndex = endLogIndex || Infinity
|
|
26
|
+
|
|
25
27
|
const runtimeLogFiles = await getLogFiles()
|
|
26
28
|
if (runtimeLogFiles.length === 0) {
|
|
27
29
|
writableStream.end()
|
|
@@ -47,6 +49,11 @@ async function pipeLiveLogs (writableStream, logger, startLogIndex) {
|
|
|
47
49
|
}).unref()
|
|
48
50
|
|
|
49
51
|
const streamLogFile = () => {
|
|
52
|
+
if (fileIndex > endLogIndex) {
|
|
53
|
+
writableStream.end()
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
50
57
|
const fileName = 'logs.' + fileIndex
|
|
51
58
|
const filePath = join(runtimeTmpDir, fileName)
|
|
52
59
|
|
|
@@ -61,7 +68,7 @@ async function pipeLiveLogs (writableStream, logger, startLogIndex) {
|
|
|
61
68
|
}
|
|
62
69
|
|
|
63
70
|
fileStream.on('error', (err) => {
|
|
64
|
-
logger.
|
|
71
|
+
logger.error(err, 'Error streaming log file')
|
|
65
72
|
fileStream.destroy()
|
|
66
73
|
watcher.close()
|
|
67
74
|
writableStream.end()
|
|
@@ -72,6 +79,10 @@ async function pipeLiveLogs (writableStream, logger, startLogIndex) {
|
|
|
72
79
|
})
|
|
73
80
|
|
|
74
81
|
fileStream.on('eof', () => {
|
|
82
|
+
if (fileIndex >= endLogIndex) {
|
|
83
|
+
writableStream.end()
|
|
84
|
+
return
|
|
85
|
+
}
|
|
75
86
|
if (latestFileIndex > fileIndex) {
|
|
76
87
|
streamLogFile(++fileIndex)
|
|
77
88
|
} else {
|
|
@@ -106,7 +117,7 @@ async function getLogFileStream (logFileIndex) {
|
|
|
106
117
|
}
|
|
107
118
|
|
|
108
119
|
module.exports = {
|
|
109
|
-
|
|
120
|
+
pipeLogsStream,
|
|
110
121
|
getLogFileStream,
|
|
111
122
|
getLogIndexes
|
|
112
123
|
}
|
package/lib/management-api.js
CHANGED
|
@@ -6,7 +6,7 @@ const { readFile, mkdir, unlink } = require('node:fs/promises')
|
|
|
6
6
|
const fastify = require('fastify')
|
|
7
7
|
const ws = require('ws')
|
|
8
8
|
const errors = require('./errors')
|
|
9
|
-
const {
|
|
9
|
+
const { pipeLogsStream, getLogFileStream, getLogIndexes } = require('./logs')
|
|
10
10
|
const platformaticVersion = require('../package.json').version
|
|
11
11
|
|
|
12
12
|
const PLATFORMATIC_TMP_DIR = join(tmpdir(), 'platformatic', 'runtimes')
|
|
@@ -118,14 +118,16 @@ async function createManagementApi (configManager, runtimeApiClient) {
|
|
|
118
118
|
|
|
119
119
|
app.get('/metrics/live', { websocket: true }, async (socket) => {
|
|
120
120
|
const cachedMetrics = runtimeApiClient.getCachedMetrics()
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
if (cachedMetrics.length > 0) {
|
|
122
|
+
const serializedMetrics = cachedMetrics
|
|
123
|
+
.map((metric) => JSON.stringify(metric))
|
|
124
|
+
.join('\n')
|
|
125
|
+
socket.send(serializedMetrics + '\n')
|
|
126
|
+
}
|
|
125
127
|
|
|
126
128
|
const eventHandler = (metrics) => {
|
|
127
129
|
const serializedMetrics = JSON.stringify(metrics)
|
|
128
|
-
socket.send(serializedMetrics)
|
|
130
|
+
socket.send(serializedMetrics + '\n')
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
runtimeApiClient.on('metrics', eventHandler)
|
|
@@ -150,8 +152,7 @@ async function createManagementApi (configManager, runtimeApiClient) {
|
|
|
150
152
|
}
|
|
151
153
|
|
|
152
154
|
const stream = ws.createWebSocketStream(socket)
|
|
153
|
-
|
|
154
|
-
pipeLiveLogs(stream, req.log, startLogIndex)
|
|
155
|
+
pipeLogsStream(stream, req.log, startLogIndex)
|
|
155
156
|
})
|
|
156
157
|
|
|
157
158
|
app.get('/logs/indexes', async () => {
|
|
@@ -159,6 +160,15 @@ async function createManagementApi (configManager, runtimeApiClient) {
|
|
|
159
160
|
return { indexes: logIndexes }
|
|
160
161
|
})
|
|
161
162
|
|
|
163
|
+
app.get('/logs/all', async (req, reply) => {
|
|
164
|
+
const logIndexes = await getLogIndexes()
|
|
165
|
+
const startLogIndex = logIndexes.at(0)
|
|
166
|
+
const endLogIndex = logIndexes.at(-1)
|
|
167
|
+
|
|
168
|
+
reply.hijack()
|
|
169
|
+
pipeLogsStream(reply.raw, req.log, startLogIndex, endLogIndex)
|
|
170
|
+
})
|
|
171
|
+
|
|
162
172
|
app.get('/logs/:id', async (req) => {
|
|
163
173
|
const { id } = req.params
|
|
164
174
|
|
package/lib/schema.js
CHANGED
|
@@ -150,6 +150,7 @@ const platformaticRuntimeSchema = {
|
|
|
150
150
|
managementApi: {
|
|
151
151
|
anyOf: [
|
|
152
152
|
{ type: 'boolean' },
|
|
153
|
+
{ type: 'string' },
|
|
153
154
|
{
|
|
154
155
|
type: 'object',
|
|
155
156
|
properties: {
|
|
@@ -163,7 +164,8 @@ const platformaticRuntimeSchema = {
|
|
|
163
164
|
},
|
|
164
165
|
additionalProperties: false
|
|
165
166
|
}
|
|
166
|
-
]
|
|
167
|
+
],
|
|
168
|
+
default: true
|
|
167
169
|
},
|
|
168
170
|
metrics: {
|
|
169
171
|
anyOf: [
|
package/lib/utils.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/runtime",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"typescript": "^5.4.2",
|
|
34
34
|
"undici-oidc-interceptor": "^0.5.0",
|
|
35
35
|
"why-is-node-running": "^2.2.2",
|
|
36
|
-
"@platformatic/sql-
|
|
37
|
-
"@platformatic/sql-
|
|
36
|
+
"@platformatic/sql-mapper": "1.30.0",
|
|
37
|
+
"@platformatic/sql-graphql": "1.30.0"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"ws": "^8.16.0",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"commist": "^3.2.0",
|
|
48
48
|
"debounce": "^2.0.0",
|
|
49
49
|
"desm": "^1.3.1",
|
|
50
|
-
"dotenv-tool": "^0.
|
|
50
|
+
"dotenv-tool": "^0.1.1",
|
|
51
51
|
"es-main": "^1.3.0",
|
|
52
52
|
"fastest-levenshtein": "^1.0.16",
|
|
53
53
|
"fastify": "^4.26.2",
|
|
@@ -62,13 +62,13 @@
|
|
|
62
62
|
"tail-file-stream": "^0.1.0",
|
|
63
63
|
"undici": "^6.9.0",
|
|
64
64
|
"why-is-node-running": "^2.2.2",
|
|
65
|
-
"@platformatic/composer": "1.
|
|
66
|
-
"@platformatic/
|
|
67
|
-
"@platformatic/
|
|
68
|
-
"@platformatic/generators": "1.
|
|
69
|
-
"@platformatic/
|
|
70
|
-
"@platformatic/
|
|
71
|
-
"@platformatic/utils": "1.
|
|
65
|
+
"@platformatic/composer": "1.30.0",
|
|
66
|
+
"@platformatic/db": "1.30.0",
|
|
67
|
+
"@platformatic/config": "1.30.0",
|
|
68
|
+
"@platformatic/generators": "1.30.0",
|
|
69
|
+
"@platformatic/service": "1.30.0",
|
|
70
|
+
"@platformatic/telemetry": "1.30.0",
|
|
71
|
+
"@platformatic/utils": "1.30.0"
|
|
72
72
|
},
|
|
73
73
|
"standard": {
|
|
74
74
|
"ignore": [
|