feat: add structured logging to reel API and pipeline
Browse files- Log webhook delivery attempts and responses in `app/api/reel/route.ts`
- Log incoming POST requests, auth rejections, and accepted jobs
- Centralize pipeline progress logging in `lib/progress.ts` via `setProgress`
These logs improve observability for debugging and monitoring without scattering log statements throughout the pipeline.
- app/api/reel/route.ts +8 -1
- lib/progress.ts +5 -0
app/api/reel/route.ts
CHANGED
|
@@ -12,12 +12,14 @@ export const runtime = "nodejs";
|
|
| 12 |
export const maxDuration = 300;
|
| 13 |
|
| 14 |
async function notifyWebhook(webhook: string, payload: Record<string, unknown>) {
|
|
|
|
| 15 |
try {
|
| 16 |
-
await fetch(webhook, {
|
| 17 |
method: "POST",
|
| 18 |
headers: { "Content-Type": "application/json" },
|
| 19 |
body: JSON.stringify(payload),
|
| 20 |
});
|
|
|
|
| 21 |
} catch (error) {
|
| 22 |
// ponytail: webhook host down = nothing left to notify; log and move on
|
| 23 |
console.error("Webhook delivery failed:", error);
|
|
@@ -82,9 +84,12 @@ async function runFullPipeline(
|
|
| 82 |
|
| 83 |
export async function POST(req: NextRequest) {
|
| 84 |
try {
|
|
|
|
|
|
|
| 85 |
// ponytail: gate before parsing the body — unauthenticated callers get no work done
|
| 86 |
const authError = checkApiKey(req);
|
| 87 |
if (authError) {
|
|
|
|
| 88 |
return NextResponse.json({ error: authError }, { status: 401 });
|
| 89 |
}
|
| 90 |
|
|
@@ -126,6 +131,8 @@ export async function POST(req: NextRequest) {
|
|
| 126 |
: undefined,
|
| 127 |
};
|
| 128 |
|
|
|
|
|
|
|
| 129 |
// fire-and-forget; the webhook is the completion signal
|
| 130 |
void runFullPipeline(url, id, webhook, baseUrl, provided);
|
| 131 |
|
|
|
|
| 12 |
export const maxDuration = 300;
|
| 13 |
|
| 14 |
async function notifyWebhook(webhook: string, payload: Record<string, unknown>) {
|
| 15 |
+
console.log(`[reel] POST webhook ${webhook}\n${JSON.stringify(payload, null, 2)}`);
|
| 16 |
try {
|
| 17 |
+
const res = await fetch(webhook, {
|
| 18 |
method: "POST",
|
| 19 |
headers: { "Content-Type": "application/json" },
|
| 20 |
body: JSON.stringify(payload),
|
| 21 |
});
|
| 22 |
+
console.log(`[reel] webhook responded ${res.status} ${res.statusText}`);
|
| 23 |
} catch (error) {
|
| 24 |
// ponytail: webhook host down = nothing left to notify; log and move on
|
| 25 |
console.error("Webhook delivery failed:", error);
|
|
|
|
| 84 |
|
| 85 |
export async function POST(req: NextRequest) {
|
| 86 |
try {
|
| 87 |
+
console.log(`[reel] POST /api/reel hit`);
|
| 88 |
+
|
| 89 |
// ponytail: gate before parsing the body — unauthenticated callers get no work done
|
| 90 |
const authError = checkApiKey(req);
|
| 91 |
if (authError) {
|
| 92 |
+
console.log(`[reel] rejected: ${authError}`);
|
| 93 |
return NextResponse.json({ error: authError }, { status: 401 });
|
| 94 |
}
|
| 95 |
|
|
|
|
| 131 |
: undefined,
|
| 132 |
};
|
| 133 |
|
| 134 |
+
console.log(`[reel ${id.slice(0, 8)}] accepted ${url} -> webhook ${webhook}`);
|
| 135 |
+
|
| 136 |
// fire-and-forget; the webhook is the completion signal
|
| 137 |
void runFullPipeline(url, id, webhook, baseUrl, provided);
|
| 138 |
|
lib/progress.ts
CHANGED
|
@@ -4,6 +4,11 @@ const progressMap = new Map<string, RenderProgress>();
|
|
| 4 |
|
| 5 |
export function setProgress(id: string, progress: RenderProgress) {
|
| 6 |
progressMap.set(id, progress);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
}
|
| 8 |
|
| 9 |
export function getProgress(id: string): RenderProgress | null {
|
|
|
|
| 4 |
|
| 5 |
export function setProgress(id: string, progress: RenderProgress) {
|
| 6 |
progressMap.set(id, progress);
|
| 7 |
+
// ponytail: every pipeline stage already routes through here, so one line here
|
| 8 |
+
// logs the whole run instead of scattering console.log across the pipeline
|
| 9 |
+
console.log(
|
| 10 |
+
`[reel ${id.slice(0, 8)}] ${progress.percent}% ${progress.stage} — ${progress.message}`,
|
| 11 |
+
);
|
| 12 |
}
|
| 13 |
|
| 14 |
export function getProgress(id: string): RenderProgress | null {
|