remcode
Version:
Turn your AI assistant into a codebase expert. Intelligent code analysis, semantic search, and software engineering guidance through MCP integration.
312 lines (311 loc) • 9.75 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.logger = exports.defaultLoggerConfig = exports.LogLevelNames = exports.LogLevel = void 0;
exports.configureLogger = configureLogger;
exports.createLogger = createLogger;
exports.getLogger = getLogger;
exports.logError = logError;
exports.getLogLevel = getLogLevel;
exports.setLogLevel = setLogLevel;
exports.enableFileLogging = enableFileLogging;
exports.disableFileLogging = disableFileLogging;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const util = __importStar(require("util"));
// Import chalk with compatibility for both CommonJS and ES modules
let chalk;
try {
chalk = require('chalk');
}
catch (error) {
// Fallback for when chalk is not available or in ES module format
chalk = {
gray: (text) => text,
magenta: (text) => text,
blue: (text) => text,
yellow: (text) => text,
red: (text) => text,
white: (text) => text,
bgRed: { white: (text) => text }
};
}
/**
* Log levels
*/
var LogLevel;
(function (LogLevel) {
LogLevel[LogLevel["TRACE"] = 0] = "TRACE";
LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG";
LogLevel[LogLevel["INFO"] = 2] = "INFO";
LogLevel[LogLevel["WARN"] = 3] = "WARN";
LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
LogLevel[LogLevel["FATAL"] = 5] = "FATAL";
LogLevel[LogLevel["SILENT"] = 6] = "SILENT";
})(LogLevel || (exports.LogLevel = LogLevel = {}));
/**
* Log level names for display
*/
exports.LogLevelNames = {
[LogLevel.TRACE]: 'TRACE',
[LogLevel.DEBUG]: 'DEBUG',
[LogLevel.INFO]: 'INFO',
[LogLevel.WARN]: 'WARN',
[LogLevel.ERROR]: 'ERROR',
[LogLevel.FATAL]: 'FATAL',
[LogLevel.SILENT]: 'SILENT'
};
/**
* Default logger configuration
*/
exports.defaultLoggerConfig = {
level: process.env.NODE_ENV === 'production' ? LogLevel.INFO : LogLevel.DEBUG,
colors: process.stdout.isTTY,
timestamp: true,
logToFile: false,
logFormat: 'text'
};
/**
* Global logger configuration
*/
let globalConfig = { ...exports.defaultLoggerConfig };
/**
* Configure global logger settings
*/
function configureLogger(config) {
globalConfig = { ...globalConfig, ...config };
// Set up file logging if enabled
if (globalConfig.logToFile && globalConfig.logFilePath) {
const dir = path.dirname(globalConfig.logFilePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
}
}
/**
* Format a log record for output
*/
function formatLogRecord(record, config) {
if (config.logFormat === 'json') {
return JSON.stringify({
timestamp: record.timestamp.toISOString(),
level: exports.LogLevelNames[record.level],
name: record.name,
message: record.message,
...record.metadata,
...(record.error ? {
error: {
name: record.error.name,
message: record.error.message,
stack: record.error.stack
}
} : {})
});
}
// Text format
let output = '';
if (config.timestamp) {
const timestamp = record.timestamp.toISOString();
output += config.colors ? chalk.gray(timestamp) + ' ' : timestamp + ' ';
}
const levelName = exports.LogLevelNames[record.level];
if (config.colors) {
let levelColor;
switch (record.level) {
case LogLevel.TRACE:
levelColor = chalk.magenta;
break;
case LogLevel.DEBUG:
levelColor = chalk.gray;
break;
case LogLevel.INFO:
levelColor = chalk.blue;
break;
case LogLevel.WARN:
levelColor = chalk.yellow;
break;
case LogLevel.ERROR:
levelColor = chalk.red;
break;
case LogLevel.FATAL:
levelColor = chalk.bgRed.white;
break;
default: levelColor = chalk.white;
}
output += `[${levelColor(levelName)}] `;
}
else {
output += `[${levelName}] `;
}
output += `${record.name}: ${record.message}`;
if (record.metadata && Object.keys(record.metadata).length > 0) {
output += ' ' + util.inspect(record.metadata, { colors: config.colors, depth: 4 });
}
if (record.error) {
output += '\n' + (config.colors ? chalk.red(record.error.stack || record.error.message) : (record.error.stack || record.error.message));
}
return output;
}
/**
* Write a log record to the configured outputs
*/
function writeLogRecord(record, config) {
// Skip if level is below configured level
if (record.level < config.level)
return;
const formattedLog = formatLogRecord(record, config);
// Write to console
if (record.level >= LogLevel.ERROR) {
console.error(formattedLog);
}
else if (record.level >= LogLevel.WARN) {
console.warn(formattedLog);
}
else {
console.log(formattedLog);
}
// Write to file if enabled
if (config.logToFile && config.logFilePath) {
try {
fs.appendFileSync(config.logFilePath, formattedLog + '\n', 'utf8');
}
catch (error) {
console.error(`Failed to write to log file: ${error instanceof Error ? error.message : String(error)}`);
}
}
}
/**
* Create a logger instance
*/
function createLogger(name, baseMetadata = {}) {
const createLogMethod = (level) => {
return (message, errorOrMetadata, metadata) => {
let error;
let combinedMetadata;
// Handle flexible parameters
if (errorOrMetadata instanceof Error) {
error = errorOrMetadata;
combinedMetadata = { ...baseMetadata, ...metadata };
}
else if (errorOrMetadata && typeof errorOrMetadata === 'object') {
combinedMetadata = { ...baseMetadata, ...errorOrMetadata };
}
else {
combinedMetadata = { ...baseMetadata };
}
const record = {
timestamp: new Date(),
level,
name,
message,
metadata: combinedMetadata,
error
};
writeLogRecord(record, globalConfig);
};
};
return {
trace: createLogMethod(LogLevel.TRACE),
debug: createLogMethod(LogLevel.DEBUG),
info: createLogMethod(LogLevel.INFO),
warn: createLogMethod(LogLevel.WARN),
error: createLogMethod(LogLevel.ERROR),
fatal: createLogMethod(LogLevel.FATAL),
log: (level, message, error, metadata) => {
const combinedMetadata = { ...baseMetadata, ...metadata };
const record = {
timestamp: new Date(),
level,
name,
message,
metadata: combinedMetadata,
error
};
writeLogRecord(record, globalConfig);
},
child: (childName) => createLogger(`${name}:${childName}`, baseMetadata),
withMetadata: (additionalMetadata) => {
return createLogger(name, { ...baseMetadata, ...additionalMetadata });
}
};
}
/**
* Global logger instance
*/
exports.logger = createLogger('Remcode');
/**
* Get a logger instance for a specific component
*/
function getLogger(component) {
return createLogger(component);
}
/**
* Log an error with stack trace
*/
function logError(error, context) {
const component = context || 'Error';
const logger = getLogger(component);
logger.error('An error occurred', error);
}
/**
* Get the current log level
*/
function getLogLevel() {
return globalConfig.level;
}
/**
* Set the current log level
*/
function setLogLevel(level) {
globalConfig.level = level;
}
/**
* Enable file logging
*/
function enableFileLogging(filePath, format = 'text') {
configureLogger({
logToFile: true,
logFilePath: filePath,
logFormat: format
});
}
/**
* Disable file logging
*/
function disableFileLogging() {
configureLogger({
logToFile: false
});
}
;