From eca1490c72ff04cdd21d2bb76d520df8388f59f6 Mon Sep 17 00:00:00 2001 From: hailin Date: Sat, 7 Mar 2026 06:33:18 -0800 Subject: [PATCH] debug(admin-service): add timing logs to parse and upload endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Logs file size on receipt, parse duration, file save duration, and total request time — to pinpoint where upload latency comes from. Co-Authored-By: Claude Sonnet 4.6 --- .../http/controllers/admin-version.controller.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/backend/services/admin-service/src/interface/http/controllers/admin-version.controller.ts b/backend/services/admin-service/src/interface/http/controllers/admin-version.controller.ts index 084ea26..73bdafe 100644 --- a/backend/services/admin-service/src/interface/http/controllers/admin-version.controller.ts +++ b/backend/services/admin-service/src/interface/http/controllers/admin-version.controller.ts @@ -1,5 +1,5 @@ import { - Controller, Get, Post, Put, Patch, Delete, Inject, + Controller, Get, Post, Put, Patch, Delete, Inject, Logger, Param, Query, Body, UseGuards, UseInterceptors, UploadedFile, Req, } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; @@ -17,6 +17,8 @@ import { AppType } from '../../../domain/enums/app-type.enum'; @Roles(UserRole.ADMIN) @ApiBearerAuth() export class AdminVersionController { + private readonly logger = new Logger(AdminVersionController.name); + constructor( private readonly versionService: AppVersionService, private readonly fileStorage: FileStorageService, @@ -100,9 +102,14 @@ export class AdminVersionController { }, @Req() req: any, ) { + const t0 = Date.now(); if (!file) return { code: 400, message: 'No file uploaded' }; + this.logger.log(`[upload] received: ${file.originalname} size=${(file.size / 1024 / 1024).toFixed(1)}MB`); + const t1 = Date.now(); const info = await this.packageParser.parse(file.buffer, file.originalname); + this.logger.log(`[upload] parse done in ${Date.now() - t1}ms → pkg=${info.packageName} ver=${info.versionName}`); + const appType: AppType = (body.appType || 'GENEX_MOBILE').toUpperCase() as AppType; const platform: Platform = ( body.platform || (file.originalname.toLowerCase().endsWith('.ipa') ? 'IOS' : 'ANDROID') @@ -111,8 +118,10 @@ export class AdminVersionController { const versionName = info.versionName || body.versionName || '0.0.0'; const buildNumber = body.buildNumber || versionCode.toString(); + const t2 = Date.now(); const filename = this.fileStorage.generateObjectName(file.originalname, platform, versionName); const saved = await this.fileStorage.saveFile(file.buffer, filename); + this.logger.log(`[upload] file saved in ${Date.now() - t2}ms → ${filename}`); const version = await this.versionService.createVersion({ appType, @@ -131,6 +140,7 @@ export class AdminVersionController { createdBy: req.user?.sub, }); + this.logger.log(`[upload] total=${Date.now() - t0}ms`); return { code: 0, data: version }; } @@ -139,10 +149,13 @@ export class AdminVersionController { @ApiConsumes('multipart/form-data') @ApiOperation({ summary: 'Parse APK/IPA without saving (preview metadata)' }) async parsePackage(@UploadedFile() file: Express.Multer.File) { + const t0 = Date.now(); if (!file) { return { code: 400, message: 'No file uploaded — check Content-Type boundary' }; } + this.logger.log(`[parse] received: ${file.originalname} size=${(file.size / 1024 / 1024).toFixed(1)}MB`); const info = await this.packageParser.parse(file.buffer, file.originalname); + this.logger.log(`[parse] done in ${Date.now() - t0}ms → pkg=${info.packageName} ver=${info.versionName}`); return { code: 0, data: info }; }