debug(admin-service): add timing logs to parse and upload endpoints
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 <noreply@anthropic.com>
This commit is contained in:
parent
d48f1df0ff
commit
eca1490c72
|
|
@ -1,5 +1,5 @@
|
||||||
import {
|
import {
|
||||||
Controller, Get, Post, Put, Patch, Delete, Inject,
|
Controller, Get, Post, Put, Patch, Delete, Inject, Logger,
|
||||||
Param, Query, Body, UseGuards, UseInterceptors, UploadedFile, Req,
|
Param, Query, Body, UseGuards, UseInterceptors, UploadedFile, Req,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { FileInterceptor } from '@nestjs/platform-express';
|
import { FileInterceptor } from '@nestjs/platform-express';
|
||||||
|
|
@ -17,6 +17,8 @@ import { AppType } from '../../../domain/enums/app-type.enum';
|
||||||
@Roles(UserRole.ADMIN)
|
@Roles(UserRole.ADMIN)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
export class AdminVersionController {
|
export class AdminVersionController {
|
||||||
|
private readonly logger = new Logger(AdminVersionController.name);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly versionService: AppVersionService,
|
private readonly versionService: AppVersionService,
|
||||||
private readonly fileStorage: FileStorageService,
|
private readonly fileStorage: FileStorageService,
|
||||||
|
|
@ -100,9 +102,14 @@ export class AdminVersionController {
|
||||||
},
|
},
|
||||||
@Req() req: any,
|
@Req() req: any,
|
||||||
) {
|
) {
|
||||||
|
const t0 = Date.now();
|
||||||
if (!file) return { code: 400, message: 'No file uploaded' };
|
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);
|
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 appType: AppType = (body.appType || 'GENEX_MOBILE').toUpperCase() as AppType;
|
||||||
const platform: Platform = (
|
const platform: Platform = (
|
||||||
body.platform || (file.originalname.toLowerCase().endsWith('.ipa') ? 'IOS' : 'ANDROID')
|
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 versionName = info.versionName || body.versionName || '0.0.0';
|
||||||
const buildNumber = body.buildNumber || versionCode.toString();
|
const buildNumber = body.buildNumber || versionCode.toString();
|
||||||
|
|
||||||
|
const t2 = Date.now();
|
||||||
const filename = this.fileStorage.generateObjectName(file.originalname, platform, versionName);
|
const filename = this.fileStorage.generateObjectName(file.originalname, platform, versionName);
|
||||||
const saved = await this.fileStorage.saveFile(file.buffer, filename);
|
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({
|
const version = await this.versionService.createVersion({
|
||||||
appType,
|
appType,
|
||||||
|
|
@ -131,6 +140,7 @@ export class AdminVersionController {
|
||||||
createdBy: req.user?.sub,
|
createdBy: req.user?.sub,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.logger.log(`[upload] total=${Date.now() - t0}ms`);
|
||||||
return { code: 0, data: version };
|
return { code: 0, data: version };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,10 +149,13 @@ export class AdminVersionController {
|
||||||
@ApiConsumes('multipart/form-data')
|
@ApiConsumes('multipart/form-data')
|
||||||
@ApiOperation({ summary: 'Parse APK/IPA without saving (preview metadata)' })
|
@ApiOperation({ summary: 'Parse APK/IPA without saving (preview metadata)' })
|
||||||
async parsePackage(@UploadedFile() file: Express.Multer.File) {
|
async parsePackage(@UploadedFile() file: Express.Multer.File) {
|
||||||
|
const t0 = Date.now();
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return { code: 400, message: 'No file uploaded — check Content-Type boundary' };
|
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);
|
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 };
|
return { code: 0, data: info };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue