logging
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { hostname } from 'node:os';
|
||||
import { Repository } from 'typeorm';
|
||||
import { sanitizeContext, sanitizeString } from '../application-error-log/application-error-sanitizer';
|
||||
import { RequestContextService } from '../common/request-context.service';
|
||||
import { ApplicationInfoLog } from './application-info-log.entity';
|
||||
import { ApplicationInfoLogInput } from './application-info-log.types';
|
||||
|
||||
@Injectable()
|
||||
export class ApplicationInfoLoggerService {
|
||||
private readonly fallbackLogger = new Logger(ApplicationInfoLoggerService.name);
|
||||
|
||||
constructor(
|
||||
@InjectRepository(ApplicationInfoLog)
|
||||
private readonly logs: Repository<ApplicationInfoLog>,
|
||||
private readonly config: ConfigService,
|
||||
private readonly requestContext: RequestContextService,
|
||||
) {}
|
||||
|
||||
async log(input: ApplicationInfoLogInput): Promise<void> {
|
||||
const activeRequest = this.requestContext.get();
|
||||
const request = { ...activeRequest, ...input.requestContext };
|
||||
|
||||
try {
|
||||
await this.logs.save(
|
||||
this.logs.create({
|
||||
level: 'info',
|
||||
action: sanitizeString(input.action),
|
||||
category: optionalString(input.category),
|
||||
outcome: input.outcome ?? 'SUCCESS',
|
||||
message: optionalString(input.message),
|
||||
actorType: input.actorType,
|
||||
actorId: optionalString(input.actorId),
|
||||
userId: optionalString(input.userId ?? request.userId),
|
||||
clientId: optionalString(input.clientId),
|
||||
tenantId: optionalString(input.tenantId ?? request.tenantId),
|
||||
backendModule: optionalString(input.backendModule),
|
||||
service: optionalString(input.service),
|
||||
operation: optionalString(input.operation),
|
||||
httpMethod: optionalString(request.method),
|
||||
apiPath: optionalString(withoutQuery(request.path)),
|
||||
httpStatusCode: input.requestContext?.statusCode,
|
||||
correlationId: optionalString(request.correlationId),
|
||||
ipAddress: optionalString(input.requestContext?.ipAddress),
|
||||
userAgent: optionalString(input.requestContext?.userAgent),
|
||||
environment: this.config.get<string>('NODE_ENV') ?? 'development',
|
||||
host: hostname(),
|
||||
context: sanitizeContext(input.context),
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
this.fallbackLogger.error(
|
||||
`Application info log write failed for ${sanitizeString(input.action)}: ${sanitizeString(message)}`,
|
||||
error instanceof Error ? error.stack : undefined,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function optionalString(value?: string): string | undefined {
|
||||
return value ? sanitizeString(value) : undefined;
|
||||
}
|
||||
|
||||
function withoutQuery(value?: string): string | undefined {
|
||||
return value?.split('?', 1)[0];
|
||||
}
|
||||
Reference in New Issue
Block a user