|
1 | | -import { appendFile, access, constants } from 'fs/promises'; |
| 1 | +import { appendFile, access, constants, readFile, writeFile } from 'fs/promises'; |
2 | 2 | import { resolve, dirname } from 'path'; |
3 | 3 | import { fileURLToPath } from 'url'; |
4 | 4 |
|
@@ -135,6 +135,34 @@ export async function ensureLogFile() { |
135 | 135 | } |
136 | 136 | } |
137 | 137 |
|
| 138 | +const ONE_YEAR = 365 * 24 * 60 * 60 * 1000; |
| 139 | + |
| 140 | +export async function cleanOldLogs() { |
| 141 | + try { |
| 142 | + const content = await readFile(LOG_FILE, 'utf-8'); |
| 143 | + if (!content) return; |
| 144 | + const cutoff = Date.now() - ONE_YEAR; |
| 145 | + const lines = content.split('\n').filter(line => { |
| 146 | + if (!line.trim()) return false; |
| 147 | + const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]/); |
| 148 | + if (!match) return true; |
| 149 | + const ts = new Date(match[1].replace(' ', 'T') + 'Z').getTime(); |
| 150 | + return ts >= cutoff; |
| 151 | + }); |
| 152 | + const cleaned = lines.join('\n') + (lines.length > 0 ? '\n' : ''); |
| 153 | + await writeFile(LOG_FILE, cleaned, 'utf-8'); |
| 154 | + } catch (err) { |
| 155 | + if (err.code !== 'ENOENT') { |
| 156 | + console.error('Failed to clean old logs:', err.message); |
| 157 | + } |
| 158 | + } |
| 159 | +} |
| 160 | + |
| 161 | +export function startLogCleaner() { |
| 162 | + cleanOldLogs(); |
| 163 | + setInterval(cleanOldLogs, 24 * 60 * 60 * 1000); |
| 164 | +} |
| 165 | + |
138 | 166 | export async function writeLog(method, path, ip) { |
139 | 167 | const label = getActionLabel(method, path); |
140 | 168 | const date = new Date(); |
|
0 commit comments