From 303535b22a6053ff21575e403272835a820e5f35 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 27 May 2026 10:52:00 +0800 Subject: [PATCH] chore: harden video archive logging --- lib/storage/video-archiver.ts | 53 ++++++++++++++++++++++++----------- scripts/check-log-hygiene.mjs | 1 + 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/storage/video-archiver.ts b/lib/storage/video-archiver.ts index 525e59490..f83d76ac3 100644 --- a/lib/storage/video-archiver.ts +++ b/lib/storage/video-archiver.ts @@ -7,6 +7,7 @@ import { db } from "@/lib/db"; import { message } from "@/lib/db/schema"; import { eq } from "drizzle-orm"; import { getDefaultStorageConfig } from "@/lib/db/queries"; +import { createLogger } from "@/lib/observability/logger"; import { toDbS3UploadConfig, uploadFile, @@ -14,6 +15,8 @@ import { } from "@/lib/storage/service"; import type { VideoMetadata } from "@/types/ai"; +const logger = createLogger("video-archiver"); + interface VideoArchiveOptions { messageId: string; temporaryUrl: string; @@ -33,13 +36,13 @@ export class VideoArchiver { const { messageId, temporaryUrl, taskId, metadata } = options; try { - console.log(`[VideoArchiver] 📹 开始归档视频:${messageId}`); + logger.info("archive started", { messageId, taskId }); // 1. 更新状态为"归档中" await this.updateVideoStatus(messageId, "archiving"); // 2. 下载视频 - console.log(`[VideoArchiver] ⬇️ 下载视频:${temporaryUrl}`); + logger.info("download started", { messageId, temporaryUrl }); const videoBuffer = await this.downloadVideo(temporaryUrl); if (!videoBuffer) { @@ -50,7 +53,11 @@ export class VideoArchiver { const filename = this.generateVideoFilename(messageId, taskId); // 4. 上传到S3(使用项目统一存储服务) - console.log(`[VideoArchiver] ⬆️ 上传视频到S3:${filename}`); + logger.info("upload started", { + messageId, + filename, + bytes: videoBuffer.length, + }); const permanentUrl = await this.uploadVideoToS3(videoBuffer, filename); // 5. 更新数据库 @@ -61,10 +68,14 @@ export class VideoArchiver { ...metadata, }); - console.log(`[VideoArchiver] ✅ 视频归档完成:${permanentUrl}`); + logger.info("archive completed", { + messageId, + permanentUrl, + bytes: videoBuffer.length, + }); return permanentUrl; } catch (error) { - console.error(`[VideoArchiver] ❌ 归档失败:`, error); + logger.error("archive failed", error, { messageId, taskId }); // 更新状态为"失败" await this.updateVideoStatus(messageId, "failed"); @@ -95,10 +106,12 @@ export class VideoArchiver { const arrayBuffer = await response.arrayBuffer(); return Buffer.from(arrayBuffer); } catch (error) { - console.error( - `[VideoArchiver] 下载失败 (尝试 ${i + 1}/${retries}):`, - error - ); + logger.warn("download attempt failed", { + attempt: i + 1, + retries, + url, + error, + }); if (i === retries - 1) { return null; @@ -121,7 +134,9 @@ export class VideoArchiver { buffer: Buffer, filename: string ): Promise { - const defaultStorageConfig = await getDefaultStorageConfig().catch(() => undefined); + const defaultStorageConfig = await getDefaultStorageConfig().catch( + () => undefined + ); const defaultS3Config = toDbS3UploadConfig(defaultStorageConfig); if (defaultS3Config) { @@ -130,16 +145,22 @@ export class VideoArchiver { buffer as any, defaultS3Config ); - console.log( - `[VideoArchiver] 视频已上传到默认存储:${uploaded.url}`, - defaultStorageConfig?.name ? `(config=${defaultStorageConfig.name})` : "" - ); + logger.info("upload completed with default storage", { + filename, + url: uploaded.url, + storageConfigName: defaultStorageConfig?.name, + }); return uploaded.url; } - console.warn("[VideoArchiver] 默认存储不可用,回退到通用上传策略"); + logger.warn("default storage unavailable, using fallback uploader", { + filename, + }); const fallback = await uploadFile(filename, buffer as any); - console.log(`[VideoArchiver] 视频已上传(回退路径):${fallback.url}`); + logger.info("upload completed with fallback storage", { + filename, + url: fallback.url, + }); return fallback.url; } diff --git a/scripts/check-log-hygiene.mjs b/scripts/check-log-hygiene.mjs index 65e8b5b2c..a3a7d527a 100644 --- a/scripts/check-log-hygiene.mjs +++ b/scripts/check-log-hygiene.mjs @@ -17,6 +17,7 @@ const files = [ "app/(chat)/api/chat/_lib/stream.ts", "app/(chat)/api/chat/_lib/video-models.ts", "lib/storage/service.ts", + "lib/storage/video-archiver.ts", "app/(chat)/api/files/upload/route.ts", "app/(auth)/login/page.tsx", "app/api/auth/dingtalk/callback/route.ts",