nestjs-universal-logger-v2
Version:
Universal logging package for NestJS - Automatic system-wide logging with per-service MongoDB collections and TTL-based cleanup
170 lines (169 loc) • 7.01 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.logEntrySchema = exports.LogEntrySchema = void 0;
exports.createLogEntrySchema = createLogEntrySchema;
exports.getLogCollectionName = getLogCollectionName;
exports.addTTLIndexToSchema = addTTLIndexToSchema;
const mongoose_1 = require("@nestjs/mongoose");
let LogEntrySchema = class LogEntrySchema {
};
exports.LogEntrySchema = LogEntrySchema;
__decorate([
(0, mongoose_1.Prop)({ required: true, unique: true }),
__metadata("design:type", String)
], LogEntrySchema.prototype, "id", void 0);
__decorate([
(0, mongoose_1.Prop)({ required: true, index: true }),
__metadata("design:type", Date)
], LogEntrySchema.prototype, "timestamp", void 0);
__decorate([
(0, mongoose_1.Prop)({ required: true, enum: ['error', 'warn', 'info', 'debug', 'verbose'], index: true }),
__metadata("design:type", String)
], LogEntrySchema.prototype, "level", void 0);
__decorate([
(0, mongoose_1.Prop)({ required: true, index: true }),
__metadata("design:type", String)
], LogEntrySchema.prototype, "service", void 0);
__decorate([
(0, mongoose_1.Prop)({ index: true }),
__metadata("design:type", String)
], LogEntrySchema.prototype, "module", void 0);
__decorate([
(0, mongoose_1.Prop)(),
__metadata("design:type", String)
], LogEntrySchema.prototype, "method", void 0);
__decorate([
(0, mongoose_1.Prop)({ required: true }),
__metadata("design:type", String)
], LogEntrySchema.prototype, "message", void 0);
__decorate([
(0, mongoose_1.Prop)(),
__metadata("design:type", String)
], LogEntrySchema.prototype, "trace", void 0);
__decorate([
(0, mongoose_1.Prop)({ type: Object }),
__metadata("design:type", Object)
], LogEntrySchema.prototype, "metadata", void 0);
__decorate([
(0, mongoose_1.Prop)({ index: true }),
__metadata("design:type", String)
], LogEntrySchema.prototype, "userId", void 0);
__decorate([
(0, mongoose_1.Prop)(),
__metadata("design:type", String)
], LogEntrySchema.prototype, "sessionId", void 0);
__decorate([
(0, mongoose_1.Prop)({ index: true }),
__metadata("design:type", String)
], LogEntrySchema.prototype, "requestId", void 0);
__decorate([
(0, mongoose_1.Prop)(),
__metadata("design:type", String)
], LogEntrySchema.prototype, "ip", void 0);
__decorate([
(0, mongoose_1.Prop)(),
__metadata("design:type", String)
], LogEntrySchema.prototype, "userAgent", void 0);
__decorate([
(0, mongoose_1.Prop)(),
__metadata("design:type", Number)
], LogEntrySchema.prototype, "duration", void 0);
__decorate([
(0, mongoose_1.Prop)({ index: true }),
__metadata("design:type", Number)
], LogEntrySchema.prototype, "statusCode", void 0);
__decorate([
(0, mongoose_1.Prop)(),
__metadata("design:type", String)
], LogEntrySchema.prototype, "errorCode", void 0);
__decorate([
(0, mongoose_1.Prop)({ type: [String], index: true }),
__metadata("design:type", Array)
], LogEntrySchema.prototype, "tags", void 0);
__decorate([
(0, mongoose_1.Prop)({ enum: ['low', 'medium', 'high', 'critical'], index: true }),
__metadata("design:type", String)
], LogEntrySchema.prototype, "severity", void 0);
__decorate([
(0, mongoose_1.Prop)({ required: true, index: true }),
__metadata("design:type", String)
], LogEntrySchema.prototype, "environment", void 0);
__decorate([
(0, mongoose_1.Prop)(),
__metadata("design:type", String)
], LogEntrySchema.prototype, "version", void 0);
__decorate([
(0, mongoose_1.Prop)({ type: Object }),
__metadata("design:type", Object)
], LogEntrySchema.prototype, "apiCall", void 0);
__decorate([
(0, mongoose_1.Prop)({ type: Object }),
__metadata("design:type", Object)
], LogEntrySchema.prototype, "performance", void 0);
exports.LogEntrySchema = LogEntrySchema = __decorate([
(0, mongoose_1.Schema)({
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
})
], LogEntrySchema);
exports.logEntrySchema = mongoose_1.SchemaFactory.createForClass(LogEntrySchema);
function createLogEntrySchema(serviceName, ttlConfig) {
const schema = mongoose_1.SchemaFactory.createForClass(LogEntrySchema);
const collectionName = `logs_${serviceName.toLowerCase().replace(/[^a-z0-9]/g, '_')}`;
schema.set('collection', collectionName);
schema.index({ timestamp: -1 });
schema.index({ service: 1, timestamp: -1 });
schema.index({ level: 1, timestamp: -1 });
schema.index({ severity: 1, timestamp: -1 });
schema.index({ userId: 1, timestamp: -1 });
schema.index({ requestId: 1 });
schema.index({ tags: 1 });
schema.index({ environment: 1, timestamp: -1 });
schema.index({ 'apiCall.path': 1, timestamp: -1 });
schema.index({ 'apiCall.method': 1, timestamp: -1 });
schema.index({ statusCode: 1, timestamp: -1 });
if (ttlConfig?.enabled && ttlConfig.expireAfterSeconds) {
const indexField = ttlConfig.indexField || 'timestamp';
const ttlIndexOptions = { expireAfterSeconds: ttlConfig.expireAfterSeconds };
switch (indexField) {
case 'created_at':
schema.index({ created_at: 1 }, ttlIndexOptions);
break;
case 'updated_at':
schema.index({ updated_at: 1 }, ttlIndexOptions);
break;
default:
schema.index({ timestamp: 1 }, ttlIndexOptions);
break;
}
}
return schema;
}
function getLogCollectionName(serviceName) {
return `logs_${serviceName.toLowerCase().replace(/[^a-z0-9]/g, '_')}`;
}
function addTTLIndexToSchema(schema, ttlConfig) {
if (ttlConfig?.enabled && ttlConfig.expireAfterSeconds) {
const indexField = ttlConfig.indexField || 'timestamp';
const ttlIndexOptions = { expireAfterSeconds: ttlConfig.expireAfterSeconds };
switch (indexField) {
case 'created_at':
schema.index({ created_at: 1 }, ttlIndexOptions);
break;
case 'updated_at':
schema.index({ updated_at: 1 }, ttlIndexOptions);
break;
default:
schema.index({ timestamp: 1 }, ttlIndexOptions);
break;
}
}
}