audit-logger.service.ts•2.51 kB
import { Injectable } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';
interface AuditLog {
timestamp: string;
operation: string;
tableName: string;
beforeData?: any;
afterData?: any;
sql?: string;
params?: any[];
success: boolean;
error?: string;
}
@Injectable()
export class AuditLoggerService {
private logPath: string;
constructor() {
this.logPath = path.join(process.cwd(), 'logs', 'audit.log');
this.ensureLogDirectory();
}
private ensureLogDirectory() {
const logDir = path.dirname(this.logPath);
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, { recursive: true });
}
}
async logOperation(log: AuditLog) {
const logEntry = {
...log,
timestamp: new Date().toISOString(),
};
const logLine = JSON.stringify(logEntry) + '\n';
try {
fs.appendFileSync(this.logPath, logLine, 'utf8');
console.log('📝 Audit Log:', logEntry);
} catch (error) {
console.error('Failed to write audit log:', error);
}
}
async logQuery(tableName: string, sql: string, params: any[], result: any) {
await this.logOperation({
timestamp: new Date().toISOString(),
operation: 'SELECT',
tableName,
sql,
params,
afterData: { rowCount: result.length },
success: true,
});
}
async logInsert(tableName: string, data: any, result: any) {
await this.logOperation({
timestamp: new Date().toISOString(),
operation: 'INSERT',
tableName,
beforeData: null,
afterData: { insertId: result.insertId, data },
success: true,
});
}
async logUpdate(tableName: string, data: any, where: any, beforeData: any, result: any) {
await this.logOperation({
timestamp: new Date().toISOString(),
operation: 'UPDATE',
tableName,
beforeData,
afterData: { ...data, affectedRows: result.affectedRows },
success: true,
});
}
async logDelete(tableName: string, where: any, beforeData: any, result: any) {
await this.logOperation({
timestamp: new Date().toISOString(),
operation: 'DELETE',
tableName,
beforeData,
afterData: { affectedRows: result.affectedRows },
success: true,
});
}
async logError(operation: string, tableName: string, error: string) {
await this.logOperation({
timestamp: new Date().toISOString(),
operation,
tableName,
success: false,
error,
});
}
}