From d592b58b75d5e62f17e19433f2689551fbb673af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Sun, 23 Nov 2025 20:53:23 +0100 Subject: [PATCH] feat(logging): add comprehensive logging to all API routes (Phase 4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Applied withLogging() wrapper to all 24 API routes for consistent logging: Process Control Routes: - Start/stop/restart individual processes - Start-all/stop-all/restart-all batch operations Signal Routes: - Signal individual processes - Signal all processes - Signal process groups Group Management Routes: - Start/stop/restart process groups - Signal operations for groups Configuration Routes: - Get all configs (GET) - Reload configuration (POST) - Add/remove process groups (POST/DELETE) Log Routes: - Read main supervisord log - Read process stdout/stderr logs - Clear process logs (individual and all) System Routes: - Get system info - Get all processes info - Get individual process info - Send stdin to process All routes now include: - Request/response logging with timing - Automatic error handling and correlation IDs - X-Request-ID header propagation - Consistent metadata in responses Also fixed Next.js 16 deprecation: - Moved experimental.serverComponentsExternalPackages to serverExternalPackages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/api/supervisor/config/group/route.ts | 77 ++++++++----------- app/api/supervisor/config/reload/route.ts | 31 +++----- app/api/supervisor/config/route.ts | 22 ++---- app/api/supervisor/events/route.ts | 47 ++++++++++- .../supervisor/groups/[name]/restart/route.ts | 42 +++++----- .../supervisor/groups/[name]/signal/route.ts | 46 +++++------ .../supervisor/groups/[name]/start/route.ts | 36 ++++----- .../supervisor/groups/[name]/stop/route.ts | 36 ++++----- app/api/supervisor/logs/route.ts | 46 ++++------- .../supervisor/processes/[name]/logs/route.ts | 28 ++++--- .../processes/[name]/logs/stderr/route.ts | 28 +++---- .../processes/[name]/logs/stdout/route.ts | 28 +++---- .../processes/[name]/restart/route.ts | 27 ++++--- app/api/supervisor/processes/[name]/route.ts | 23 +++--- .../processes/[name]/signal/route.ts | 44 +++++------ .../processes/[name]/start/route.ts | 31 ++++---- .../processes/[name]/stdin/route.ts | 43 +++++------ .../supervisor/processes/[name]/stop/route.ts | 31 ++++---- .../processes/logs/clear-all/route.ts | 31 +++----- .../supervisor/processes/restart-all/route.ts | 39 ++++------ app/api/supervisor/processes/route.ts | 22 ++---- .../supervisor/processes/signal-all/route.ts | 43 +++++------ .../supervisor/processes/start-all/route.ts | 33 ++++---- .../supervisor/processes/stop-all/route.ts | 33 ++++---- app/api/supervisor/system/route.ts | 22 ++---- next.config.ts | 4 +- 26 files changed, 391 insertions(+), 502 deletions(-) diff --git a/app/api/supervisor/config/group/route.ts b/app/api/supervisor/config/group/route.ts index 67f028f..b5cae7a 100644 --- a/app/api/supervisor/config/group/route.ts +++ b/app/api/supervisor/config/group/route.ts @@ -1,60 +1,45 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; -// POST - Add a process group -export async function POST(request: NextRequest) { - try { - const body = await request.json(); - const { name } = body; +export const POST = withLogging(async (request: NextRequest) => { + const body = await request.json(); + const { name } = body; - if (!name) { - return NextResponse.json( - { error: 'Group name is required' }, - { status: 400 } - ); - } - - const client = createSupervisorClient(); - const result = await client.addProcessGroup(name); - - return NextResponse.json({ - success: result, - message: `Process group '${name}' added successfully`, - }); - } catch (error: any) { - console.error('Supervisor add process group error:', error); + if (!name) { return NextResponse.json( - { error: error.message || 'Failed to add process group' }, - { status: 500 } + { error: 'Group name is required' }, + { status: 400 } ); } -} -// DELETE - Remove a process group -export async function DELETE(request: NextRequest) { - try { - const body = await request.json(); - const { name } = body; + const client = createSupervisorClient(); + const result = await client.addProcessGroup(name); - if (!name) { - return NextResponse.json( - { error: 'Group name is required' }, - { status: 400 } - ); - } + return NextResponse.json({ + success: result, + message: `Process group '${name}' added successfully`, + groupName: name, + }); +}, 'addProcessGroup'); - const client = createSupervisorClient(); - const result = await client.removeProcessGroup(name); +export const DELETE = withLogging(async (request: NextRequest) => { + const body = await request.json(); + const { name } = body; - return NextResponse.json({ - success: result, - message: `Process group '${name}' removed successfully`, - }); - } catch (error: any) { - console.error('Supervisor remove process group error:', error); + if (!name) { return NextResponse.json( - { error: error.message || 'Failed to remove process group' }, - { status: 500 } + { error: 'Group name is required' }, + { status: 400 } ); } -} + + const client = createSupervisorClient(); + const result = await client.removeProcessGroup(name); + + return NextResponse.json({ + success: result, + message: `Process group '${name}' removed successfully`, + groupName: name, + }); +}, 'removeProcessGroup'); diff --git a/app/api/supervisor/config/reload/route.ts b/app/api/supervisor/config/reload/route.ts index 4ee3e39..b5a55bf 100644 --- a/app/api/supervisor/config/reload/route.ts +++ b/app/api/supervisor/config/reload/route.ts @@ -1,21 +1,14 @@ -import { NextResponse } from 'next/server'; +import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; -// POST - Reload configuration -export async function POST() { - try { - const client = createSupervisorClient(); - const result = await client.reloadConfig(); - return NextResponse.json({ - success: true, - message: 'Configuration reloaded', - result, - }); - } catch (error: any) { - console.error('Supervisor reload config error:', error); - return NextResponse.json( - { error: error.message || 'Failed to reload configuration' }, - { status: 500 } - ); - } -} +export const POST = withLogging(async (request: NextRequest) => { + const client = createSupervisorClient(); + const result = await client.reloadConfig(); + + return NextResponse.json({ + success: true, + message: 'Configuration reloaded', + result, + }); +}, 'reloadConfig'); diff --git a/app/api/supervisor/config/route.ts b/app/api/supervisor/config/route.ts index 70330ce..d0ab5cb 100644 --- a/app/api/supervisor/config/route.ts +++ b/app/api/supervisor/config/route.ts @@ -1,17 +1,9 @@ -import { NextResponse } from 'next/server'; +import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; -// GET - Get all process configurations -export async function GET() { - try { - const client = createSupervisorClient(); - const configs = await client.getAllConfigInfo(); - return NextResponse.json(configs); - } catch (error: any) { - console.error('Supervisor get config error:', error); - return NextResponse.json( - { error: error.message || 'Failed to fetch configuration' }, - { status: 500 } - ); - } -} +export const GET = withLogging(async (request: NextRequest) => { + const client = createSupervisorClient(); + const configs = await client.getAllConfigInfo(); + return NextResponse.json(configs); +}, 'getAllConfigInfo'); diff --git a/app/api/supervisor/events/route.ts b/app/api/supervisor/events/route.ts index 5b03545..2ddaa40 100644 --- a/app/api/supervisor/events/route.ts +++ b/app/api/supervisor/events/route.ts @@ -1,5 +1,7 @@ import { NextRequest } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { createApiLogger, generateRequestId } from '@/lib/utils/api-logger'; +import { formatError } from '@/lib/utils/logger'; export const dynamic = 'force-dynamic'; @@ -8,9 +10,16 @@ export const dynamic = 'force-dynamic'; * Polls supervisor every 2 seconds and sends state changes to clients */ export async function GET(request: NextRequest) { + const requestId = generateRequestId(); + const logger = createApiLogger(request, 'SSE-Events'); + const encoder = new TextEncoder(); let intervalId: NodeJS.Timeout | null = null; let previousState: string | null = null; + let pollCount = 0; + let stateChangeCount = 0; + + logger.info({ requestId }, 'SSE connection initiated'); const stream = new ReadableStream({ async start(controller) { @@ -22,9 +31,13 @@ export async function GET(request: NextRequest) { // Send initial connection message sendEvent('connected', { timestamp: Date.now() }); + logger.debug({ requestId }, 'SSE connected event sent'); // Poll supervisor for state changes const pollSupervisor = async () => { + pollCount++; + const pollStartTime = Date.now(); + try { const client = createSupervisorClient(); const processes = await client.getAllProcessInfo(); @@ -41,17 +54,40 @@ export async function GET(request: NextRequest) { // Send update if state changed if (currentState !== previousState) { + stateChangeCount++; sendEvent('process-update', { processes, timestamp: Date.now(), }); + logger.info({ + requestId, + pollCount, + stateChangeCount, + processCount: processes.length, + duration: Date.now() - pollStartTime, + }, `Process state change detected (change #${stateChangeCount})`); previousState = currentState; } - // Send heartbeat every poll + // Send heartbeat every poll (reduced logging - only log every 10th heartbeat) sendEvent('heartbeat', { timestamp: Date.now() }); + if (pollCount % 10 === 0) { + logger.debug({ + requestId, + pollCount, + stateChangeCount, + duration: Date.now() - pollStartTime, + }, `SSE heartbeat #${pollCount}`); + } } catch (error: any) { - console.error('SSE polling error:', error); + const errorInfo = formatError(error); + logger.error({ + requestId, + pollCount, + error: errorInfo, + duration: Date.now() - pollStartTime, + }, `SSE polling error: ${errorInfo.message}`); + sendEvent('error', { message: error.message || 'Failed to fetch process state', timestamp: Date.now(), @@ -70,6 +106,12 @@ export async function GET(request: NextRequest) { if (intervalId) { clearInterval(intervalId); } + logger.info({ + requestId, + pollCount, + stateChangeCount, + duration: Date.now() - Date.now(), + }, 'SSE connection closed'); }, }); @@ -79,6 +121,7 @@ export async function GET(request: NextRequest) { 'Cache-Control': 'no-cache, no-transform', 'Connection': 'keep-alive', 'X-Accel-Buffering': 'no', // Disable nginx buffering + 'X-Request-ID': requestId, }, }); } diff --git a/app/api/supervisor/groups/[name]/restart/route.ts b/app/api/supervisor/groups/[name]/restart/route.ts index fc8ca02..6cd55a8 100644 --- a/app/api/supervisor/groups/[name]/restart/route.ts +++ b/app/api/supervisor/groups/[name]/restart/route.ts @@ -1,35 +1,29 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; interface RouteParams { params: Promise<{ name: string }>; } -// POST - Restart all processes in a group (stop then start) -export async function POST(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const body = await request.json().catch(() => ({})); - const wait = body.wait ?? true; +export const POST = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + const body = await request.json().catch(() => ({})); + const wait = body.wait ?? true; - const client = createSupervisorClient(); + const client = createSupervisorClient(); - // Stop all processes in the group first - await client.stopProcessGroup(name, wait); + // Stop all processes in the group first + await client.stopProcessGroup(name, wait); - // Then start them - const results = await client.startProcessGroup(name, wait); + // Then start them + const results = await client.startProcessGroup(name, wait); - return NextResponse.json({ - success: true, - message: `Restarted process group: ${name}`, - results, - }); - } catch (error: any) { - console.error('Supervisor restart process group error:', error); - return NextResponse.json( - { error: error.message || 'Failed to restart process group' }, - { status: 500 } - ); - } -} + return NextResponse.json({ + success: true, + message: `Restarted process group: ${name}`, + results, + groupName: name, + wait, + }); +}, 'restartProcessGroup'); diff --git a/app/api/supervisor/groups/[name]/signal/route.ts b/app/api/supervisor/groups/[name]/signal/route.ts index f208aec..fe88c93 100644 --- a/app/api/supervisor/groups/[name]/signal/route.ts +++ b/app/api/supervisor/groups/[name]/signal/route.ts @@ -1,37 +1,31 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; interface RouteParams { params: Promise<{ name: string }>; } -// POST - Send signal to all processes in a group -export async function POST(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const body = await request.json(); - const { signal } = body; +export const POST = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + const body = await request.json(); + const { signal } = body; - if (!signal) { - return NextResponse.json( - { error: 'Signal is required' }, - { status: 400 } - ); - } - - const client = createSupervisorClient(); - const results = await client.signalProcessGroup(name, signal); - - return NextResponse.json({ - success: true, - message: `Signal ${signal} sent to group ${name}`, - results, - }); - } catch (error: any) { - console.error('Supervisor signal process group error:', error); + if (!signal) { return NextResponse.json( - { error: error.message || 'Failed to send signal to process group' }, - { status: 500 } + { error: 'Signal is required' }, + { status: 400 } ); } -} + + const client = createSupervisorClient(); + const results = await client.signalProcessGroup(name, signal); + + return NextResponse.json({ + success: true, + message: `Signal ${signal} sent to group ${name}`, + results, + groupName: name, + signal, + }); +}, 'signalProcessGroup'); diff --git a/app/api/supervisor/groups/[name]/start/route.ts b/app/api/supervisor/groups/[name]/start/route.ts index f43475a..091b5f9 100644 --- a/app/api/supervisor/groups/[name]/start/route.ts +++ b/app/api/supervisor/groups/[name]/start/route.ts @@ -1,30 +1,24 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; interface RouteParams { params: Promise<{ name: string }>; } -// POST - Start all processes in a group -export async function POST(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const body = await request.json().catch(() => ({})); - const wait = body.wait ?? true; +export const POST = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + const body = await request.json().catch(() => ({})); + const wait = body.wait ?? true; - const client = createSupervisorClient(); - const results = await client.startProcessGroup(name, wait); + const client = createSupervisorClient(); + const results = await client.startProcessGroup(name, wait); - return NextResponse.json({ - success: true, - message: `Started process group: ${name}`, - results, - }); - } catch (error: any) { - console.error('Supervisor start process group error:', error); - return NextResponse.json( - { error: error.message || 'Failed to start process group' }, - { status: 500 } - ); - } -} + return NextResponse.json({ + success: true, + message: `Started process group: ${name}`, + results, + groupName: name, + wait, + }); +}, 'startProcessGroup'); diff --git a/app/api/supervisor/groups/[name]/stop/route.ts b/app/api/supervisor/groups/[name]/stop/route.ts index 50069b5..8acc59d 100644 --- a/app/api/supervisor/groups/[name]/stop/route.ts +++ b/app/api/supervisor/groups/[name]/stop/route.ts @@ -1,30 +1,24 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; interface RouteParams { params: Promise<{ name: string }>; } -// POST - Stop all processes in a group -export async function POST(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const body = await request.json().catch(() => ({})); - const wait = body.wait ?? true; +export const POST = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + const body = await request.json().catch(() => ({})); + const wait = body.wait ?? true; - const client = createSupervisorClient(); - const results = await client.stopProcessGroup(name, wait); + const client = createSupervisorClient(); + const results = await client.stopProcessGroup(name, wait); - return NextResponse.json({ - success: true, - message: `Stopped process group: ${name}`, - results, - }); - } catch (error: any) { - console.error('Supervisor stop process group error:', error); - return NextResponse.json( - { error: error.message || 'Failed to stop process group' }, - { status: 500 } - ); - } -} + return NextResponse.json({ + success: true, + message: `Stopped process group: ${name}`, + results, + groupName: name, + wait, + }); +}, 'stopProcessGroup'); diff --git a/app/api/supervisor/logs/route.ts b/app/api/supervisor/logs/route.ts index 90decab..c5cc315 100644 --- a/app/api/supervisor/logs/route.ts +++ b/app/api/supervisor/logs/route.ts @@ -1,39 +1,23 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; export const dynamic = 'force-dynamic'; -// GET main supervisord log -export async function GET(request: NextRequest) { - try { - const searchParams = request.nextUrl.searchParams; - const offset = parseInt(searchParams.get('offset') || '-4096', 10); - const length = parseInt(searchParams.get('length') || '4096', 10); +export const GET = withLogging(async (request: NextRequest) => { + const searchParams = request.nextUrl.searchParams; + const offset = parseInt(searchParams.get('offset') || '-4096', 10); + const length = parseInt(searchParams.get('length') || '4096', 10); - const client = createSupervisorClient(); - const logs = await client.readLog(offset, length); + const client = createSupervisorClient(); + const logs = await client.readLog(offset, length); - return NextResponse.json({ logs, offset, length }); - } catch (error: any) { - console.error('Supervisor main log error:', error); - return NextResponse.json( - { error: error.message || 'Failed to fetch main log' }, - { status: 500 } - ); - } -} + return NextResponse.json({ logs, offset, length }); +}, 'readMainLog'); -// DELETE - Clear main supervisord log -export async function DELETE() { - try { - const client = createSupervisorClient(); - const result = await client.clearLog(); - return NextResponse.json({ success: result, message: 'Main log cleared' }); - } catch (error: any) { - console.error('Supervisor clear main log error:', error); - return NextResponse.json( - { error: error.message || 'Failed to clear main log' }, - { status: 500 } - ); - } -} +export const DELETE = withLogging(async (request: NextRequest) => { + const client = createSupervisorClient(); + const result = await client.clearLog(); + + return NextResponse.json({ success: result, message: 'Main log cleared' }); +}, 'clearMainLog'); diff --git a/app/api/supervisor/processes/[name]/logs/route.ts b/app/api/supervisor/processes/[name]/logs/route.ts index 5b9e518..3d22e64 100644 --- a/app/api/supervisor/processes/[name]/logs/route.ts +++ b/app/api/supervisor/processes/[name]/logs/route.ts @@ -1,22 +1,20 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; interface RouteParams { params: Promise<{ name: string }>; } -// DELETE - Clear process logs (both stdout and stderr) -export async function DELETE(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const client = createSupervisorClient(); - const result = await client.clearProcessLogs(name); - return NextResponse.json({ success: result, message: `Logs cleared for ${name}` }); - } catch (error: any) { - console.error('Supervisor clear process logs error:', error); - return NextResponse.json( - { error: error.message || 'Failed to clear process logs' }, - { status: 500 } - ); - } -} +export const DELETE = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + + const client = createSupervisorClient(); + const result = await client.clearProcessLogs(name); + + return NextResponse.json({ + success: result, + message: `Logs cleared for ${name}`, + processName: name, + }); +}, 'clearProcessLogs'); diff --git a/app/api/supervisor/processes/[name]/logs/stderr/route.ts b/app/api/supervisor/processes/[name]/logs/stderr/route.ts index 2abc187..b069817 100644 --- a/app/api/supervisor/processes/[name]/logs/stderr/route.ts +++ b/app/api/supervisor/processes/[name]/logs/stderr/route.ts @@ -1,5 +1,6 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; export const dynamic = 'force-dynamic'; @@ -7,21 +8,14 @@ interface RouteParams { params: Promise<{ name: string }>; } -export async function GET(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const searchParams = request.nextUrl.searchParams; - const offset = parseInt(searchParams.get('offset') || '-4096', 10); - const length = parseInt(searchParams.get('length') || '4096', 10); +export const GET = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + const searchParams = request.nextUrl.searchParams; + const offset = parseInt(searchParams.get('offset') || '-4096', 10); + const length = parseInt(searchParams.get('length') || '4096', 10); - const client = createSupervisorClient(); - const logs = await client.tailProcessStderrLog(name, offset, length); - return NextResponse.json(logs); - } catch (error: any) { - console.error('Supervisor stderr log error:', error); - return NextResponse.json( - { error: error.message || 'Failed to fetch stderr logs' }, - { status: 500 } - ); - } -} + const client = createSupervisorClient(); + const logs = await client.tailProcessStderrLog(name, offset, length); + + return NextResponse.json(logs); +}, 'readProcessStderr'); diff --git a/app/api/supervisor/processes/[name]/logs/stdout/route.ts b/app/api/supervisor/processes/[name]/logs/stdout/route.ts index e8a73f4..3ff7a2c 100644 --- a/app/api/supervisor/processes/[name]/logs/stdout/route.ts +++ b/app/api/supervisor/processes/[name]/logs/stdout/route.ts @@ -1,5 +1,6 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; export const dynamic = 'force-dynamic'; @@ -7,21 +8,14 @@ interface RouteParams { params: Promise<{ name: string }>; } -export async function GET(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const searchParams = request.nextUrl.searchParams; - const offset = parseInt(searchParams.get('offset') || '-4096', 10); - const length = parseInt(searchParams.get('length') || '4096', 10); +export const GET = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + const searchParams = request.nextUrl.searchParams; + const offset = parseInt(searchParams.get('offset') || '-4096', 10); + const length = parseInt(searchParams.get('length') || '4096', 10); - const client = createSupervisorClient(); - const logs = await client.tailProcessStdoutLog(name, offset, length); - return NextResponse.json(logs); - } catch (error: any) { - console.error('Supervisor stdout log error:', error); - return NextResponse.json( - { error: error.message || 'Failed to fetch stdout logs' }, - { status: 500 } - ); - } -} + const client = createSupervisorClient(); + const logs = await client.tailProcessStdoutLog(name, offset, length); + + return NextResponse.json(logs); +}, 'readProcessStdout'); diff --git a/app/api/supervisor/processes/[name]/restart/route.ts b/app/api/supervisor/processes/[name]/restart/route.ts index 9d2299f..749144b 100644 --- a/app/api/supervisor/processes/[name]/restart/route.ts +++ b/app/api/supervisor/processes/[name]/restart/route.ts @@ -1,21 +1,20 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; interface RouteParams { params: Promise<{ name: string }>; } -export async function POST(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const client = createSupervisorClient(); - const result = await client.restartProcess(name); - return NextResponse.json({ success: result, message: `Process ${name} restarted` }); - } catch (error: any) { - console.error('Supervisor restart process error:', error); - return NextResponse.json( - { error: error.message || 'Failed to restart process' }, - { status: 500 } - ); - } -} +export const POST = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + + const client = createSupervisorClient(); + const result = await client.restartProcess(name); + + return NextResponse.json({ + success: result, + message: `Process ${name} restarted`, + processName: name, + }); +}, 'restartProcess'); diff --git a/app/api/supervisor/processes/[name]/route.ts b/app/api/supervisor/processes/[name]/route.ts index 510efbc..7874f17 100644 --- a/app/api/supervisor/processes/[name]/route.ts +++ b/app/api/supervisor/processes/[name]/route.ts @@ -1,5 +1,6 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; export const dynamic = 'force-dynamic'; @@ -7,17 +8,11 @@ interface RouteParams { params: Promise<{ name: string }>; } -export async function GET(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const client = createSupervisorClient(); - const processInfo = await client.getProcessInfo(name); - return NextResponse.json(processInfo); - } catch (error: any) { - console.error('Supervisor process info error:', error); - return NextResponse.json( - { error: error.message || 'Failed to fetch process info' }, - { status: 500 } - ); - } -} +export const GET = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + + const client = createSupervisorClient(); + const processInfo = await client.getProcessInfo(name); + + return NextResponse.json(processInfo); +}, 'getProcessInfo'); diff --git a/app/api/supervisor/processes/[name]/signal/route.ts b/app/api/supervisor/processes/[name]/signal/route.ts index 5e41c15..1bbe501 100644 --- a/app/api/supervisor/processes/[name]/signal/route.ts +++ b/app/api/supervisor/processes/[name]/signal/route.ts @@ -1,36 +1,30 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; interface RouteParams { params: Promise<{ name: string }>; } -// POST - Send signal to a process -export async function POST(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const body = await request.json(); - const { signal } = body; +export const POST = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + const body = await request.json(); + const { signal } = body; - if (!signal) { - return NextResponse.json( - { error: 'Signal is required' }, - { status: 400 } - ); - } - - const client = createSupervisorClient(); - const result = await client.signalProcess(name, signal); - - return NextResponse.json({ - success: result, - message: `Signal ${signal} sent to ${name}`, - }); - } catch (error: any) { - console.error('Supervisor signal process error:', error); + if (!signal) { return NextResponse.json( - { error: error.message || 'Failed to send signal to process' }, - { status: 500 } + { error: 'Signal is required' }, + { status: 400 } ); } -} + + const client = createSupervisorClient(); + const result = await client.signalProcess(name, signal); + + return NextResponse.json({ + success: result, + message: `Signal ${signal} sent to ${name}`, + processName: name, + signal, + }); +}, 'signalProcess'); diff --git a/app/api/supervisor/processes/[name]/start/route.ts b/app/api/supervisor/processes/[name]/start/route.ts index 7dc367e..26821c5 100644 --- a/app/api/supervisor/processes/[name]/start/route.ts +++ b/app/api/supervisor/processes/[name]/start/route.ts @@ -1,24 +1,23 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; interface RouteParams { params: Promise<{ name: string }>; } -export async function POST(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const body = await request.json().catch(() => ({})); - const wait = body.wait !== undefined ? body.wait : true; +export const POST = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + const body = await request.json().catch(() => ({})); + const wait = body.wait !== undefined ? body.wait : true; - const client = createSupervisorClient(); - const result = await client.startProcess(name, wait); - return NextResponse.json({ success: result, message: `Process ${name} started` }); - } catch (error: any) { - console.error('Supervisor start process error:', error); - return NextResponse.json( - { error: error.message || 'Failed to start process' }, - { status: 500 } - ); - } -} + const client = createSupervisorClient(); + const result = await client.startProcess(name, wait); + + return NextResponse.json({ + success: result, + message: `Process ${name} started`, + processName: name, + wait, + }); +}, 'startProcess'); diff --git a/app/api/supervisor/processes/[name]/stdin/route.ts b/app/api/supervisor/processes/[name]/stdin/route.ts index 6901c35..22a5018 100644 --- a/app/api/supervisor/processes/[name]/stdin/route.ts +++ b/app/api/supervisor/processes/[name]/stdin/route.ts @@ -1,36 +1,29 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; interface RouteParams { params: Promise<{ name: string }>; } -// POST - Send input to process stdin -export async function POST(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const body = await request.json(); - const { chars } = body; +export const POST = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + const body = await request.json(); + const { chars } = body; - if (chars === undefined || chars === null) { - return NextResponse.json( - { error: 'Input characters are required' }, - { status: 400 } - ); - } - - const client = createSupervisorClient(); - const result = await client.sendProcessStdin(name, chars); - - return NextResponse.json({ - success: result, - message: `Input sent to ${name}`, - }); - } catch (error: any) { - console.error('Supervisor send stdin error:', error); + if (chars === undefined || chars === null) { return NextResponse.json( - { error: error.message || 'Failed to send input to process' }, - { status: 500 } + { error: 'Input characters are required' }, + { status: 400 } ); } -} + + const client = createSupervisorClient(); + const result = await client.sendProcessStdin(name, chars); + + return NextResponse.json({ + success: result, + message: `Input sent to ${name}`, + processName: name, + }); +}, 'sendProcessStdin'); diff --git a/app/api/supervisor/processes/[name]/stop/route.ts b/app/api/supervisor/processes/[name]/stop/route.ts index 10c6540..2ef282f 100644 --- a/app/api/supervisor/processes/[name]/stop/route.ts +++ b/app/api/supervisor/processes/[name]/stop/route.ts @@ -1,24 +1,23 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; interface RouteParams { params: Promise<{ name: string }>; } -export async function POST(request: NextRequest, { params }: RouteParams) { - try { - const { name } = await params; - const body = await request.json().catch(() => ({})); - const wait = body.wait !== undefined ? body.wait : true; +export const POST = withLogging(async (request: NextRequest, { params }: RouteParams) => { + const { name } = await params; + const body = await request.json().catch(() => ({})); + const wait = body.wait !== undefined ? body.wait : true; - const client = createSupervisorClient(); - const result = await client.stopProcess(name, wait); - return NextResponse.json({ success: result, message: `Process ${name} stopped` }); - } catch (error: any) { - console.error('Supervisor stop process error:', error); - return NextResponse.json( - { error: error.message || 'Failed to stop process' }, - { status: 500 } - ); - } -} + const client = createSupervisorClient(); + const result = await client.stopProcess(name, wait); + + return NextResponse.json({ + success: result, + message: `Process ${name} stopped`, + processName: name, + wait, + }); +}, 'stopProcess'); diff --git a/app/api/supervisor/processes/logs/clear-all/route.ts b/app/api/supervisor/processes/logs/clear-all/route.ts index 42ad5ed..ecd62f9 100644 --- a/app/api/supervisor/processes/logs/clear-all/route.ts +++ b/app/api/supervisor/processes/logs/clear-all/route.ts @@ -1,21 +1,14 @@ -import { NextResponse } from 'next/server'; +import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; -// POST - Clear all process logs -export async function POST() { - try { - const client = createSupervisorClient(); - const results = await client.clearAllProcessLogs(); - return NextResponse.json({ - success: true, - message: 'All process logs cleared', - results - }); - } catch (error: any) { - console.error('Supervisor clear all logs error:', error); - return NextResponse.json( - { error: error.message || 'Failed to clear all logs' }, - { status: 500 } - ); - } -} +export const POST = withLogging(async (request: NextRequest) => { + const client = createSupervisorClient(); + const results = await client.clearAllProcessLogs(); + + return NextResponse.json({ + success: true, + message: 'All process logs cleared', + results, + }); +}, 'clearAllProcessLogs'); diff --git a/app/api/supervisor/processes/restart-all/route.ts b/app/api/supervisor/processes/restart-all/route.ts index 7f1d031..75dc103 100644 --- a/app/api/supervisor/processes/restart-all/route.ts +++ b/app/api/supervisor/processes/restart-all/route.ts @@ -1,30 +1,23 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; -// POST - Restart all processes (stop then start) -export async function POST(request: NextRequest) { - try { - const body = await request.json().catch(() => ({})); - const wait = body.wait ?? true; +export const POST = withLogging(async (request: NextRequest) => { + const body = await request.json().catch(() => ({})); + const wait = body.wait ?? true; - const client = createSupervisorClient(); + const client = createSupervisorClient(); - // Stop all processes first - await client.stopAllProcesses(wait); + // Stop all processes first + await client.stopAllProcesses(wait); - // Then start them - const results = await client.startAllProcesses(wait); + // Then start them + const results = await client.startAllProcesses(wait); - return NextResponse.json({ - success: true, - message: 'Restarted all processes', - results, - }); - } catch (error: any) { - console.error('Supervisor restart all processes error:', error); - return NextResponse.json( - { error: error.message || 'Failed to restart all processes' }, - { status: 500 } - ); - } -} + return NextResponse.json({ + success: true, + message: 'Restarted all processes', + results, + wait, + }); +}, 'restartAllProcesses'); diff --git a/app/api/supervisor/processes/route.ts b/app/api/supervisor/processes/route.ts index a60c797..9087ccf 100644 --- a/app/api/supervisor/processes/route.ts +++ b/app/api/supervisor/processes/route.ts @@ -1,18 +1,12 @@ -import { NextResponse } from 'next/server'; +import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; export const dynamic = 'force-dynamic'; -export async function GET() { - try { - const client = createSupervisorClient(); - const processes = await client.getAllProcessInfo(); - return NextResponse.json(processes); - } catch (error: any) { - console.error('Supervisor processes error:', error); - return NextResponse.json( - { error: error.message || 'Failed to fetch processes' }, - { status: 500 } - ); - } -} +export const GET = withLogging(async (request: NextRequest) => { + const client = createSupervisorClient(); + const processes = await client.getAllProcessInfo(); + + return NextResponse.json(processes); +}, 'getAllProcessInfo'); diff --git a/app/api/supervisor/processes/signal-all/route.ts b/app/api/supervisor/processes/signal-all/route.ts index 914b32a..fea0342 100644 --- a/app/api/supervisor/processes/signal-all/route.ts +++ b/app/api/supervisor/processes/signal-all/route.ts @@ -1,32 +1,25 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; -// POST - Send signal to all processes -export async function POST(request: NextRequest) { - try { - const body = await request.json(); - const { signal } = body; +export const POST = withLogging(async (request: NextRequest) => { + const body = await request.json(); + const { signal } = body; - if (!signal) { - return NextResponse.json( - { error: 'Signal is required' }, - { status: 400 } - ); - } - - const client = createSupervisorClient(); - const results = await client.signalAllProcesses(signal); - - return NextResponse.json({ - success: true, - message: `Signal ${signal} sent to all processes`, - results, - }); - } catch (error: any) { - console.error('Supervisor signal all processes error:', error); + if (!signal) { return NextResponse.json( - { error: error.message || 'Failed to send signal to all processes' }, - { status: 500 } + { error: 'Signal is required' }, + { status: 400 } ); } -} + + const client = createSupervisorClient(); + const results = await client.signalAllProcesses(signal); + + return NextResponse.json({ + success: true, + message: `Signal ${signal} sent to all processes`, + results, + signal, + }); +}, 'signalAllProcesses'); diff --git a/app/api/supervisor/processes/start-all/route.ts b/app/api/supervisor/processes/start-all/route.ts index 40dbb8c..30b2bab 100644 --- a/app/api/supervisor/processes/start-all/route.ts +++ b/app/api/supervisor/processes/start-all/route.ts @@ -1,25 +1,18 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; -// POST - Start all processes -export async function POST(request: NextRequest) { - try { - const body = await request.json().catch(() => ({})); - const wait = body.wait ?? true; +export const POST = withLogging(async (request: NextRequest) => { + const body = await request.json().catch(() => ({})); + const wait = body.wait ?? true; - const client = createSupervisorClient(); - const results = await client.startAllProcesses(wait); + const client = createSupervisorClient(); + const results = await client.startAllProcesses(wait); - return NextResponse.json({ - success: true, - message: 'Started all processes', - results, - }); - } catch (error: any) { - console.error('Supervisor start all processes error:', error); - return NextResponse.json( - { error: error.message || 'Failed to start all processes' }, - { status: 500 } - ); - } -} + return NextResponse.json({ + success: true, + message: 'Started all processes', + results, + wait, + }); +}, 'startAllProcesses'); diff --git a/app/api/supervisor/processes/stop-all/route.ts b/app/api/supervisor/processes/stop-all/route.ts index 6291f49..d2d99be 100644 --- a/app/api/supervisor/processes/stop-all/route.ts +++ b/app/api/supervisor/processes/stop-all/route.ts @@ -1,25 +1,18 @@ import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; -// POST - Stop all processes -export async function POST(request: NextRequest) { - try { - const body = await request.json().catch(() => ({})); - const wait = body.wait ?? true; +export const POST = withLogging(async (request: NextRequest) => { + const body = await request.json().catch(() => ({})); + const wait = body.wait ?? true; - const client = createSupervisorClient(); - const results = await client.stopAllProcesses(wait); + const client = createSupervisorClient(); + const results = await client.stopAllProcesses(wait); - return NextResponse.json({ - success: true, - message: 'Stopped all processes', - results, - }); - } catch (error: any) { - console.error('Supervisor stop all processes error:', error); - return NextResponse.json( - { error: error.message || 'Failed to stop all processes' }, - { status: 500 } - ); - } -} + return NextResponse.json({ + success: true, + message: 'Stopped all processes', + results, + wait, + }); +}, 'stopAllProcesses'); diff --git a/app/api/supervisor/system/route.ts b/app/api/supervisor/system/route.ts index 976193f..0e6ec6f 100644 --- a/app/api/supervisor/system/route.ts +++ b/app/api/supervisor/system/route.ts @@ -1,18 +1,12 @@ -import { NextResponse } from 'next/server'; +import { NextRequest, NextResponse } from 'next/server'; import { createSupervisorClient } from '@/lib/supervisor/client'; +import { withLogging } from '@/lib/utils/api-logger'; export const dynamic = 'force-dynamic'; -export async function GET() { - try { - const client = createSupervisorClient(); - const systemInfo = await client.getSystemInfo(); - return NextResponse.json(systemInfo); - } catch (error: any) { - console.error('Supervisor system info error:', error); - return NextResponse.json( - { error: error.message || 'Failed to fetch system info' }, - { status: 500 } - ); - } -} +export const GET = withLogging(async (request: NextRequest) => { + const client = createSupervisorClient(); + const systemInfo = await client.getSystemInfo(); + + return NextResponse.json(systemInfo); +}, 'getSystemInfo'); diff --git a/next.config.ts b/next.config.ts index 9b7cdcd..3970958 100644 --- a/next.config.ts +++ b/next.config.ts @@ -5,9 +5,7 @@ const nextConfig: NextConfig = { output: 'standalone', // Turbopack configuration (Next.js 16+) turbopack: {}, - experimental: { - serverComponentsExternalPackages: ['pino', 'pino-pretty'], - }, + serverExternalPackages: ['pino', 'pino-pretty'], }; export default nextConfig;