@platformatic/control
Advanced tools
Comparing version 1.24.0 to 1.25.0
'use strict' | ||
const { parseArgs } = require('node:util') | ||
const { prettyFactory } = require('pino-pretty') | ||
const RuntimeApiClient = require('./runtime-api-client') | ||
const pinoLogLevels = { | ||
fatal: 60, | ||
error: 50, | ||
warn: 40, | ||
info: 30, | ||
debug: 20, | ||
trace: 10 | ||
} | ||
async function streamRuntimeLogsCommand (argv) { | ||
@@ -13,3 +23,3 @@ const args = parseArgs({ | ||
level: { type: 'string', short: 'l', default: 'info' }, | ||
pretty: { type: 'boolean', default: true }, | ||
pretty: { type: 'string', default: 'true' }, | ||
service: { type: 'string', short: 's' } | ||
@@ -23,16 +33,27 @@ }, | ||
const options = {} | ||
if (args.level !== undefined) { | ||
options.level = args.level | ||
} | ||
if (args.pretty !== undefined) { | ||
options.pretty = args.pretty | ||
} | ||
if (args.service !== undefined) { | ||
options.serviceId = args.service | ||
} | ||
const logLevelNumber = pinoLogLevels[args.level] | ||
const prettify = prettyFactory() | ||
const logsStream = client.getRuntimeLogsStream(runtime.pid, options) | ||
logsStream.pipe(process.stdout) | ||
const logsStream = client.getRuntimeLogsStream(runtime.pid) | ||
logsStream.on('data', (data) => { | ||
const logs = data.toString().split('\n') | ||
for (let log of logs) { | ||
try { | ||
const parsedLog = JSON.parse(log) | ||
if (parsedLog.level < logLevelNumber) continue | ||
if (args.service && parsedLog.name !== args.service) continue | ||
if (args.pretty !== 'false') { | ||
log = prettify(parsedLog) | ||
} else { | ||
log += '\n' | ||
} | ||
process.stdout.write(log) | ||
} catch (err) { | ||
console.error('Failed to parse log message: ', log, err) | ||
} | ||
} | ||
}) | ||
process.on('SIGINT', () => { | ||
@@ -39,0 +60,0 @@ logsStream.destroy() |
@@ -6,3 +6,3 @@ 'use strict' | ||
const { exec, spawn } = require('node:child_process') | ||
const { readdir } = require('node:fs/promises') | ||
const { readdir, unlink, access } = require('node:fs/promises') | ||
const { Readable } = require('node:stream') | ||
@@ -48,5 +48,14 @@ const { Client } = require('undici') | ||
return getMetadataRequests | ||
.filter(result => result.status === 'fulfilled') | ||
.map(result => result.value) | ||
const runtimes = [] | ||
for (let i = 0; i < runtimePIDs.length; i++) { | ||
const runtimePID = runtimePIDs[i] | ||
const metadataRequest = getMetadataRequests[i] | ||
if (metadataRequest.status === 'rejected') { | ||
await this.#removeRuntimeSocket(runtimePID).catch(() => {}) | ||
} else { | ||
runtimes.push(metadataRequest.value) | ||
} | ||
} | ||
return runtimes | ||
} | ||
@@ -58,3 +67,3 @@ | ||
const { statusCode, body } = await client.request({ | ||
path: '/api/metadata', | ||
path: '/api/v1/metadata', | ||
method: 'GET' | ||
@@ -76,3 +85,3 @@ }) | ||
const { statusCode, body } = await client.request({ | ||
path: '/api/services', | ||
path: '/api/v1/services', | ||
method: 'GET' | ||
@@ -94,3 +103,3 @@ }) | ||
const { statusCode, body } = await client.request({ | ||
path: `/api/services/${serviceId}/config`, | ||
path: `/api/v1/services/${serviceId}/config`, | ||
method: 'GET' | ||
@@ -112,3 +121,3 @@ }) | ||
const { statusCode, body } = await client.request({ | ||
path: '/api/config', | ||
path: '/api/v1/config', | ||
method: 'GET' | ||
@@ -130,3 +139,3 @@ }) | ||
const { statusCode, body } = await client.request({ | ||
path: '/api/env', | ||
path: '/api/v1/env', | ||
method: 'GET' | ||
@@ -158,3 +167,3 @@ }) | ||
const { statusCode, body } = await client.request({ | ||
path: '/api/reload', | ||
path: '/api/v1/reload', | ||
method: 'POST' | ||
@@ -173,3 +182,3 @@ }) | ||
const { statusCode, body } = await client.request({ | ||
path: '/api/stop', | ||
path: '/api/v1/stop', | ||
method: 'POST' | ||
@@ -184,11 +193,7 @@ }) | ||
getRuntimeLogsStream (pid, options) { | ||
getRuntimeLogsStream (pid) { | ||
const socketPath = this.#getSocketPathFromPid(pid) | ||
let query = '' | ||
if (options.level || options.pretty || options.serviceId) { | ||
query = '?' + new URLSearchParams(options).toString() | ||
} | ||
const protocol = platform() === 'win32' ? 'ws+unix:' : 'ws+unix://' | ||
const webSocketUrl = protocol + socketPath + ':/api/logs' + query | ||
const webSocketUrl = protocol + socketPath + ':/api/v1/logs' | ||
const webSocketStream = new WebSocketStream(webSocketUrl) | ||
@@ -204,3 +209,3 @@ this.#webSockets.add(webSocketStream.ws) | ||
const response = await client.request({ | ||
path: `/api/services/${serviceId}/proxy` + options.url, | ||
path: `/api/v1/services/${serviceId}/proxy` + options.url, | ||
method: options.method, | ||
@@ -245,2 +250,7 @@ headers: options.headers, | ||
async #getUnixRuntimePIDs () { | ||
try { | ||
await access(PLATFORMATIC_TMP_DIR) | ||
} catch { | ||
return [] | ||
} | ||
const socketNames = await readdir(PLATFORMATIC_TMP_DIR) | ||
@@ -283,2 +293,9 @@ const runtimePIDs = [] | ||
} | ||
async #removeRuntimeSocket (pid) { | ||
if (platform() !== 'win32') { | ||
const socketPath = this.#getSocketPathFromPid(pid) | ||
await unlink(socketPath) | ||
} | ||
} | ||
} | ||
@@ -285,0 +302,0 @@ |
{ | ||
"name": "@platformatic/control", | ||
"version": "1.24.0", | ||
"version": "1.25.0", | ||
"description": "Platformatic Control", | ||
@@ -27,3 +27,3 @@ "main": "index.js", | ||
"tsd": "^0.30.4", | ||
"@platformatic/runtime": "1.24.0" | ||
"@platformatic/runtime": "1.25.0" | ||
}, | ||
@@ -33,5 +33,5 @@ "dependencies": { | ||
"commist": "^3.2.0", | ||
"help-me": "^5.0.0", | ||
"pino": "^8.17.2", | ||
"pino-pretty": "^10.3.1", | ||
"help-me": "^5.0.0", | ||
"table": "^6.8.1", | ||
@@ -38,0 +38,0 @@ "undici": "^6.6.0", |
41902
721