All files / src/lib/core logger.ts

100% Statements 133/133
100% Branches 26/26
100% Functions 9/9
100% Lines 133/133

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 1341x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 24x 24x 24x 24x 24x 24x 24x 24x 8x 8x 24x 24x 24x 1x 1x 1x 1x 12x 12x 12x 12x 12x 1x 1x 1x 1x 4x 4x 4x 4x 1x 1x 1x 1x 4x 4x 4x 4x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 4x 1x 1x 1x 1x 6x 6x 4x 4x 4x 4x 6x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 1x 1x 1x 1x 3x 3x 3x 3x 1x 1x 1x 1x 2x 2x 2x 2x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
/**
 * Simple logging utility for the application
 * Provides consistent timestamp and context formatting
 */
 
type LogLevel = "INFO" | "WARN" | "ERROR" | "DEBUG";
 
interface LogEntry {
  timestamp: string;
  level: LogLevel;
  context: string;
  message: string;
  data?: unknown;
}
 
/**
 * Format log entry with timestamp and context
 */
function formatLogEntry(level: LogLevel, context: string, message: string, data?: unknown): LogEntry {
  const entry: LogEntry = {
    timestamp: new Date().toISOString(),
    level,
    context,
    message};
 
  if (data !== undefined) {
    entry.data = data;
  }
 
  return entry;
}
 
/**
 * Log an info message
 */
export function logInfo(context: string, message: string, data?: unknown): void {
  const entry = formatLogEntry("INFO", context, message, data);
  // eslint-disable-next-line no-console
  console.log(`[${entry.timestamp}] ${entry.level} [${entry.context}]: ${entry.message}`, data || "");
}
 
/**
 * Log a warning message
 */
export function logWarn(context: string, message: string, data?: unknown): void {
  const entry = formatLogEntry("WARN", context, message, data);
  console.warn(`[${entry.timestamp}] ${entry.level} [${entry.context}]: ${entry.message}`, data || "");
}
 
/**
 * Log an error message
 */
export function logError(context: string, message: string, error?: unknown): void {
  let errorData: unknown = error;
 
  if (error instanceof Error) {
    errorData = {
      name: error.name,
      message: error.message,
      stack: error.stack};
  }
 
  const entry = formatLogEntry("ERROR", context, message, errorData);
  console.error(
    `[${entry.timestamp}] ${entry.level} [${entry.context}]: ${entry.message}`,
    errorData || ""
  );
}
 
/**
 * Log a debug message (only in development)
 */
export function logDebug(context: string, message: string, data?: unknown): void {
  if (process.env.NODE_ENV === "development") {
    const entry = formatLogEntry("DEBUG", context, message, data);
    // eslint-disable-next-line no-console
    console.debug(`[${entry.timestamp}] ${entry.level} [${entry.context}]: ${entry.message}`, data || "");
  }
}
 
/**
 * Log an API request
 */
export function logRequest(
  method: string,
  path: string,
  statusCode?: number,
  userId?: string,
  duration?: number
): void {
  const durationStr = duration ? ` (${duration}ms)` : "";
  const userStr = userId ? ` (user: ${userId})` : "";
  const statusStr = statusCode ? ` -> ${statusCode}` : "";
 
  logInfo("API", `${method} ${path}${statusStr}${userStr}${durationStr}`);
}
 
/**
 * Log authentication event
 */
export function logAuth(event: string, email: string, success: boolean): void {
  const message = `${event} - ${email} - ${success ? "SUCCESS" : "FAILED"}`;
  logInfo("AUTH", message);
}
 
/**
 * Log database operation
 */
export function logDatabase(operation: string, model: string, duration?: number): void {
  const durationStr = duration ? ` (${duration}ms)` : "";
  logDebug("DATABASE", `${operation} on ${model}${durationStr}`);
}
 
/**
 * Log rate limit event
 */
export function logRateLimit(identifier: string, limit: number, remaining: number): void {
  logWarn(
    "RATE_LIMIT",
    `Rate limit approaching for ${identifier}`,
    { limit, remaining }
  );
}
 
export const logger = {
  info: logInfo,
  warn: logWarn,
  error: logError,
  debug: logDebug,
  request: logRequest,
  auth: logAuth,
  database: logDatabase,
  rateLimit: logRateLimit};