feat: log generation requests
This commit is contained in:
parent
13e8824000
commit
367f1d1946
|
|
@ -17,4 +17,7 @@ RESULTS_DIR=./results
|
|||
UPLOADS_DIR=./uploads/temp
|
||||
|
||||
# Logging Configuration
|
||||
LOG_LEVEL=info
|
||||
LOG_LEVEL=info
|
||||
|
||||
# Text-to-Image Logging (optional)
|
||||
# TTI_LOG=./apps/api-service/logs/tti.log
|
||||
|
|
@ -9,6 +9,7 @@ import {
|
|||
GeminiParams,
|
||||
} from "../types/api";
|
||||
import { StorageFactory } from "./StorageFactory";
|
||||
import { TTILogger, TTILogEntry } from "./TTILogger";
|
||||
|
||||
export class ImageGenService {
|
||||
private ai: GoogleGenAI;
|
||||
|
|
@ -39,7 +40,12 @@ export class ImageGenService {
|
|||
let generatedData: GeneratedImageData;
|
||||
let geminiParams: GeminiParams;
|
||||
try {
|
||||
const aiResult = await this.generateImageWithAI(prompt, referenceImages);
|
||||
const aiResult = await this.generateImageWithAI(
|
||||
prompt,
|
||||
referenceImages,
|
||||
finalOrgId,
|
||||
finalProjectId,
|
||||
);
|
||||
generatedData = aiResult.generatedData;
|
||||
geminiParams = aiResult.geminiParams;
|
||||
} catch (error) {
|
||||
|
|
@ -114,8 +120,13 @@ export class ImageGenService {
|
|||
*/
|
||||
private async generateImageWithAI(
|
||||
prompt: string,
|
||||
referenceImages?: ReferenceImage[],
|
||||
): Promise<{ generatedData: GeneratedImageData; geminiParams: GeminiParams }> {
|
||||
referenceImages: ReferenceImage[] | undefined,
|
||||
orgId: string,
|
||||
projectId: string,
|
||||
): Promise<{
|
||||
generatedData: GeneratedImageData;
|
||||
geminiParams: GeminiParams;
|
||||
}> {
|
||||
const contentParts: any[] = [];
|
||||
|
||||
// Add reference images if provided
|
||||
|
|
@ -135,6 +146,8 @@ export class ImageGenService {
|
|||
text: prompt,
|
||||
});
|
||||
|
||||
// CRITICAL: Calculate exact values before SDK call
|
||||
// These exact objects will be passed to both SDK and logger
|
||||
const contents = [
|
||||
{
|
||||
role: "user" as const,
|
||||
|
|
@ -155,7 +168,29 @@ export class ImageGenService {
|
|||
},
|
||||
};
|
||||
|
||||
// Log TTI request BEFORE SDK call - using exact same values
|
||||
const ttiLogger = TTILogger.getInstance();
|
||||
const logEntry: TTILogEntry = {
|
||||
timestamp: new Date().toISOString(),
|
||||
orgId,
|
||||
projectId,
|
||||
prompt,
|
||||
model: this.primaryModel,
|
||||
config,
|
||||
...(referenceImages &&
|
||||
referenceImages.length > 0 && {
|
||||
referenceImages: referenceImages.map((img) => ({
|
||||
mimetype: img.mimetype,
|
||||
size: img.buffer.length,
|
||||
originalname: img.originalname,
|
||||
})),
|
||||
}),
|
||||
};
|
||||
|
||||
ttiLogger.log(logEntry);
|
||||
|
||||
try {
|
||||
// Use the EXACT same config and contents objects calculated above
|
||||
const response = await this.ai.models.generateContent({
|
||||
model: this.primaryModel,
|
||||
config,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
import { writeFileSync, appendFileSync, existsSync, mkdirSync } from "fs";
|
||||
import { dirname } from "path";
|
||||
|
||||
export interface TTILogEntry {
|
||||
timestamp: string;
|
||||
orgId: string;
|
||||
projectId: string;
|
||||
prompt: string;
|
||||
referenceImages?: Array<{
|
||||
mimetype: string;
|
||||
size: number;
|
||||
originalname: string;
|
||||
}>;
|
||||
model: string;
|
||||
config: any;
|
||||
}
|
||||
|
||||
export class TTILogger {
|
||||
private static instance: TTILogger | null = null;
|
||||
private logFilePath: string | null = null;
|
||||
private isEnabled: boolean = false;
|
||||
|
||||
private constructor() {
|
||||
const ttiLogPath = process.env["TTI_LOG"];
|
||||
|
||||
if (ttiLogPath) {
|
||||
this.logFilePath = ttiLogPath;
|
||||
this.isEnabled = true;
|
||||
this.initializeLogFile();
|
||||
}
|
||||
}
|
||||
|
||||
static getInstance(): TTILogger {
|
||||
if (!TTILogger.instance) {
|
||||
TTILogger.instance = new TTILogger();
|
||||
}
|
||||
return TTILogger.instance;
|
||||
}
|
||||
|
||||
private initializeLogFile(): void {
|
||||
if (!this.logFilePath) return;
|
||||
|
||||
try {
|
||||
// Ensure directory exists
|
||||
const dir = dirname(this.logFilePath);
|
||||
if (!existsSync(dir)) {
|
||||
mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
|
||||
// Reset/clear the log file on service start
|
||||
writeFileSync(this.logFilePath, "# Text-to-Image Generation Log\n\n", {
|
||||
encoding: "utf-8",
|
||||
});
|
||||
|
||||
console.log(`[TTILogger] Log file initialized: ${this.logFilePath}`);
|
||||
} catch (error) {
|
||||
console.error(`[TTILogger] Failed to initialize log file:`, error);
|
||||
this.isEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
log(entry: TTILogEntry): void {
|
||||
if (!this.isEnabled || !this.logFilePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const logEntry = this.formatLogEntry(entry);
|
||||
appendFileSync(this.logFilePath, logEntry, { encoding: "utf-8" });
|
||||
} catch (error) {
|
||||
console.error(`[TTILogger] Failed to write log entry:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
private formatLogEntry(entry: TTILogEntry): string {
|
||||
const { timestamp, orgId, projectId, prompt, referenceImages, model, config } = entry;
|
||||
|
||||
// Format date from ISO timestamp
|
||||
const date = new Date(timestamp);
|
||||
const formattedDate = date.toISOString().replace("T", " ").slice(0, 19);
|
||||
|
||||
let logText = `## ${formattedDate}\n`;
|
||||
logText += `${orgId}/${projectId}\n\n`;
|
||||
logText += `**Prompt:** ${prompt}\n\n`;
|
||||
|
||||
if (referenceImages && referenceImages.length > 0) {
|
||||
logText += `**Reference Images:** ${referenceImages.length} image${referenceImages.length > 1 ? "s" : ""}\n`;
|
||||
for (const img of referenceImages) {
|
||||
const sizeMB = (img.size / (1024 * 1024)).toFixed(2);
|
||||
logText += `- ${img.originalname} (${img.mimetype}, ${sizeMB} MB)\n`;
|
||||
}
|
||||
logText += "\n";
|
||||
}
|
||||
|
||||
logText += `**Model:** ${model}\n`;
|
||||
logText += `**Config:** ${JSON.stringify(config)}\n\n`;
|
||||
logText += `---\n\n`;
|
||||
|
||||
return logText;
|
||||
}
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@ services:
|
|||
- LOG_LEVEL=${LOG_LEVEL}
|
||||
- PORT=${PORT}
|
||||
- CORS_ORIGIN=${CORS_ORIGIN}
|
||||
- TTI_LOG=${TTI_LOG}
|
||||
restart: unless-stopped
|
||||
|
||||
postgres:
|
||||
|
|
|
|||
Loading…
Reference in New Issue