add structured logging with timestamps for docker/unraid log viewer
Build and Push Docker Image / build (push) Successful in 15s
Build and Push Docker Image / build (push) Successful in 15s
all server output now prefixed with ISO timestamp and level [INFO/WARN/ERROR]. logs requests, scan start/complete, job lifecycle, errors. skips noisy SSE endpoints. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { execStream } from '../services/ssh';
|
||||
import type { Job, Node, MediaItem, MediaStream } from '../types';
|
||||
import { predictExtractedFiles } from '../services/ffmpeg';
|
||||
import { accessSync, constants } from 'node:fs';
|
||||
import { log, error as logError } from '../lib/log';
|
||||
|
||||
const app = new Hono();
|
||||
|
||||
@@ -73,7 +74,7 @@ app.get('/', (c) => {
|
||||
app.post('/start', (c) => {
|
||||
const db = getDb();
|
||||
const pending = db.prepare("SELECT * FROM jobs WHERE status = 'pending' ORDER BY created_at").all() as Job[];
|
||||
for (const job of pending) runJob(job).catch((err) => console.error(`Job ${job.id} failed:`, err));
|
||||
for (const job of pending) runJob(job).catch((err) => logError(`Job ${job.id} failed:`, err));
|
||||
return c.json({ ok: true, started: pending.length });
|
||||
});
|
||||
|
||||
@@ -100,7 +101,7 @@ app.post('/job/:id/run', async (c) => {
|
||||
if (!result) return c.notFound();
|
||||
return c.json(result);
|
||||
}
|
||||
runJob(job).catch((err) => console.error(`Job ${job.id} failed:`, err));
|
||||
runJob(job).catch((err) => logError(`Job ${job.id} failed:`, err));
|
||||
const result = loadJobRow(jobId);
|
||||
if (!result) return c.notFound();
|
||||
return c.json(result);
|
||||
@@ -168,6 +169,7 @@ app.get('/events', (c) => {
|
||||
// ─── Job execution ────────────────────────────────────────────────────────────
|
||||
|
||||
async function runJob(job: Job): Promise<void> {
|
||||
log(`Job ${job.id} starting (item=${job.item_id}${job.node_id ? `, node=${job.node_id}` : ', local'})`);
|
||||
const db = getDb();
|
||||
|
||||
if (!job.node_id) {
|
||||
@@ -227,6 +229,7 @@ async function runJob(job: Job): Promise<void> {
|
||||
|
||||
const fullOutput = outputLines.join('\n');
|
||||
db.prepare("UPDATE jobs SET status = 'done', exit_code = 0, output = ?, completed_at = datetime('now') WHERE id = ?").run(fullOutput, job.id);
|
||||
log(`Job ${job.id} completed successfully`);
|
||||
emitJobUpdate(job.id, 'done', fullOutput);
|
||||
db.prepare("UPDATE review_plans SET status = 'done' WHERE item_id = ?").run(job.item_id);
|
||||
|
||||
@@ -242,8 +245,9 @@ async function runJob(job: Job): Promise<void> {
|
||||
}
|
||||
db.prepare('UPDATE review_plans SET subs_extracted = 1 WHERE item_id = ?').run(job.item_id);
|
||||
}
|
||||
} catch (subErr) { console.error('Failed to record extracted subtitle files:', subErr); }
|
||||
} catch (subErr) { logError('Failed to record extracted subtitle files:', subErr); }
|
||||
} catch (err) {
|
||||
logError(`Job ${job.id} failed:`, err);
|
||||
const fullOutput = outputLines.join('\n') + '\n' + String(err);
|
||||
db.prepare("UPDATE jobs SET status = 'error', exit_code = 1, output = ?, completed_at = datetime('now') WHERE id = ?").run(fullOutput, job.id);
|
||||
emitJobUpdate(job.id, 'error', fullOutput);
|
||||
|
||||
Reference in New Issue
Block a user