openai-compatible-providers-framework
Version:
OpenAI Compatible Providers Framework with Qwen and iFlow tool calling support, OAuth authentication, dynamic module loading, and comprehensive debug logging system
275 lines • 10.4 kB
JavaScript
"use strict";
/**
* Standalone Debug Logging Module
* 独立调试日志模块
*
* This is a complete standalone implementation that doesn't rely on relative imports.
* 这是一个完整的独立实现,不依赖相对导入。
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimpleDebugLogManager = exports.DEFAULT_DEBUG_CONFIG = void 0;
// Default configuration
exports.DEFAULT_DEBUG_CONFIG = {
enabled: false,
baseDirectory: './debug-logs',
paths: {
requests: 'requests',
responses: 'responses',
errors: 'errors',
pipeline: 'pipeline',
system: 'system'
},
logLevel: 'info',
contentFiltering: {
enabled: true,
sensitiveFields: ['apiKey', 'password', 'token', 'secret', 'key']
},
maxLogFiles: 1000,
maxLogSize: '100MB'
};
// Simple Debug Log Manager Implementation
class SimpleDebugLogManager {
constructor(config = {}) {
this.logs = [];
this.activeRequests = new Map();
this.config = { ...exports.DEFAULT_DEBUG_CONFIG, ...config };
try {
this.fileSystem = require('fs');
this.path = require('path');
}
catch (error) {
console.warn('FileSystem not available, logging to memory only');
}
}
startRequest(provider, operation, metadata) {
const requestId = `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const pipelineId = `pipeline_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const startTime = Date.now();
const context = {
requestId,
pipelineId,
startTime,
provider,
operation,
metadata,
getRequestId: () => requestId,
getPipelineId: () => pipelineId,
getStartTime: () => startTime,
getProvider: () => provider,
getOperation: () => operation,
getMetadata: () => metadata
};
this.activeRequests.set(requestId, context);
if (this.config.enabled && this.config.logLevel === 'debug') {
this.logDebug(`Request started: ${provider}.${operation}`, { requestId, metadata });
}
return context;
}
async logSuccess(context, request, response) {
if (!this.config.enabled)
return;
const duration = Date.now() - context.getStartTime();
const entry = {
type: 'success',
requestId: context.getRequestId(),
provider: context.getProvider(),
operation: context.getOperation(),
timestamp: Date.now(),
request: this.filterContent(request),
response: this.filterContent(response),
duration
};
await this.writeLogEntry(entry);
this.logs.push(entry);
this.activeRequests.delete(context.getRequestId());
if (this.config.logLevel !== 'silent') {
console.log(`[${context.getRequestId()}] Request completed successfully`);
}
}
async logError(context, request, error) {
if (!this.config.enabled)
return;
const duration = Date.now() - context.getStartTime();
const entry = {
type: 'error',
requestId: context.getRequestId(),
provider: context.getProvider(),
operation: context.getOperation(),
timestamp: Date.now(),
request: this.filterContent(request),
error: {
message: error instanceof Error ? error.message : String(error),
stack: error instanceof Error ? error.stack : undefined,
name: error instanceof Error ? error.name : 'Error'
},
duration
};
await this.writeLogEntry(entry, this.config.paths.errors);
this.logs.push(entry);
this.activeRequests.delete(context.getRequestId());
if (this.config.logLevel !== 'silent') {
console.error(`[${context.getRequestId()}] Request failed: ${error.message}`);
}
}
async info(message, data) {
if (!this.config.enabled || this.config.logLevel === 'silent')
return;
const entry = {
type: 'info',
requestId: 'system',
provider: 'system',
operation: 'info',
timestamp: Date.now(),
message,
data: this.filterContent(data)
};
await this.writeLogEntry(entry);
this.logs.push(entry);
if (this.config.logLevel === 'debug' || this.config.logLevel === 'info') {
console.log(`[INFO] ${message}`, data || '');
}
}
async warn(message, data) {
if (!this.config.enabled || this.config.logLevel === 'silent' || this.config.logLevel === 'error')
return;
const entry = {
type: 'warn',
requestId: 'system',
provider: 'system',
operation: 'warn',
timestamp: Date.now(),
message,
data: this.filterContent(data)
};
await this.writeLogEntry(entry);
this.logs.push(entry);
if (this.config.logLevel === 'debug' || this.config.logLevel === 'info' || this.config.logLevel === 'warn') {
console.warn(`[WARN] ${message}`, data || '');
}
}
async error(message, data) {
if (!this.config.enabled || this.config.logLevel === 'silent')
return;
const entry = {
type: 'error',
requestId: 'system',
provider: 'system',
operation: 'error',
timestamp: Date.now(),
message,
data: this.filterContent(data)
};
await this.writeLogEntry(entry, this.config.paths.errors);
this.logs.push(entry);
console.error(`[ERROR] ${message}`, data || '');
}
async logDebug(message, data) {
if (!this.config.enabled || this.config.logLevel !== 'debug')
return;
const entry = {
type: 'debug',
requestId: 'system',
provider: 'system',
operation: 'debug',
timestamp: Date.now(),
message,
data: this.filterContent(data)
};
await this.writeLogEntry(entry);
this.logs.push(entry);
console.log(`[DEBUG] ${message}`, data || '');
}
async getDebugStatistics() {
const totalLogs = this.logs.length;
const successCount = this.logs.filter(log => log.type === 'success').length;
const errorCount = this.logs.filter(log => log.type === 'error').length;
const responseTimes = this.logs
.filter(log => log.duration !== undefined)
.map(log => log.duration);
const averageResponseTime = responseTimes.length > 0
? responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length
: 0;
return {
systemHealth: {
status: 'healthy',
lastCheck: Date.now(),
issues: []
},
systemLogStats: {
totalLogs,
successCount,
errorCount,
lastActivity: this.logs.length > 0 ? this.logs[this.logs.length - 1].timestamp : Date.now()
},
activeRequests: Array.from(this.activeRequests.values()),
performanceMetrics: {
averageResponseTime,
maxResponseTime: responseTimes.length > 0 ? Math.max(...responseTimes) : 0,
minResponseTime: responseTimes.length > 0 ? Math.min(...responseTimes) : 0
}
};
}
async destroy() {
// Clean up resources
this.activeRequests.clear();
this.logs = [];
if (this.config.enabled) {
await this.info('Debug logging manager destroyed');
}
}
async writeLogEntry(entry, subdirectory) {
if (!this.fileSystem || !this.path) {
// Memory-only mode
return;
}
try {
const timestamp = new Date(entry.timestamp);
const dateStr = timestamp.toISOString().split('T')[0];
const timeStr = timestamp.toTimeString().split(' ')[0].replace(/:/g, '-');
const randomId = Math.random().toString(36).substr(2, 6);
const filename = `debug-${entry.timestamp}-${randomId}.json`;
const subdir = subdirectory || this.config.paths.system;
const dirPath = this.path.join(this.config.baseDirectory, subdir, dateStr);
const filePath = this.path.join(dirPath, filename);
// Ensure directory exists
if (!this.fileSystem.existsSync(dirPath)) {
this.fileSystem.mkdirSync(dirPath, { recursive: true });
}
// Write log file
this.fileSystem.writeFileSync(filePath, JSON.stringify(entry, null, 2));
if (this.config.logLevel === 'debug') {
console.log(`📝 Log written to: ${filePath}`);
}
}
catch (error) {
console.warn('Failed to write log file:', error instanceof Error ? error.message : String(error));
}
}
filterContent(obj) {
if (!this.config.contentFiltering.enabled || !obj) {
return obj;
}
const filtered = JSON.parse(JSON.stringify(obj));
const filterRecursive = (current) => {
if (typeof current === 'object' && current !== null) {
for (const key in current) {
if (this.config.contentFiltering.sensitiveFields.some(field => key.toLowerCase().includes(field.toLowerCase()))) {
current[key] = '[REDACTED]';
}
else if (typeof current[key] === 'object') {
filterRecursive(current[key]);
}
}
}
};
filterRecursive(filtered);
return filtered;
}
}
exports.SimpleDebugLogManager = SimpleDebugLogManager;
// Default export
exports.default = {
SimpleDebugLogManager,
DEFAULT_DEBUG_CONFIG: exports.DEFAULT_DEBUG_CONFIG
};
//# sourceMappingURL=index-standalone.js.map