mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Enhanced logging functionality with improved context handling and documentation.
- ✨ **Feature**: Added support for hierarchical logger context - 🛠️ **Refactor**: Updated logging methods to use LoggerContext - 📚 **Docs**: Improved documentation for logger methods and context
This commit is contained in:
@@ -22,22 +22,48 @@ export function logger(): LoggerApi {
|
||||
// Return an object with methods that forward to the logging service
|
||||
// with the provided context
|
||||
return {
|
||||
trace: (message: string, additionalContext?: unknown): void => {
|
||||
/**
|
||||
* Logs trace information with optional additional context.
|
||||
* @param message The log message.
|
||||
* @param additionalContext Optional context data specific to this log message.
|
||||
*/
|
||||
trace: (message: string, additionalContext?: LoggerContext): void => {
|
||||
loggingService.trace(message, mergeContexts(context, additionalContext));
|
||||
},
|
||||
debug: (message: string, additionalContext?: unknown): void => {
|
||||
/**
|
||||
* Logs debug information with optional additional context.
|
||||
* @param message The log message.
|
||||
* @param additionalContext Optional context data specific to this log message.
|
||||
*/
|
||||
debug: (message: string, additionalContext?: LoggerContext): void => {
|
||||
loggingService.debug(message, mergeContexts(context, additionalContext));
|
||||
},
|
||||
info: (message: string, additionalContext?: unknown): void => {
|
||||
/**
|
||||
* Logs informational messages with optional additional context.
|
||||
* @param message The log message.
|
||||
* @param additionalContext Optional context data specific to this log message.
|
||||
*/
|
||||
info: (message: string, additionalContext?: LoggerContext): void => {
|
||||
loggingService.info(message, mergeContexts(context, additionalContext));
|
||||
},
|
||||
warn: (message: string, additionalContext?: unknown): void => {
|
||||
/**
|
||||
* Logs warning messages with optional additional context.
|
||||
* @param message The log message.
|
||||
* @param additionalContext Optional context data specific to this log message.
|
||||
*/
|
||||
warn: (message: string, additionalContext?: LoggerContext): void => {
|
||||
loggingService.warn(message, mergeContexts(context, additionalContext));
|
||||
},
|
||||
/**
|
||||
* Logs error messages with optional error object and additional context.
|
||||
* @param message The log message.
|
||||
* @param error Optional error object.
|
||||
* @param additionalContext Optional context data specific to this log message.
|
||||
*/
|
||||
error: (
|
||||
message: string,
|
||||
error?: Error,
|
||||
additionalContext?: unknown,
|
||||
additionalContext?: LoggerContext,
|
||||
): void => {
|
||||
loggingService.error(
|
||||
message,
|
||||
@@ -49,35 +75,24 @@ export function logger(): LoggerApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges component-level context with message-specific context.
|
||||
* @param baseContext The component-level context.
|
||||
* @param additionalContext The message-specific context.
|
||||
* @returns The merged context.
|
||||
* Merges component-level context (potentially multiple contexts) with message-specific context.
|
||||
* @param baseContext The array of component-level contexts provided via `provideLoggerContext`.
|
||||
* @param additionalContext The message-specific context provided in the log call.
|
||||
* @returns The merged context object containing properties from all provided contexts.
|
||||
*/
|
||||
function mergeContexts(
|
||||
baseContext?: LoggerContext | null,
|
||||
additionalContext?: unknown,
|
||||
): unknown {
|
||||
if (!baseContext) {
|
||||
return additionalContext;
|
||||
baseContext: LoggerContext[] | null,
|
||||
additionalContext?: LoggerContext,
|
||||
): LoggerContext {
|
||||
const contextArray = Array.isArray(baseContext) ? baseContext : [];
|
||||
|
||||
if (typeof additionalContext === 'object') {
|
||||
contextArray.push(additionalContext);
|
||||
}
|
||||
|
||||
if (!additionalContext) {
|
||||
return baseContext;
|
||||
if (!contextArray.length) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// If both contexts are objects, merge them
|
||||
if (
|
||||
typeof additionalContext === 'object' &&
|
||||
additionalContext !== null &&
|
||||
!Array.isArray(additionalContext)
|
||||
) {
|
||||
return { ...baseContext, ...additionalContext };
|
||||
}
|
||||
|
||||
// If not both objects, return them separately
|
||||
return {
|
||||
baseContext,
|
||||
additionalContext,
|
||||
};
|
||||
return contextArray.reduce((acc, context) => ({ ...acc, ...context }), {});
|
||||
}
|
||||
|
||||
@@ -12,7 +12,11 @@ import { LoggerContext, LoggingConfig, Sink, SinkFn } from './logging.types';
|
||||
|
||||
// Injection tokens for the Logger API
|
||||
export const LOGGER_CONFIG = new InjectionToken<LoggingConfig>('LOGGER_CONFIG');
|
||||
export const LOGGER_CONTEXT = new InjectionToken<LoggerContext>(
|
||||
/**
|
||||
* Injection token for providing hierarchical logger context.
|
||||
* Allows multiple contexts to be provided and merged.
|
||||
*/
|
||||
export const LOGGER_CONTEXT = new InjectionToken<LoggerContext[]>(
|
||||
'LOGGER_CONTEXT',
|
||||
);
|
||||
|
||||
@@ -113,14 +117,16 @@ export function provideLogging(
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a context object for logging within a specific component or module
|
||||
* @param context The context object to provide
|
||||
* Provides a context object for logging within a specific component or module scope.
|
||||
* Multiple contexts can be provided at different levels and will be merged.
|
||||
* @param context The context object to provide for this scope.
|
||||
*/
|
||||
export function provideLoggerContext(context: LoggerContext): Provider[] {
|
||||
return [
|
||||
{
|
||||
provide: LOGGER_CONTEXT,
|
||||
useValue: context,
|
||||
multi: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { LogLevel } from './log-level.enum';
|
||||
import { LoggerApi, LoggingConfig, Sink, SinkFn } from './logging.types';
|
||||
import {
|
||||
LoggerApi,
|
||||
LoggerContext,
|
||||
LoggingConfig,
|
||||
Sink,
|
||||
SinkFn,
|
||||
} from './logging.types';
|
||||
|
||||
/**
|
||||
* The main service for logging functionality.
|
||||
@@ -10,9 +16,14 @@ import { LoggerApi, LoggingConfig, Sink, SinkFn } from './logging.types';
|
||||
export class LoggingService implements LoggerApi {
|
||||
private level: LogLevel = LogLevel.Info; // Default level
|
||||
private sinks: Array<
|
||||
(level: LogLevel, message: string, context?: unknown, error?: Error) => void
|
||||
(
|
||||
level: LogLevel,
|
||||
message: string,
|
||||
context?: LoggerContext,
|
||||
error?: Error,
|
||||
) => void
|
||||
> = [];
|
||||
private globalContext?: Record<string, unknown>;
|
||||
private globalContext?: LoggerContext;
|
||||
|
||||
// Cache log level indexes for performance
|
||||
private readonly LOG_LEVEL_ORDER: Record<LogLevel, number> = {
|
||||
@@ -26,7 +37,7 @@ export class LoggingService implements LoggerApi {
|
||||
|
||||
/**
|
||||
* Configures the logging service with the provided options.
|
||||
* @param config The logging configuration options.
|
||||
* @param config The logging configuration options, including level, sinks, and global context.
|
||||
*/
|
||||
configure(config: LoggingConfig): void {
|
||||
this.level = config.level;
|
||||
@@ -55,36 +66,36 @@ export class LoggingService implements LoggerApi {
|
||||
/**
|
||||
* Logs trace information.
|
||||
* @param message The log message.
|
||||
* @param context Optional context data.
|
||||
* @param context Optional context data specific to this log message.
|
||||
*/
|
||||
trace(message: string, context?: unknown): void {
|
||||
trace(message: string, context?: LoggerContext): void {
|
||||
this.log(LogLevel.Trace, message, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs debug information.
|
||||
* @param message The log message.
|
||||
* @param context Optional context data.
|
||||
* @param context Optional context data specific to this log message.
|
||||
*/
|
||||
debug(message: string, context?: unknown): void {
|
||||
debug(message: string, context?: LoggerContext): void {
|
||||
this.log(LogLevel.Debug, message, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs informational messages.
|
||||
* @param message The log message.
|
||||
* @param context Optional context data.
|
||||
* @param context Optional context data specific to this log message.
|
||||
*/
|
||||
info(message: string, context?: unknown): void {
|
||||
info(message: string, context?: LoggerContext): void {
|
||||
this.log(LogLevel.Info, message, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs warning messages.
|
||||
* @param message The log message.
|
||||
* @param context Optional context data.
|
||||
* @param context Optional context data specific to this log message.
|
||||
*/
|
||||
warn(message: string, context?: unknown): void {
|
||||
warn(message: string, context?: LoggerContext): void {
|
||||
this.log(LogLevel.Warn, message, context);
|
||||
}
|
||||
|
||||
@@ -92,23 +103,23 @@ export class LoggingService implements LoggerApi {
|
||||
* Logs error messages.
|
||||
* @param message The log message.
|
||||
* @param error Optional error object.
|
||||
* @param context Optional context data.
|
||||
* @param context Optional context data specific to this log message.
|
||||
*/
|
||||
error(message: string, error?: Error, context?: unknown): void {
|
||||
error(message: string, error?: Error, context?: LoggerContext): void {
|
||||
this.log(LogLevel.Error, message, context, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to handle logging with level filtering.
|
||||
* Internal method to handle logging with level filtering and context merging.
|
||||
* @param level The log level.
|
||||
* @param message The log message.
|
||||
* @param context Optional context data.
|
||||
* @param context Optional context data specific to this log message.
|
||||
* @param error Optional error object.
|
||||
*/
|
||||
private log(
|
||||
level: LogLevel,
|
||||
message: string,
|
||||
context?: unknown,
|
||||
context?: LoggerContext,
|
||||
error?: Error,
|
||||
): void {
|
||||
// Short-circuit if logging is disabled or level is too low (performance optimization)
|
||||
@@ -152,13 +163,13 @@ export class LoggingService implements LoggerApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the global context with the provided context.
|
||||
* @param context The context provided in the log call.
|
||||
* @returns The merged context object.
|
||||
* Merges the global context (if configured) with the context provided in the log call.
|
||||
* @param context The context provided in the specific log call.
|
||||
* @returns The merged context object. If both global and specific contexts exist, they are merged with specific context properties overwriting global ones.
|
||||
*/
|
||||
private mergeContext(context?: unknown): unknown {
|
||||
private mergeContext(context?: LoggerContext): LoggerContext {
|
||||
if (!this.globalContext) {
|
||||
return context;
|
||||
return context || {};
|
||||
}
|
||||
|
||||
if (!context) {
|
||||
|
||||
@@ -5,16 +5,30 @@ import { Type } from '@angular/core';
|
||||
* Represents a destination where log messages are sent.
|
||||
*/
|
||||
export interface Sink {
|
||||
log(level: LogLevel, message: string, context?: unknown, error?: Error): void;
|
||||
/**
|
||||
* Method called by the LoggingService to send a log entry to this sink.
|
||||
* @param level The log level of the message.
|
||||
* @param message The log message string.
|
||||
* @param context Optional context data associated with the log message.
|
||||
* @param error Optional error object associated with the log message.
|
||||
*/
|
||||
log(
|
||||
level: LogLevel,
|
||||
message: string,
|
||||
context?: LoggerContext,
|
||||
error?: Error,
|
||||
): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function implementation of a Sink.
|
||||
* A factory function that returns a logging function conforming to the Sink interface.
|
||||
* Allows for dependency injection or setup logic within the factory.
|
||||
* @returns A function that handles logging a message.
|
||||
*/
|
||||
export type SinkFn = () => (
|
||||
level: LogLevel,
|
||||
message: string,
|
||||
context?: unknown,
|
||||
context?: LoggerContext,
|
||||
error?: Error,
|
||||
) => void;
|
||||
|
||||
@@ -22,24 +36,33 @@ export type SinkFn = () => (
|
||||
* Configuration options for the logging service.
|
||||
*/
|
||||
export interface LoggingConfig {
|
||||
/** The minimum log level to process. */
|
||||
level: LogLevel;
|
||||
/** An array of sinks (instances, classes, or factory functions) to send logs to. */
|
||||
sinks: (Sink | SinkFn | Type<Sink>)[];
|
||||
context?: Record<string, unknown>;
|
||||
/** Optional global context to be included with every log message. */
|
||||
context?: LoggerContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the logger API for logging operations.
|
||||
* Represents the public API for logging operations provided by the logger factory.
|
||||
*/
|
||||
export interface LoggerApi {
|
||||
trace(message: string, context?: unknown): void;
|
||||
debug(message: string, context?: unknown): void;
|
||||
info(message: string, context?: unknown): void;
|
||||
warn(message: string, context?: unknown): void;
|
||||
error(message: string, error?: Error, context?: unknown): void;
|
||||
/** Logs a trace message with optional context. */
|
||||
trace(message: string, context?: LoggerContext): void;
|
||||
/** Logs a debug message with optional context. */
|
||||
debug(message: string, context?: LoggerContext): void;
|
||||
/** Logs an info message with optional context. */
|
||||
info(message: string, context?: LoggerContext): void;
|
||||
/** Logs a warning message with optional context. */
|
||||
warn(message: string, context?: LoggerContext): void;
|
||||
/** Logs an error message with an optional error object and context. */
|
||||
error(message: string, error?: Error, context?: LoggerContext): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logger context for context-aware logging.
|
||||
* Represents context data associated with a log message.
|
||||
* It's an object where keys are strings and values can be of any type.
|
||||
*/
|
||||
export interface LoggerContext {
|
||||
[key: string]: unknown;
|
||||
|
||||
Reference in New Issue
Block a user