nestjs-auditlog
Version:
A powerful package for auditlog using opentelemetry in NestJS applications
133 lines • 9.86 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuditlogClickHouseExporter = void 0;
const client_1 = require("@clickhouse/client");
class AuditlogClickHouseExporter {
constructor(options) {
var _a, _b;
this.options = options;
this.databaseName = (_a = options.databaseName) !== null && _a !== void 0 ? _a : 'auditlog';
this.client = options.clickHouseClient;
this.auditLogTableName = 'audit_logs';
this.logExpired = (_b = options.logExpired) !== null && _b !== void 0 ? _b : 180;
}
clone() {
return new AuditlogClickHouseExporter(this.options);
}
createClickhouseClient() {
return (0, client_1.createClient)({
url: this.options.clickHouseUrl || 'http://localhost:8123',
database: this.databaseName,
clickhouse_settings: {
async_insert: 1,
},
});
}
getClient() {
return this.client;
}
async startup() {
var _a;
if (!this.client) {
this.client = this.createClickhouseClient();
}
try {
// setup table
await ((_a = this.getClient()) === null || _a === void 0 ? void 0 : _a.query({
query: `
CREATE TABLE IF NOT EXISTS ${this.auditLogTableName} (
service_name String,
service_namespace String,
service_env String,
resource_id String,
resource_type String,
resource_data_before String,
resource_data_after String,
resource_data_diff String,
operation_id String,
operation_type String,
operation_status String,
actor_id String,
actor_type String,
actor_ip String,
actor_agent String,
message String,
created_at DateTime
) ENGINE = MergeTree
PRIMARY KEY (service_name, service_namespace, service_env, created_at, actor_id, operation_type)
TTL created_at + toIntervalDay(${this.logExpired})
PARTITION BY toYYYYMM(created_at)
ORDER BY (service_name, service_namespace, service_env, created_at, actor_id, operation_type)
SETTINGS index_granularity = 8192
`,
}));
}
catch (ex) {
console.error(ex);
}
}
async shutdown() {
var _a;
await ((_a = this.getClient()) === null || _a === void 0 ? void 0 : _a.close());
}
async sendAuditLog(log) {
var _a, _b, _c, _d;
try {
const values = [
{
service_name: this.options.serviceName,
service_namespace: this.options.serviceNamespace,
service_env: this.options.serviceEnvironmentName,
resource_id: log.resource.id,
resource_type: log.resource.type,
resource_data_before: JSON.stringify((_a = log.data_diff) === null || _a === void 0 ? void 0 : _a.before),
resource_data_after: JSON.stringify((_b = log.data_diff) === null || _b === void 0 ? void 0 : _b.after),
resource_data_diff: JSON.stringify((_c = log.data_diff) === null || _c === void 0 ? void 0 : _c.diff),
operation_id: log.operation.id,
operation_type: log.operation.type,
operation_status: log.operation.status,
actor_id: log.actor.id,
actor_type: log.actor.type,
actor_ip: log.actor.ip,
actor_agent: log.actor.agent,
message: this.customLoggerBodyTransformation(log),
created_at: this.formatDateToUTC(new Date()),
},
];
await ((_d = this.getClient()) === null || _d === void 0 ? void 0 : _d.insert({
table: this.auditLogTableName,
values: values,
format: 'JSONEachRow',
}));
}
catch (ex) {
console.error(ex);
}
}
/**
* the transformation function to convert audit log object to readable log body string
*
* @param log audit log
* @returns log body
*/
customLoggerBodyTransformation(log) {
const resourceId = Array.isArray(log.resource.id)
? log.resource.id.join(',')
: log.resource.id;
return `The actor ${log.actor.type} ${log.actor.id} did the operator ${log.operation.type} ${log.operation.id} on the resource ${log.resource.type} ${resourceId}`;
}
padTo2Digits(num) {
return num.toString().padStart(2, '0');
}
formatDateToUTC(date) {
const year = date.getUTCFullYear();
const month = this.padTo2Digits(date.getUTCMonth() + 1); // Months are zero-based
const day = this.padTo2Digits(date.getUTCDate());
const hours = this.padTo2Digits(date.getUTCHours());
const minutes = this.padTo2Digits(date.getUTCMinutes());
const seconds = this.padTo2Digits(date.getUTCSeconds());
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
}
exports.AuditlogClickHouseExporter = AuditlogClickHouseExporter;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaXRsb2cuY2xpY2tob3VzZS5leHBvcnRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvbW9kdWxlcy9hdWRpdC1sb2cvZXhwb3J0ZXJzL2F1ZGl0bG9nLmNsaWNraG91c2UuZXhwb3J0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0NBQW9FO0FBUXBFLE1BQWEsMEJBQTBCO0lBT3JDLFlBQVksT0FBMEM7O1FBQ3BELElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxZQUFZLEdBQUcsTUFBQSxPQUFPLENBQUMsWUFBWSxtQ0FBSSxVQUFVLENBQUM7UUFDdkQsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7UUFDdkMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLFlBQVksQ0FBQztRQUN0QyxJQUFJLENBQUMsVUFBVSxHQUFHLE1BQUEsT0FBTyxDQUFDLFVBQVUsbUNBQUksR0FBRyxDQUFDO0lBQzlDLENBQUM7SUFFRCxLQUFLO1FBQ0gsT0FBTyxJQUFJLDBCQUEwQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQsc0JBQXNCO1FBQ3BCLE9BQU8sSUFBQSxxQkFBWSxFQUFDO1lBQ2xCLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsSUFBSSx1QkFBdUI7WUFDMUQsUUFBUSxFQUFFLElBQUksQ0FBQyxZQUFZO1lBQzNCLG1CQUFtQixFQUFFO2dCQUNuQixZQUFZLEVBQUUsQ0FBQzthQUNoQjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxTQUFTO1FBQ1AsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxLQUFLLENBQUMsT0FBTzs7UUFDWCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNoQixJQUFJLENBQUMsTUFBTSxHQUFH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