153 lines
3.6 KiB
TypeScript
153 lines
3.6 KiB
TypeScript
/**
|
|
* Centralized logging utility for FitAI Admin App
|
|
* Uses Pino for structured logging with appropriate log levels
|
|
*/
|
|
|
|
import pino from "pino";
|
|
|
|
/**
|
|
* Create logger instance based on environment
|
|
* - Development: JSON logs to console (pino-pretty disabled due to Turbopack compatibility)
|
|
* - Production: JSON logs for aggregation/monitoring
|
|
*/
|
|
const logger = pino({
|
|
level:
|
|
process.env.LOG_LEVEL ||
|
|
(process.env.NODE_ENV === "production" ? "info" : "debug"),
|
|
formatters: {
|
|
level: (label) => {
|
|
return { level: label };
|
|
},
|
|
},
|
|
// Note: pino-pretty transport disabled for Next.js 15+ Turbopack compatibility
|
|
// The transport uses worker threads which cause module resolution issues
|
|
// Logs will be in JSON format in all environments
|
|
});
|
|
|
|
/**
|
|
* Log levels:
|
|
* - debug: Detailed information for debugging (only in dev)
|
|
* - info: General informational messages
|
|
* - warn: Warning messages for potentially harmful situations
|
|
* - error: Error messages for failures that don't stop the app
|
|
* - fatal: Critical errors that may cause the app to crash
|
|
*/
|
|
|
|
export { logger };
|
|
|
|
/**
|
|
* Convenience functions for common logging patterns
|
|
*/
|
|
|
|
export const log = {
|
|
/**
|
|
* Log debug information (only in development)
|
|
*/
|
|
debug: (message: string, data?: Record<string, unknown>) => {
|
|
logger.debug(data || {}, message);
|
|
},
|
|
|
|
/**
|
|
* Log general information
|
|
*/
|
|
info: (message: string, data?: Record<string, unknown>) => {
|
|
logger.info(data || {}, message);
|
|
},
|
|
|
|
/**
|
|
* Log warnings
|
|
*/
|
|
warn: (message: string, data?: Record<string, unknown>) => {
|
|
logger.warn(data || {}, message);
|
|
},
|
|
|
|
/**
|
|
* Log errors with optional error object
|
|
*/
|
|
error: (message: string, error?: unknown, data?: Record<string, unknown>) => {
|
|
const errorData: Record<string, unknown> = {
|
|
...(data || {}),
|
|
};
|
|
|
|
if (error instanceof Error) {
|
|
errorData.error = {
|
|
name: error.name,
|
|
message: error.message,
|
|
stack: error.stack,
|
|
};
|
|
} else if (error && typeof error === "object") {
|
|
errorData.error = error;
|
|
}
|
|
|
|
logger.error(errorData, message);
|
|
},
|
|
|
|
/**
|
|
* Log fatal errors (should be rare)
|
|
*/
|
|
fatal: (message: string, error?: unknown, data?: Record<string, unknown>) => {
|
|
const errorData: Record<string, unknown> = {
|
|
...(data || {}),
|
|
};
|
|
|
|
if (error instanceof Error) {
|
|
errorData.error = {
|
|
name: error.name,
|
|
message: error.message,
|
|
stack: error.stack,
|
|
};
|
|
} else if (error && typeof error === "object") {
|
|
errorData.error = error;
|
|
}
|
|
|
|
logger.fatal(errorData, message);
|
|
},
|
|
|
|
/**
|
|
* Log API requests (use in middleware or API routes)
|
|
*/
|
|
apiRequest: (
|
|
method: string,
|
|
path: string,
|
|
data?: Record<string, unknown>,
|
|
) => {
|
|
logger.info({ method, path, ...(data || {}) }, "API request");
|
|
},
|
|
|
|
/**
|
|
* Log API responses
|
|
*/
|
|
apiResponse: (
|
|
method: string,
|
|
path: string,
|
|
status: number,
|
|
duration?: number,
|
|
data?: Record<string, unknown>,
|
|
) => {
|
|
logger.info(
|
|
{ method, path, status, duration, ...(data || {}) },
|
|
"API response",
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Log database operations
|
|
*/
|
|
database: (
|
|
operation: string,
|
|
table?: string,
|
|
data?: Record<string, unknown>,
|
|
) => {
|
|
logger.debug({ operation, table, ...(data || {}) }, "Database operation");
|
|
},
|
|
|
|
/**
|
|
* Log authentication events
|
|
*/
|
|
auth: (event: string, userId?: string, data?: Record<string, unknown>) => {
|
|
logger.info({ event, userId, ...(data || {}) }, "Authentication event");
|
|
},
|
|
};
|
|
|
|
export default log;
|