Add trace logging and tighten daemon log defaults (#933)
* Add trace logging and tighten daemon log defaults * Clean up daemon trace logging shape * Clean up daemon trace logging * Route provider turn-id checks through shared helper * Fix supervisor log config test paths on Windows * Expect resolved supervisor log path on Windows
This commit is contained in:
@@ -10,12 +10,9 @@ import {
|
||||
import { resolvePaseoHome } from "../src/server/paseo-home.js";
|
||||
import { loadPersistedConfig } from "../src/server/persisted-config.js";
|
||||
import { runSupervisor } from "./supervisor.js";
|
||||
import { resolveSupervisorLogFile } from "./supervisor-log-config.js";
|
||||
import { applySherpaLoaderEnv } from "../src/server/speech/providers/local/sherpa/sherpa-runtime-env.js";
|
||||
|
||||
const DEFAULT_DAEMON_LOG_FILENAME = "daemon.log";
|
||||
const DEFAULT_LOG_ROTATE_SIZE = "10m";
|
||||
const DEFAULT_LOG_ROTATE_MAX_FILES = 2;
|
||||
|
||||
interface DaemonRunnerConfig {
|
||||
devMode: boolean;
|
||||
workerArgs: string[];
|
||||
@@ -77,28 +74,6 @@ function resolvePackagedNodeEntrypointRunnerPath(currentScriptPath: string): str
|
||||
return existsSync(runnerPath) ? runnerPath : null;
|
||||
}
|
||||
|
||||
function resolveSupervisorLogFile(
|
||||
paseoHome: string,
|
||||
persistedConfig: ReturnType<typeof loadPersistedConfig>,
|
||||
) {
|
||||
const configuredFile = persistedConfig.log?.file;
|
||||
const configuredPath = configuredFile?.path;
|
||||
let logPath = path.join(paseoHome, DEFAULT_DAEMON_LOG_FILENAME);
|
||||
if (configuredPath) {
|
||||
logPath = path.isAbsolute(configuredPath)
|
||||
? configuredPath
|
||||
: path.resolve(paseoHome, configuredPath);
|
||||
}
|
||||
|
||||
return {
|
||||
path: logPath,
|
||||
rotate: {
|
||||
maxSize: configuredFile?.rotate?.maxSize ?? DEFAULT_LOG_ROTATE_SIZE,
|
||||
maxFiles: configuredFile?.rotate?.maxFiles ?? DEFAULT_LOG_ROTATE_MAX_FILES,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const config = parseConfig(process.argv.slice(2));
|
||||
const workerEntry = config.devMode ? resolveDevWorkerEntry() : resolveWorkerEntry();
|
||||
@@ -113,7 +88,7 @@ async function main(): Promise<void> {
|
||||
|
||||
const paseoHome = resolvePaseoHome(workerEnv);
|
||||
const persistedConfig = loadPersistedConfig(paseoHome);
|
||||
const supervisorLogFile = resolveSupervisorLogFile(paseoHome, persistedConfig);
|
||||
const supervisorLogFile = resolveSupervisorLogFile(paseoHome, persistedConfig, workerEnv);
|
||||
|
||||
try {
|
||||
await acquirePidLock(paseoHome, null, {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import path from "node:path";
|
||||
|
||||
import type { loadPersistedConfig } from "../src/server/persisted-config.js";
|
||||
|
||||
const DEFAULT_DAEMON_LOG_FILENAME = "daemon.log";
|
||||
const DEFAULT_LOG_ROTATE_SIZE = "10m";
|
||||
const DEFAULT_LOG_ROTATE_MAX_FILES = 3;
|
||||
|
||||
export function resolveSupervisorLogFile(
|
||||
paseoHome: string,
|
||||
persistedConfig: ReturnType<typeof loadPersistedConfig>,
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
) {
|
||||
const configuredFile = persistedConfig.log?.file;
|
||||
const configuredPath = configuredFile?.path;
|
||||
const envRotateSize = env.PASEO_LOG_ROTATE_SIZE?.trim();
|
||||
const envRotateMaxFiles = parseOptionalPositiveInteger(env.PASEO_LOG_ROTATE_COUNT);
|
||||
let logPath = path.join(paseoHome, DEFAULT_DAEMON_LOG_FILENAME);
|
||||
if (configuredPath) {
|
||||
logPath = path.isAbsolute(configuredPath)
|
||||
? configuredPath
|
||||
: path.resolve(paseoHome, configuredPath);
|
||||
}
|
||||
|
||||
return {
|
||||
path: logPath,
|
||||
rotate: {
|
||||
maxSize: configuredFile?.rotate?.maxSize ?? envRotateSize ?? DEFAULT_LOG_ROTATE_SIZE,
|
||||
maxFiles:
|
||||
configuredFile?.rotate?.maxFiles ?? envRotateMaxFiles ?? DEFAULT_LOG_ROTATE_MAX_FILES,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function parseOptionalPositiveInteger(value: string | undefined): number | undefined {
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const parsed = Number.parseInt(value.trim(), 10);
|
||||
return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { spawn } from "node:child_process";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { isPlatform } from "../src/test-utils/platform.js";
|
||||
import { resolveSupervisorLogFile } from "./supervisor-log-config.js";
|
||||
|
||||
const repoRoot = path.resolve(fileURLToPath(new URL("../../..", import.meta.url)));
|
||||
const supervisorPath = fileURLToPath(new URL("./supervisor.ts", import.meta.url));
|
||||
@@ -87,6 +88,57 @@ async function runSupervisorFixture(options: {
|
||||
}
|
||||
|
||||
describe("supervisor durable logging", () => {
|
||||
test("resolves rotation defaults", () => {
|
||||
const paseoHome = path.join(path.sep, "tmp", "paseo-home");
|
||||
const logFile = resolveSupervisorLogFile(paseoHome, {}, {});
|
||||
|
||||
expect(logFile).toEqual({
|
||||
path: path.join(paseoHome, "daemon.log"),
|
||||
rotate: { maxSize: "10m", maxFiles: 3 },
|
||||
});
|
||||
});
|
||||
|
||||
test("lets persisted rotation override env rotation defaults", () => {
|
||||
const paseoHome = path.join(path.sep, "tmp", "paseo-home");
|
||||
const logFile = resolveSupervisorLogFile(
|
||||
paseoHome,
|
||||
{
|
||||
log: {
|
||||
file: {
|
||||
path: "logs/daemon.log",
|
||||
rotate: { maxSize: "25m", maxFiles: 4 },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
PASEO_LOG_ROTATE_SIZE: "200m",
|
||||
PASEO_LOG_ROTATE_COUNT: "12",
|
||||
},
|
||||
);
|
||||
|
||||
expect(logFile).toEqual({
|
||||
path: path.resolve(paseoHome, "logs", "daemon.log"),
|
||||
rotate: { maxSize: "25m", maxFiles: 4 },
|
||||
});
|
||||
});
|
||||
|
||||
test("uses env rotation when persisted rotation is absent", () => {
|
||||
const paseoHome = path.join(path.sep, "tmp", "paseo-home");
|
||||
const logFile = resolveSupervisorLogFile(
|
||||
paseoHome,
|
||||
{},
|
||||
{
|
||||
PASEO_LOG_ROTATE_SIZE: "50m",
|
||||
PASEO_LOG_ROTATE_COUNT: "8",
|
||||
},
|
||||
);
|
||||
|
||||
expect(logFile).toEqual({
|
||||
path: path.join(paseoHome, "daemon.log"),
|
||||
rotate: { maxSize: "50m", maxFiles: 8 },
|
||||
});
|
||||
});
|
||||
|
||||
test("writes supervised worker stdout and stderr to daemon.log", async () => {
|
||||
const result = await runSupervisorFixture({
|
||||
workerSource: `
|
||||
|
||||
Reference in New Issue
Block a user