@gftdcojp/ksqldb-orm
Version:
ksqldb-orm - Server-Side TypeScript ORM for ksqlDB with enterprise security extensions
199 lines • 6.61 kB
JavaScript
;
/**
* @fileoverview 監査ログ機能を管理
* @description データベース操作の監査ログを記録、管理します
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.auditLog = exports.AuditLogManager = void 0;
const logger_1 = require("./utils/logger");
/**
* 監査ログマネージャー
* ksqlDBの操作を追跡・記録するための機能を提供
*/
class AuditLogManager {
constructor(options = {}) {
this.logs = [];
this.options = {
enableConsoleOutput: true,
enableFileOutput: false,
logLevel: 'info',
retentionDays: 30,
...options
};
}
/**
* シングルトンインスタンスを取得
*/
static getInstance(options) {
if (!AuditLogManager.instance) {
AuditLogManager.instance = new AuditLogManager(options);
}
return AuditLogManager.instance;
}
/**
* 監査ログエントリを記録
*/
logOperation(entry) {
const auditEntry = {
id: `audit_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
timestamp: new Date(),
...entry
};
this.logs.push(auditEntry);
// コンソール出力
if (this.options.enableConsoleOutput) {
const logMessage = `AUDIT: ${auditEntry.operation} on ${auditEntry.tableName || 'N/A'} by ${auditEntry.userId || 'anonymous'} - ${auditEntry.success ? 'SUCCESS' : 'FAILED'}`;
if (auditEntry.success) {
logger_1.log.info(logMessage);
}
else {
logger_1.log.error(`${logMessage} - Error: ${auditEntry.errorMessage}`);
}
}
// 古いログのクリーンアップ
this.cleanupOldLogs();
return auditEntry;
}
/**
* 成功した操作をログ
*/
logSuccess(operation, options = {}) {
return this.logOperation({
operation,
success: true,
...options
});
}
/**
* 失敗した操作をログ
*/
logFailure(operation, errorMessage, options = {}) {
return this.logOperation({
operation,
success: false,
errorMessage,
...options
});
}
/**
* ユーザーの操作履歴を取得
*/
getUserAuditLogs(userId, limit) {
const userLogs = this.logs
.filter(entry => entry.userId === userId)
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
return limit ? userLogs.slice(0, limit) : userLogs;
}
/**
* テーブルの操作履歴を取得
*/
getTableAuditLogs(tableName, limit) {
const tableLogs = this.logs
.filter(entry => entry.tableName === tableName)
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
return limit ? tableLogs.slice(0, limit) : tableLogs;
}
/**
* 期間内の監査ログを取得
*/
getAuditLogsByDateRange(startDate, endDate) {
return this.logs
.filter(entry => entry.timestamp >= startDate && entry.timestamp <= endDate)
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
}
/**
* 失敗した操作のログを取得
*/
getFailedOperations(limit) {
const failedLogs = this.logs
.filter(entry => !entry.success)
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
return limit ? failedLogs.slice(0, limit) : failedLogs;
}
/**
* 監査ログ統計情報を取得
*/
getAuditStatistics() {
const totalOperations = this.logs.length;
const successfulOperations = this.logs.filter(entry => entry.success).length;
const failedOperations = totalOperations - successfulOperations;
const successRate = totalOperations > 0 ? (successfulOperations / totalOperations) * 100 : 0;
const operationsByType = {};
const operationsByUser = {};
this.logs.forEach(entry => {
// 操作タイプ別の集計
operationsByType[entry.operation] = (operationsByType[entry.operation] || 0) + 1;
// ユーザー別の集計
const userId = entry.userId || 'anonymous';
operationsByUser[userId] = (operationsByUser[userId] || 0) + 1;
});
return {
totalOperations,
successfulOperations,
failedOperations,
successRate,
operationsByType,
operationsByUser
};
}
/**
* 古いログをクリーンアップ
*/
cleanupOldLogs() {
if (!this.options.retentionDays)
return;
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - this.options.retentionDays);
const initialLogCount = this.logs.length;
this.logs = this.logs.filter(entry => entry.timestamp >= cutoffDate);
const removedCount = initialLogCount - this.logs.length;
if (removedCount > 0) {
logger_1.log.info(`Cleaned up ${removedCount} old audit log entries`);
}
}
/**
* 監査ログをクリア(開発用)
*/
clearAuditLogs() {
const logCount = this.logs.length;
this.logs = [];
logger_1.log.warn(`Cleared ${logCount} audit log entries`);
}
/**
* 監査ログをJSON形式でエクスポート
*/
exportAuditLogs(startDate, endDate) {
let logsToExport = this.logs;
if (startDate || endDate) {
logsToExport = this.getAuditLogsByDateRange(startDate || new Date(0), endDate || new Date());
}
return JSON.stringify(logsToExport, null, 2);
}
}
exports.AuditLogManager = AuditLogManager;
AuditLogManager.instance = null;
/**
* 便利関数のエクスポート
*/
exports.auditLog = {
/**
* 成功操作をログ
*/
success: (operation, options) => {
return AuditLogManager.getInstance().logSuccess(operation, options);
},
/**
* 失敗操作をログ
*/
failure: (operation, errorMessage, options) => {
return AuditLogManager.getInstance().logFailure(operation, errorMessage, options);
},
/**
* マネージャーインスタンスを取得
*/
getManager: (options) => {
return AuditLogManager.getInstance(options);
}
};
exports.default = AuditLogManager;
//# sourceMappingURL=audit-log.js.map