mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 08:47:44 +00:00
pre-release commit
This commit is contained in:
135
packages/core/src/utils/openaiLogger.ts
Normal file
135
packages/core/src/utils/openaiLogger.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import * as path from 'node:path';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import * as os from 'os';
|
||||
|
||||
/**
|
||||
* Logger specifically for OpenAI API requests and responses
|
||||
*/
|
||||
export class OpenAILogger {
|
||||
private logDir: string;
|
||||
private initialized: boolean = false;
|
||||
|
||||
/**
|
||||
* Creates a new OpenAI logger
|
||||
* @param customLogDir Optional custom log directory path
|
||||
*/
|
||||
constructor(customLogDir?: string) {
|
||||
this.logDir = customLogDir || path.join(process.cwd(), 'logs', 'openai');
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the logger by creating the log directory if it doesn't exist
|
||||
*/
|
||||
async initialize(): Promise<void> {
|
||||
if (this.initialized) return;
|
||||
|
||||
try {
|
||||
await fs.mkdir(this.logDir, { recursive: true });
|
||||
this.initialized = true;
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize OpenAI logger:', error);
|
||||
throw new Error(`Failed to initialize OpenAI logger: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an OpenAI API request and its response
|
||||
* @param request The request sent to OpenAI
|
||||
* @param response The response received from OpenAI
|
||||
* @param error Optional error if the request failed
|
||||
* @returns The file path where the log was written
|
||||
*/
|
||||
async logInteraction(
|
||||
request: unknown,
|
||||
response?: unknown,
|
||||
error?: Error,
|
||||
): Promise<string> {
|
||||
if (!this.initialized) {
|
||||
await this.initialize();
|
||||
}
|
||||
|
||||
const timestamp = new Date().toISOString().replace(/:/g, '-');
|
||||
const id = uuidv4().slice(0, 8);
|
||||
const filename = `openai-${timestamp}-${id}.json`;
|
||||
const filePath = path.join(this.logDir, filename);
|
||||
|
||||
const logData = {
|
||||
timestamp: new Date().toISOString(),
|
||||
request,
|
||||
response: response || null,
|
||||
error: error
|
||||
? {
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
}
|
||||
: null,
|
||||
system: {
|
||||
hostname: os.hostname(),
|
||||
platform: os.platform(),
|
||||
release: os.release(),
|
||||
nodeVersion: process.version,
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
await fs.writeFile(filePath, JSON.stringify(logData, null, 2), 'utf-8');
|
||||
return filePath;
|
||||
} catch (writeError) {
|
||||
console.error('Failed to write OpenAI log file:', writeError);
|
||||
throw new Error(`Failed to write OpenAI log file: ${writeError}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all logged interactions
|
||||
* @param limit Optional limit on the number of log files to return (sorted by most recent first)
|
||||
* @returns Array of log file paths
|
||||
*/
|
||||
async getLogFiles(limit?: number): Promise<string[]> {
|
||||
if (!this.initialized) {
|
||||
await this.initialize();
|
||||
}
|
||||
|
||||
try {
|
||||
const files = await fs.readdir(this.logDir);
|
||||
const logFiles = files
|
||||
.filter((file) => file.startsWith('openai-') && file.endsWith('.json'))
|
||||
.map((file) => path.join(this.logDir, file))
|
||||
.sort()
|
||||
.reverse();
|
||||
|
||||
return limit ? logFiles.slice(0, limit) : logFiles;
|
||||
} catch (error) {
|
||||
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
||||
return [];
|
||||
}
|
||||
console.error('Failed to read OpenAI log directory:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a specific log file
|
||||
* @param filePath The path to the log file
|
||||
* @returns The log file content
|
||||
*/
|
||||
async readLogFile(filePath: string): Promise<unknown> {
|
||||
try {
|
||||
const content = await fs.readFile(filePath, 'utf-8');
|
||||
return JSON.parse(content);
|
||||
} catch (error) {
|
||||
console.error(`Failed to read log file ${filePath}:`, error);
|
||||
throw new Error(`Failed to read log file: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a singleton instance for easy import
|
||||
export const openaiLogger = new OpenAILogger();
|
||||
Reference in New Issue
Block a user