chore: harden world labs task logging

This commit is contained in:
Your Name 2026-05-27 11:10:23 +08:00
parent f4214bf3a9
commit e211e41c25
3 changed files with 30 additions and 19 deletions

View File

@ -5,6 +5,7 @@ import { db } from "@/lib/db";
import { model3dAsset } from "@/lib/db/schema";
import { resolveThreeDModelAliasId } from "@/lib/model3d/model-alias-config";
import { getThreeDModelAliasConfigForRuntime } from "@/lib/model3d/model-alias-config-server";
import { createLogger } from "@/lib/observability/logger";
import { uploadFile } from "@/lib/storage/service";
import { WorldLabsApiError, worldLabsRequest } from "@/lib/worldlabs/client";
import { getWorldLabsProviderConfig } from "@/lib/worldlabs/server";
@ -17,6 +18,8 @@ import type {
export const runtime = "nodejs";
export const maxDuration = 120;
const logger = createLogger("world-labs-task-status");
type ArchiveCacheItem = {
sourceUrl: string;
archivedUrl: string;
@ -209,7 +212,7 @@ async function archiveRemoteAssetIfNeeded(params: {
const contentType = upstream.headers.get("content-type");
if (params.skipHtml && /\btext\/html\b/i.test(String(contentType || ""))) {
console.warn("[WorldLabsArchive] skip html viewer url", {
logger.warn("archive skipped html viewer", {
cacheKey: params.cacheKey,
sourceUrl,
});
@ -236,10 +239,10 @@ async function archiveRemoteAssetIfNeeded(params: {
});
return uploaded.url;
} catch (error) {
console.error("[WorldLabsArchive] failed", {
logger.warn("archive failed", {
cacheKey: params.cacheKey,
sourceUrl,
error: error instanceof Error ? error.message : String(error),
error,
});
return null;
} finally {
@ -477,9 +480,9 @@ export async function GET(request: Request, { params }: RouteParams) {
error: operation.error.message,
assetPayload: failedAssetPayload,
});
console.warn("[WorldLabsTask] failed status", {
logger.warn("task failed status", {
elapsedMs: Date.now() - startedAt,
taskId: normalizedTaskId,
taskIdLength: normalizedTaskId.length,
providerId: config.providerId || null,
error: operation.error.message,
});
@ -536,11 +539,11 @@ export async function GET(request: Request, { params }: RouteParams) {
operationMetadata: operation.metadata ?? null,
},
});
console.info("[WorldLabsTask] assets pending", {
logger.info("task assets pending", {
elapsedMs: Date.now() - startedAt,
taskId: normalizedTaskId,
taskIdLength: normalizedTaskId.length,
providerId: config.providerId || null,
worldId: getStringValue(world.world_id) || worldId || null,
worldIdLength: String(getStringValue(world.world_id) || worldId || "").length,
});
return NextResponse.json({
success: true,
@ -648,11 +651,11 @@ export async function GET(request: Request, { params }: RouteParams) {
? new Date().toISOString()
: null;
console.info("[WorldLabsTask] success status", {
logger.info("task success status", {
elapsedMs: Date.now() - startedAt,
taskId: normalizedTaskId,
taskIdLength: normalizedTaskId.length,
providerId: config.providerId || null,
worldId: assetPayload.worldId,
worldIdLength: String(assetPayload.worldId || "").length,
hasMesh: Boolean(stableModelUrl),
hasPano: Boolean(stablePanoUrl),
hasThumbnail: Boolean(stableThumbnailUrl),
@ -723,11 +726,10 @@ export async function GET(request: Request, { params }: RouteParams) {
},
});
} catch (error) {
console.error("[WorldLabsTask] status failed", {
logger.error("task status failed", error, {
elapsedMs: Date.now() - startedAt,
taskId: normalizedTaskIdForLog,
taskIdLength: String(normalizedTaskIdForLog || "").length,
providerId: providerForLog,
error: error instanceof Error ? error.message : String(error),
});
if (error instanceof WorldLabsApiError) {
return NextResponse.json(

View File

@ -10,6 +10,7 @@ import {
resolveThreeDModelRealId,
} from "@/lib/model3d/model-alias-config";
import { getThreeDModelAliasConfigForRuntime } from "@/lib/model3d/model-alias-config-server";
import { createLogger } from "@/lib/observability/logger";
import { get3DWorldCreditCost } from "@/lib/points/config";
import { WorldLabsApiError, worldLabsRequest } from "@/lib/worldlabs/client";
import {
@ -22,6 +23,8 @@ import type { WorldLabsModel, WorldLabsOperation } from "@/lib/worldlabs/types";
export const runtime = "nodejs";
export const maxDuration = 60;
const logger = createLogger("world-labs-task-create");
type WorldTaskMode = "text" | "image" | "multi-image" | "video";
type CreateWorldTaskRequest = {
@ -287,13 +290,18 @@ export async function POST(request: Request) {
note: `3D世界生成消耗积分(${worldModelDisplayName})`,
});
} catch (error) {
console.error("[Points] Failed to consume World Labs 3D points:", error);
logger.error("points consume failed", error, {
userId: session.user.id,
unitCost,
mode,
model: resolvedWorldModel || "marble-1.1",
});
}
}
console.info("[WorldLabsTask] created", {
logger.info("task created", {
elapsedMs: Date.now() - startedAt,
taskId,
taskIdLength: taskId.length,
mode,
model: resolvedWorldModel || "marble-1.1",
providerId: usedProvider.providerId || null,
@ -314,12 +322,11 @@ export async function POST(request: Request) {
},
});
} catch (error) {
console.error("[WorldLabsTask] create failed", {
logger.error("task create failed", error, {
elapsedMs: Date.now() - startedAt,
mode: modeForLog,
model: modelForLog,
providerId: providerForLog,
error: error instanceof Error ? error.message : String(error),
});
if (error instanceof WorldLabsApiError) {
return NextResponse.json(

View File

@ -35,6 +35,8 @@ const files = [
"app/api/canvas/world/upload/route.ts",
"app/api/canvas/3d/tasks/route.ts",
"app/api/canvas/3d/tasks/[taskId]/route.ts",
"app/api/canvas/world/tasks/route.ts",
"app/api/canvas/world/tasks/[taskId]/route.ts",
];
const consolePattern = /\bconsole\.(log|warn|error|info|debug)\b/g;