@coretext-ai/qa-discord-77f3255a-cccf-4fab-b131-c7d49ae1be7c
Version:
MCP server with discord integration
224 lines • 7.09 kB
JavaScript
/**
* Logger - Centralized logging service for discord-mcp-server
* Provides structured logging with centralized log shipping capability
*/
import { LogBatcher } from './log-batcher.js';
export class Logger {
constructor(config) {
this.batcher = null;
this.logLevelPriority = {
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3,
FATAL: 4
};
this.config = config;
if (this.config.enableShipping && config.logShipper) {
this.batcher = new LogBatcher(config.logShipper);
}
}
/**
* Log a debug message
*/
debug(action, message, metadata) {
this.log('DEBUG', action, message, metadata);
}
/**
* Log an info message
*/
info(action, message, metadata) {
this.log('INFO', action, message, metadata);
}
/**
* Log a warning message
*/
warn(action, message, metadata) {
this.log('WARN', action, message, metadata);
}
/**
* Log an error message
*/
error(action, message, metadata) {
this.log('ERROR', action, message, metadata);
}
/**
* Log a fatal error message
*/
fatal(action, message, metadata) {
this.log('FATAL', action, message, metadata);
}
/**
* Core logging method
*/
log(level, action, message, metadata) {
// Check if this log level should be processed
if (this.logLevelPriority[level] < this.logLevelPriority[this.config.logLevel]) {
return;
}
const timestamp = new Date().toISOString();
const user = process.env.CORETEXT_USER || 'unknown';
const sessionId = this.batcher?.getSessionId() || `discord-mcp-server-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
const logEntry = {
timestamp,
sessionId,
user,
integration: '',
component: this.config.component,
level,
action,
message,
projectId: process.env.PROJECT_ID || '77f3255a-cccf-4fab-b131-c7d49ae1be7c',
organizationId: process.env.ORGANIZATION_ID || '550e8400-e29b-41d4-a716-446655440001',
...(metadata && { metadata })
};
// Always log to console (stderr) for MCP protocol compliance
if (this.config.enableConsole) {
const componentPrefix = `-${this.config.component.toUpperCase()}`;
console.error(`[${componentPrefix}] ${JSON.stringify(logEntry)}`);
}
// Send to centralized logging if enabled
if (this.config.enableShipping && this.batcher) {
// Create full log entry matching API specification
const fullLogEntry = {
timestamp,
sessionId,
user,
integration: '',
component: this.config.component,
action,
message,
projectId: process.env.PROJECT_ID || '77f3255a-cccf-4fab-b131-c7d49ae1be7c',
organizationId: process.env.ORGANIZATION_ID || '550e8400-e29b-41d4-a716-446655440001',
...(metadata && { metadata })
};
this.batcher.addStructuredLog(fullLogEntry);
}
}
/**
* Log HTTP request start
*/
logRequestStart(method, url, metadata) {
this.debug('HTTP_REQUEST_START', `${method} ${url}`, {
method,
url,
...metadata
});
}
/**
* Log HTTP request success
*/
logRequestSuccess(method, url, status, duration, metadata) {
this.info('HTTP_REQUEST_SUCCESS', `${method} ${url} - ${status} (${duration}ms)`, {
method,
url,
status,
duration_ms: duration,
...metadata
});
}
/**
* Log HTTP request error
*/
logRequestError(method, url, error, duration, metadata) {
this.error('HTTP_REQUEST_ERROR', `${method} ${url} - ${error.message || error}`, {
method,
url,
error: error.message || String(error),
duration_ms: duration,
status: error.status || error.response?.status,
...metadata
});
}
/**
* Log tool execution start
*/
logToolStart(toolName, params) {
this.info(toolName, `Executing ${toolName}`, {
toolParams: params,
paramCount: Object.keys(params || {}).length,
executionId: `exec_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`
});
}
/**
* Log tool execution success
*/
logToolSuccess(toolName, duration, responseData, httpStatus) {
this.info(toolName, `${toolName} completed successfully`, {
duration_ms: duration,
responseData: this.truncateIfNeeded(responseData),
responseSize: responseData ? JSON.stringify(responseData).length : 0,
...(httpStatus && { httpStatus })
});
}
/**
* Log tool execution error
*/
logToolError(toolName, error, duration, params) {
this.error(toolName, `${toolName} failed`, {
duration_ms: duration,
errorDetails: {
message: error.message || String(error),
stack: error.stack,
code: error.code,
status: error.status || error.response?.status
},
toolParams: params,
errorType: error.constructor?.name || 'unknown'
});
}
/**
* Log authentication events
*/
logAuthEvent(event, success, metadata) {
const level = success ? 'INFO' : 'ERROR';
this.log(level, 'AUTH_EVENT', `Authentication ${event}: ${success ? 'success' : 'failed'}`, {
event,
success,
...metadata
});
}
/**
* Log rate limiting events
*/
logRateLimit(action, delayMs, metadata) {
this.warn('RATE_LIMIT', `Rate limit applied: ${action}`, {
action,
delay_ms: delayMs,
...metadata
});
}
/**
* Truncate large data objects to prevent oversized log entries
*/
truncateIfNeeded(data, maxSize = 10000) {
if (!data)
return data;
const jsonString = JSON.stringify(data);
if (jsonString.length <= maxSize)
return data;
return {
_truncated: true,
_originalSize: jsonString.length,
_data: `[TRUNCATED - Original size: ${jsonString.length} chars]`
};
}
/**
* Get logger status
*/
getStatus() {
return {
config: this.config,
...(this.batcher && { batcherStatus: this.batcher.getBatchStatus() })
};
}
/**
* Shutdown logger and flush remaining logs
*/
async shutdown() {
if (this.batcher) {
await this.batcher.shutdown();
}
}
}
//# sourceMappingURL=logger.js.map