UNPKG

@0xobelisk/graphql-server

Version:

Tookit for interacting with dubhe graphql server

230 lines 9.23 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.logGraphQLQuery = exports.logWebSocketEvent = exports.logDatabaseOperation = exports.logExpress = exports.logPerformance = exports.createComponentLogger = exports.perfLogger = exports.authLogger = exports.systemLogger = exports.subscriptionLogger = exports.gqlLogger = exports.wsLogger = exports.httpLogger = exports.serverLogger = exports.dbLogger = exports.Logger = void 0; const pino_1 = __importDefault(require("pino")); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); /** * High-performance logging system based on Pino */ class Logger { pinoInstance; config; constructor(config = {}) { this.config = { level: config.level || process.env.LOG_LEVEL || 'info', service: config.service || 'dubhe-graphql-server', component: config.component || 'default', enableFileLogging: config.enableFileLogging !== false, logsDir: config.logsDir || path_1.default.join(process.cwd(), 'logs') }; this.ensureLogsDirectory(); this.pinoInstance = this.createPinoInstance(); this.setupExceptionHandlers(); } /** * Ensure logs directory exists */ ensureLogsDirectory() { if (this.config.enableFileLogging && !fs_1.default.existsSync(this.config.logsDir)) { fs_1.default.mkdirSync(this.config.logsDir, { recursive: true }); } } /** * Create Pino instance */ createPinoInstance() { const pinoOptions = { level: this.config.level, base: { service: this.config.service, pid: process.pid }, timestamp: pino_1.default.stdTimeFunctions.isoTime, formatters: { level(label) { return { level: label }; } }, serializers: { error: pino_1.default.stdSerializers.err } }; // If file logging is enabled, use multistream if (this.config.enableFileLogging) { const streams = [ // Pretty print to console { stream: pino_1.default.transport({ target: 'pino-pretty', options: { colorize: true, translateTime: 'yyyy-mm-dd HH:MM:ss.l', ignore: 'pid,hostname,service,component', messageFormat: '[{component}]: {msg}', singleLine: true, hideObject: false } }) }, // JSON format to file { stream: pino_1.default.destination({ dest: path_1.default.join(this.config.logsDir, 'combined.log'), sync: false }) } ]; return (0, pino_1.default)(pinoOptions, pino_1.default.multistream(streams)); } // Only output to console in pretty format return (0, pino_1.default)({ ...pinoOptions, transport: { target: 'pino-pretty', options: { colorize: true, translateTime: 'yyyy-mm-dd HH:MM:ss.l', ignore: 'pid,hostname,service', messageFormat: '[{component}]: {msg}', singleLine: true, hideObject: false } } }); } /** * Setup exception handlers */ setupExceptionHandlers() { process.on('uncaughtException', (error) => { this.pinoInstance.fatal({ error }, 'Uncaught Exception'); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { this.pinoInstance.fatal({ reason, promise }, 'Unhandled Promise Rejection'); process.exit(1); }); } /** * Create component logger with context */ createComponentLogger(component) { const componentLogger = this.pinoInstance.child({ component }); return { debug: (message, meta) => componentLogger.debug(meta || {}, message), info: (message, meta) => componentLogger.info(meta || {}, message), warn: (message, meta) => componentLogger.warn(meta || {}, message), error: (message, error, meta) => { const errorData = error instanceof Error ? { error: { message: error.message, stack: error.stack, name: error.name }, ...meta } : { error, ...meta }; componentLogger.error(errorData, message); } }; } /** * Get raw Pino instance */ getPinoInstance() { return this.pinoInstance; } /** * Log performance metrics */ logPerformance(operation, startTime, meta) { const duration = Date.now() - startTime; const perfLogger = this.createComponentLogger('performance'); perfLogger.info(operation, { duration: `${duration}ms`, ...meta }); } /** * Log Express HTTP requests */ logExpress(method, path, statusCode, startTime, meta) { const duration = Date.now() - startTime; const httpLogger = this.createComponentLogger('express'); const message = `${method} ${path} - ${statusCode} (${duration}ms)`; // Choose log level based on status code if (statusCode >= 500) { httpLogger.error(message, meta); } else if (statusCode >= 400) { httpLogger.warn(message, meta); } else { httpLogger.info(message, meta); } } /** * Log database operations */ logDatabaseOperation(operation, table, meta) { const dbLogger = this.createComponentLogger('database'); dbLogger.info(`Database operation: ${operation}`, { table, ...meta }); } /** * Log WebSocket events */ logWebSocketEvent(event, clientCount, meta) { const wsLogger = this.createComponentLogger('websocket'); wsLogger.info(`WebSocket event: ${event}`, { clientCount, ...meta }); } /** * Log GraphQL queries */ logGraphQLQuery(operation, query, variables) { const gqlLogger = this.createComponentLogger('graphql'); gqlLogger.info(`GraphQL ${operation}`, { query: query?.substring(0, 200) + (query && query.length > 200 ? '...' : ''), variableCount: variables ? Object.keys(variables).length : 0 }); } } exports.Logger = Logger; // Create default logger instance const defaultLogger = new Logger(); // Export predefined component loggers (maintain backward compatibility) exports.dbLogger = defaultLogger.createComponentLogger('database'); exports.serverLogger = defaultLogger.createComponentLogger('server'); exports.httpLogger = defaultLogger.createComponentLogger('express'); exports.wsLogger = defaultLogger.createComponentLogger('websocket'); exports.gqlLogger = defaultLogger.createComponentLogger('graphql'); exports.subscriptionLogger = defaultLogger.createComponentLogger('subscription'); exports.systemLogger = defaultLogger.createComponentLogger('system'); exports.authLogger = defaultLogger.createComponentLogger('auth'); exports.perfLogger = defaultLogger.createComponentLogger('performance'); // Export utility functions (maintain backward compatibility) const createComponentLogger = (component) => defaultLogger.createComponentLogger(component); exports.createComponentLogger = createComponentLogger; const logPerformance = (operation, startTime, meta) => defaultLogger.logPerformance(operation, startTime, meta); exports.logPerformance = logPerformance; const logExpress = (method, path, statusCode, startTime, meta) => defaultLogger.logExpress(method, path, statusCode, startTime, meta); exports.logExpress = logExpress; const logDatabaseOperation = (operation, table, meta) => defaultLogger.logDatabaseOperation(operation, table, meta); exports.logDatabaseOperation = logDatabaseOperation; const logWebSocketEvent = (event, clientCount, meta) => defaultLogger.logWebSocketEvent(event, clientCount, meta); exports.logWebSocketEvent = logWebSocketEvent; const logGraphQLQuery = (operation, query, variables) => defaultLogger.logGraphQLQuery(operation, query, variables); exports.logGraphQLQuery = logGraphQLQuery; // Default export (maintain backward compatibility) exports.default = defaultLogger.getPinoInstance(); //# sourceMappingURL=index.js.map