more detailed display
This commit is contained in:
+162
-55
@@ -10,6 +10,7 @@ class Logger {
|
||||
this.logFilePath = path.join(__dirname, 'requests.log');
|
||||
this.statistics = {};
|
||||
this.monthStart = this.getMonthStart();
|
||||
this.today = this.getToday();
|
||||
this.loadStatistics();
|
||||
}
|
||||
|
||||
@@ -21,6 +22,14 @@ class Logger {
|
||||
return monthStart;
|
||||
}
|
||||
|
||||
getToday() {
|
||||
const now = new Date();
|
||||
// 获取当天日期
|
||||
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||
today.setHours(0, 0, 0, 0);
|
||||
return today;
|
||||
}
|
||||
|
||||
// 加载日志
|
||||
loadStatistics() {
|
||||
if (fs.existsSync(this.logFilePath)) {
|
||||
@@ -31,11 +40,40 @@ class Logger {
|
||||
for (const line of entries) {
|
||||
try {
|
||||
const logEntry = JSON.parse(line);
|
||||
if (logEntry && logEntry.email && logEntry.time && logEntry.mode && logEntry.model !== undefined && logEntry.completed !== undefined && logEntry.unusualQueryVolume !== undefined) {
|
||||
validEntries.push(logEntry);
|
||||
} else {
|
||||
console.warn(`忽略格式不正确的日志: ${line}`);
|
||||
|
||||
// 补全缺少的字段
|
||||
if (!logEntry.provider) {
|
||||
logEntry.provider = 'you';
|
||||
}
|
||||
if (!logEntry.email) {
|
||||
logEntry.email = 'unknown';
|
||||
}
|
||||
if (!logEntry.mode) {
|
||||
logEntry.mode = 'default';
|
||||
}
|
||||
if (logEntry.model === undefined) {
|
||||
logEntry.model = 'unknown';
|
||||
}
|
||||
if (logEntry.completed === undefined) {
|
||||
logEntry.completed = false;
|
||||
}
|
||||
if (logEntry.unusualQueryVolume === undefined) {
|
||||
logEntry.unusualQueryVolume = false;
|
||||
}
|
||||
|
||||
// 调整字段顺序
|
||||
const logEntryArray = [
|
||||
['provider', logEntry.provider],
|
||||
['email', logEntry.email],
|
||||
['time', logEntry.time],
|
||||
['mode', logEntry.mode],
|
||||
['model', logEntry.model],
|
||||
['completed', logEntry.completed],
|
||||
['unusualQueryVolume', logEntry.unusualQueryVolume],
|
||||
];
|
||||
const formattedLogEntry = Object.fromEntries(logEntryArray);
|
||||
|
||||
validEntries.push(formattedLogEntry);
|
||||
} catch (e) {
|
||||
console.warn(`无法解析的日志,已忽略: ${line}`);
|
||||
}
|
||||
@@ -44,37 +82,69 @@ class Logger {
|
||||
// 处理有效日志
|
||||
for (const logEntry of validEntries) {
|
||||
const logDate = new Date(logEntry.time);
|
||||
const email = logEntry.email || 'unknown';
|
||||
const provider = logEntry.provider;
|
||||
const email = logEntry.email;
|
||||
|
||||
// 初始化 provider
|
||||
if (!this.statistics[provider]) {
|
||||
this.statistics[provider] = {};
|
||||
}
|
||||
|
||||
// 初始化邮箱
|
||||
if (!this.statistics[email]) {
|
||||
this.statistics[email] = {
|
||||
requests: [],
|
||||
totalRequests: 0,
|
||||
defaultModeCount: 0,
|
||||
customModeCount: 0,
|
||||
modelCount: {},
|
||||
if (!this.statistics[provider][email]) {
|
||||
this.statistics[provider][email] = {
|
||||
allRequests: [], // 所有请求
|
||||
monthlyRequests: [], // 本月请求
|
||||
dailyRequests: [], // 当日请求
|
||||
monthlyStats: {
|
||||
totalRequests: 0,
|
||||
defaultModeCount: 0,
|
||||
customModeCount: 0,
|
||||
modelCount: {},
|
||||
},
|
||||
dailyStats: {
|
||||
totalRequests: 0,
|
||||
defaultModeCount: 0,
|
||||
customModeCount: 0,
|
||||
modelCount: {},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const stats = this.statistics[provider][email];
|
||||
stats.allRequests.push(logEntry);
|
||||
|
||||
// 本月统计
|
||||
if (logDate >= this.monthStart) {
|
||||
this.statistics[email].requests.push(logEntry);
|
||||
this.updateStatistics(email, logEntry);
|
||||
stats.monthlyRequests.push(logEntry);
|
||||
this.updateStatistics(stats.monthlyStats, logEntry);
|
||||
}
|
||||
|
||||
// 当日统计
|
||||
if (logDate >= this.today) {
|
||||
stats.dailyRequests.push(logEntry);
|
||||
this.updateStatistics(stats.dailyStats, logEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// 每个邮箱时间排序
|
||||
for (const email in this.statistics) {
|
||||
this.statistics[email].requests.sort((a, b) => new Date(b.time) - new Date(a.time));
|
||||
// 对每个 provider 的每个邮箱时间排序
|
||||
for (const provider in this.statistics) {
|
||||
for (const email in this.statistics[provider]) {
|
||||
const stats = this.statistics[provider][email];
|
||||
stats.allRequests.sort((a, b) => new Date(b.time) - new Date(a.time));
|
||||
stats.monthlyRequests.sort((a, b) => new Date(b.time) - new Date(a.time));
|
||||
stats.dailyRequests.sort((a, b) => new Date(b.time) - new Date(a.time));
|
||||
}
|
||||
}
|
||||
|
||||
// 理无效数据
|
||||
// 清理无效数据
|
||||
const cleanedData = validEntries.map(entry => JSON.stringify(entry)).join('\n') + '\n';
|
||||
fs.writeFileSync(this.logFilePath, cleanedData);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新统计
|
||||
updateStatistics(email, logEntry) {
|
||||
const stats = this.statistics[email];
|
||||
updateStatistics(stats, logEntry) {
|
||||
stats.totalRequests++;
|
||||
if (logEntry.mode === 'default') {
|
||||
stats.defaultModeCount++;
|
||||
@@ -91,56 +161,93 @@ class Logger {
|
||||
}
|
||||
|
||||
// 记录请求日志
|
||||
logRequest({ email, time, mode, model, completed, unusualQueryVolume }) {
|
||||
const logEntry = {
|
||||
email, // 用户邮箱
|
||||
time, // 请求时间
|
||||
mode, // 请求模式
|
||||
model, // 请求模型
|
||||
completed, // 是否完成
|
||||
unusualQueryVolume, // 是否异常请求量
|
||||
};
|
||||
|
||||
logRequest({ provider, email, time, mode, model, completed, unusualQueryVolume }) {
|
||||
provider = provider || process.env.ACTIVE_PROVIDER || 'you';
|
||||
const logEntryArray = [
|
||||
['provider', provider], // 提供者名称
|
||||
['email', email], // 用户邮箱
|
||||
['time', time], // 请求时间
|
||||
['mode', mode], // 请求模式
|
||||
['model', model], // 请求模型
|
||||
['completed', completed], // 是否完成
|
||||
['unusualQueryVolume', unusualQueryVolume], // 是否异常请求量
|
||||
];
|
||||
const logEntry = Object.fromEntries(logEntryArray);
|
||||
// 写入日志
|
||||
fs.appendFileSync(this.logFilePath, JSON.stringify(logEntry) + '\n');
|
||||
|
||||
// 当前月份请求更新统计
|
||||
const logDate = new Date(time);
|
||||
if (logDate >= this.monthStart) {
|
||||
// 初始化 provider
|
||||
if (!this.statistics[provider]) {
|
||||
this.statistics[provider] = {};
|
||||
}
|
||||
|
||||
const userEmail = email || 'unknown';
|
||||
if (!this.statistics[userEmail]) {
|
||||
this.statistics[userEmail] = {
|
||||
requests: [],
|
||||
totalRequests: 0,
|
||||
defaultModeCount: 0,
|
||||
customModeCount: 0,
|
||||
modelCount: {},
|
||||
if (!this.statistics[provider][userEmail]) {
|
||||
this.statistics[provider][userEmail] = {
|
||||
allRequests: [],
|
||||
monthlyRequests: [],
|
||||
dailyRequests: [],
|
||||
monthlyStats: {
|
||||
totalRequests: 0,
|
||||
defaultModeCount: 0,
|
||||
customModeCount: 0,
|
||||
modelCount: {},
|
||||
},
|
||||
dailyStats: {
|
||||
totalRequests: 0,
|
||||
defaultModeCount: 0,
|
||||
customModeCount: 0,
|
||||
modelCount: {},
|
||||
}
|
||||
};
|
||||
}
|
||||
this.statistics[userEmail].requests.push(logEntry);
|
||||
// 对请求按照时间排序
|
||||
this.statistics[userEmail].requests.sort((a, b) => new Date(b.time) - new Date(a.time));
|
||||
this.updateStatistics(userEmail, logEntry);
|
||||
|
||||
const stats = this.statistics[provider][userEmail];
|
||||
stats.allRequests.push(logEntry);
|
||||
|
||||
// 当日统计
|
||||
if (logDate >= this.today) {
|
||||
stats.dailyRequests.push(logEntry);
|
||||
this.updateStatistics(stats.dailyStats, logEntry);
|
||||
}
|
||||
|
||||
// 本月统计
|
||||
stats.monthlyRequests.push(logEntry);
|
||||
this.updateStatistics(stats.monthlyStats, logEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// 输出当前月份的统计信息
|
||||
// 输出当前统计信息
|
||||
printStatistics() {
|
||||
console.log('===== 请求统计信息 =====');
|
||||
console.log(`当前月份: ${this.monthStart.toLocaleDateString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}`);
|
||||
const emails = Object.keys(this.statistics).sort();
|
||||
const provider = process.env.ACTIVE_PROVIDER || 'you';
|
||||
const monthStart = this.monthStart.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' });
|
||||
const today = this.today.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' });
|
||||
if (!this.statistics[provider]) {
|
||||
console.log(`===== 提供者 ${provider} 没有统计数据 =====`);
|
||||
return;
|
||||
}
|
||||
console.log(`===== 请求统计信息 (${provider}) =====`);
|
||||
const emails = Object.keys(this.statistics[provider]).sort();
|
||||
for (const email of emails) {
|
||||
const stats = this.statistics[email];
|
||||
const stats = this.statistics[provider][email];
|
||||
console.log(`用户邮箱: ${email}`);
|
||||
console.log(`总请求次数: ${stats.totalRequests}`);
|
||||
console.log(`default 请求次数: ${stats.defaultModeCount}`);
|
||||
console.log(`custom 请求次数: ${stats.customModeCount}`);
|
||||
console.log(`---------- 本月[${monthStart}]统计 ----------`);
|
||||
console.log(`总请求次数: ${stats.monthlyStats.totalRequests}`);
|
||||
console.log(`default 请求次数: ${stats.monthlyStats.defaultModeCount}`);
|
||||
console.log(`custom 请求次数: ${stats.monthlyStats.customModeCount}`);
|
||||
console.log('各模型请求次数:');
|
||||
for (const [model, count] of Object.entries(stats.modelCount)) {
|
||||
for (const [model, count] of Object.entries(stats.monthlyStats.modelCount)) {
|
||||
console.log(` - ${model}: ${count}`);
|
||||
}
|
||||
console.log(`---------- 今日[${today}]统计 ----------`);
|
||||
console.log(`总请求次数: ${stats.dailyStats.totalRequests}`);
|
||||
console.log(`default 请求次数: ${stats.dailyStats.defaultModeCount}`);
|
||||
console.log(`custom 请求次数: ${stats.dailyStats.customModeCount}`);
|
||||
console.log('各模型请求次数:');
|
||||
for (const [model, count] of Object.entries(stats.dailyStats.modelCount)) {
|
||||
console.log(` - ${model}: ${count}`);
|
||||
}
|
||||
console.log('------------------------------');
|
||||
@@ -149,4 +256,4 @@ class Logger {
|
||||
}
|
||||
}
|
||||
|
||||
export default Logger;
|
||||
export default Logger;
|
||||
|
||||
Reference in New Issue
Block a user