import { createReadStream, promises as fs } from 'fs'; import { dirname, basename } from 'path'; import type { AuditEvent, AuditQuery } from './types.js'; export async function queryAuditLogs(logPath: string, query: AuditQuery): Promise { const logs: AuditEvent[] = []; try { const content = await fs.readFile(logPath, 'utf-8'); const lines = content.split('\n').filter(line => line.trim() !== ''); for (const line of lines) { try { const event: AuditEvent = JSON.parse(line); if (matchesQuery(event, query)) { logs.push(event); } } catch { // Skip malformed lines } } } catch (err) { if ((err as NodeJS.ErrnoException).code !== 'ENOENT') { throw err; } } return logs.sort((a, b) => a.timestamp - b.timestamp); } function matchesQuery(event: AuditEvent, query: AuditQuery): boolean { if (query.start_time && event.timestamp < query.start_time) { return false; } if (query.end_time && event.timestamp > query.end_time) { return false; } if (query.event_types && !query.event_types.includes(event.event_type)) { return false; } if (query.level && event.level !== query.level) { return false; } if (query.session_id) { const eventSessionId = (event.event as Record).session_id as string | undefined; if (eventSessionId !== query.session_id) { return false; } } if (query.tool_name) { const eventToolName = (event.event as Record).tool_name as string | undefined; if (eventToolName !== query.tool_name) { return false; } } return true; } export async function exportAuditLogs(logPath: string, query: AuditQuery, format: 'json' | 'csv'): Promise { const logs = await queryAuditLogs(logPath, query); if (format === 'json') { return JSON.stringify(logs, null, 2); } // CSV format const headers = ['timestamp', 'level', 'event_type', 'event']; const rows = logs.map(log => { const eventStr = JSON.stringify(log.event).replace(/"/g, '""'); return `${log.timestamp},${log.level},${log.event_type},"${eventStr}"`; }); return [headers.join(','), ...rows].join('\n'); }