- Add admin dashboard with sync controls and data browser - Implement RMM, Auvik, and Addigy organization mappings - Add chunked ticket sync with progress tracking - Implement entity sync service with rate limiting - Add analytics engine and performance optimizer - Create data browser for all PSA entities - Add navigation components and UI improvements - Implement background processing and sync services - Add comprehensive documentation and migration scripts - Update configuration items with multi-system support - Enhance contact management and purchase history - Add issue type assignment and LLM analyzer - Improve error handling and logging utilities
140 lines
3 KiB
TypeScript
140 lines
3 KiB
TypeScript
/**
|
|
* Logger Utility
|
|
* Provides structured logging for sync operations
|
|
*/
|
|
|
|
export enum LogLevel {
|
|
DEBUG = 'DEBUG',
|
|
INFO = 'INFO',
|
|
WARN = 'WARN',
|
|
ERROR = 'ERROR',
|
|
}
|
|
|
|
export interface LogContext {
|
|
syncId?: string;
|
|
entity?: string;
|
|
operation?: string;
|
|
duration?: number;
|
|
recordCount?: number;
|
|
[key: string]: any;
|
|
}
|
|
|
|
/**
|
|
* Logger class for structured logging
|
|
*/
|
|
export class Logger {
|
|
private context: LogContext;
|
|
private minLevel: LogLevel;
|
|
|
|
constructor(context: LogContext = {}, minLevel: LogLevel = LogLevel.INFO) {
|
|
this.context = context;
|
|
this.minLevel = minLevel;
|
|
}
|
|
|
|
/**
|
|
* Create a child logger with additional context
|
|
*/
|
|
child(additionalContext: LogContext): Logger {
|
|
return new Logger({ ...this.context, ...additionalContext }, this.minLevel);
|
|
}
|
|
|
|
/**
|
|
* Log debug message
|
|
*/
|
|
debug(message: string, data?: any): void {
|
|
this.log(LogLevel.DEBUG, message, data);
|
|
}
|
|
|
|
/**
|
|
* Log info message
|
|
*/
|
|
info(message: string, data?: any): void {
|
|
this.log(LogLevel.INFO, message, data);
|
|
}
|
|
|
|
/**
|
|
* Log warning message
|
|
*/
|
|
warn(message: string, data?: any): void {
|
|
this.log(LogLevel.WARN, message, data);
|
|
}
|
|
|
|
/**
|
|
* Log error message
|
|
*/
|
|
error(message: string, error?: Error | any, data?: any): void {
|
|
const errorData = {
|
|
...data,
|
|
error: error instanceof Error ? {
|
|
message: error.message,
|
|
stack: error.stack,
|
|
name: error.name,
|
|
} : error,
|
|
};
|
|
this.log(LogLevel.ERROR, message, errorData);
|
|
}
|
|
|
|
/**
|
|
* Internal log method
|
|
*/
|
|
private log(level: LogLevel, message: string, data?: any): void {
|
|
if (!this.shouldLog(level)) {
|
|
return;
|
|
}
|
|
|
|
const timestamp = new Date().toISOString();
|
|
const contextStr = Object.keys(this.context).length > 0
|
|
? ` [${this.formatContext()}]`
|
|
: '';
|
|
|
|
const logMessage = `[${timestamp}] [${level}]${contextStr} ${message}`;
|
|
|
|
switch (level) {
|
|
case LogLevel.DEBUG:
|
|
console.debug(logMessage, data || '');
|
|
break;
|
|
case LogLevel.INFO:
|
|
console.log(logMessage, data || '');
|
|
break;
|
|
case LogLevel.WARN:
|
|
console.warn(logMessage, data || '');
|
|
break;
|
|
case LogLevel.ERROR:
|
|
console.error(logMessage, data || '');
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if log level should be logged
|
|
*/
|
|
private shouldLog(level: LogLevel): boolean {
|
|
const levels = [LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARN, LogLevel.ERROR];
|
|
const currentIndex = levels.indexOf(this.minLevel);
|
|
const messageIndex = levels.indexOf(level);
|
|
return messageIndex >= currentIndex;
|
|
}
|
|
|
|
/**
|
|
* Format context for logging
|
|
*/
|
|
private formatContext(): string {
|
|
return Object.entries(this.context)
|
|
.map(([key, value]) => `${key}=${value}`)
|
|
.join(', ');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create a logger instance
|
|
*/
|
|
export function createLogger(context?: LogContext, minLevel?: LogLevel): Logger {
|
|
return new Logger(context, minLevel);
|
|
}
|
|
|
|
/**
|
|
* Default logger instance
|
|
*/
|
|
export const logger = new Logger();
|
|
|
|
export default logger;
|