Files
openchamber/packages/web/bin/lib/commands-logs.js
T

111 lines
2.9 KiB
JavaScript

import { getLogFilePath } from './cli-paths.js';
import { readTailLines, followFile } from './cli-log-files.js';
import { discoverRunningInstances, getLatestInstance } from './cli-lifecycle.js';
import {
intro as clackIntro,
outro as clackOutro,
isJsonMode,
shouldRenderHumanOutput,
printJson,
logStatus,
} from '../cli-output.js';
async function logsCommand(options) {
const showFrames = shouldRenderHumanOutput(options);
const shouldPrefixLines = options.all || !showFrames;
let targets = [];
const running = await discoverRunningInstances();
if (options.all) {
targets = running;
if (targets.length === 0) {
throw new Error('No running OpenChamber instance found.');
}
} else if (options.explicitPort) {
const found = running.find((entry) => entry.port === options.port);
if (!found) {
throw new Error(`No running OpenChamber instance found on port ${options.port}.`);
}
targets = [found];
} else {
const latest = getLatestInstance(running);
if (!latest) {
throw new Error('No running OpenChamber instance found.');
}
targets = [latest];
if (shouldRenderHumanOutput(options)) {
logStatus('info', `no port specified; using latest started instance on port ${latest.port}`);
}
}
if (isJsonMode(options)) {
if (options.follow) {
throw new Error('`openchamber logs --json` requires `--no-follow` for deterministic JSON output.');
}
const entries = targets.map((target) => {
const logPath = getLogFilePath(target.port);
return {
port: target.port,
logPath,
lines: readTailLines(logPath, options.lines),
};
});
printJson({ entries });
return;
}
if (showFrames) {
clackIntro('OpenChamber Logs');
}
for (const target of targets) {
const logPath = getLogFilePath(target.port);
const lines = readTailLines(logPath, options.lines);
if (showFrames) {
logStatus('info', `port ${target.port}`, logPath);
}
for (const line of lines) {
if (shouldPrefixLines) {
console.log(`[${target.port}] ${line}`);
} else {
console.log(line);
}
}
}
if (showFrames) {
clackOutro(options.follow ? 'following (Ctrl+C to stop)' : 'tail complete');
}
if (!options.follow) {
return;
}
const unsubs = targets.map((target) => {
const logPath = getLogFilePath(target.port);
return followFile(logPath, (line) => {
if (shouldPrefixLines) {
console.log(`[${target.port}] ${line}`);
} else {
console.log(line);
}
});
});
await new Promise((resolve) => {
const onSignal = () => {
for (const unsub of unsubs) {
unsub();
}
process.off('SIGINT', onSignal);
process.off('SIGTERM', onSignal);
resolve();
};
process.on('SIGINT', onSignal);
process.on('SIGTERM', onSignal);
});
}
export { logsCommand };