docker-pilot
Version:
A powerful, scalable Docker CLI library for managing containerized applications of any size
373 lines âĸ 10.3 kB
JavaScript
;
/**
* Logger utility for Docker Pilot
* Provides structured logging with different levels and colored output
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.logger = exports.Logger = void 0;
class Logger {
constructor(config = {}) {
this.logs = [];
this.config = {
level: 'info',
enableColors: true,
enableTimestamp: true,
enableSource: false,
silent: false,
...config
};
}
/**
* Check if a log level should be displayed
*/
shouldLog(level) {
if (this.config.silent)
return false;
const currentLevelNum = Logger.LOG_LEVELS[this.config.level];
const messageLevelNum = Logger.LOG_LEVELS[level];
return messageLevelNum >= currentLevelNum;
}
/**
* Format context data for display
*/
formatContext(context) {
if (!context)
return '';
if (typeof context === 'string') {
return context;
}
if (context instanceof Error) {
return context.message || context.toString();
}
// For objects, try to extract meaningful information
if (typeof context === 'object') {
// If it's an empty object, don't show it
if (Object.keys(context).length === 0) {
return '';
}
// If it has a message property, use that
if (context.message) {
return typeof context.message === 'string' ? context.message : JSON.stringify(context.message);
}
// If it has an error property, format that
if (context.error) {
return this.formatContext(context.error);
}
// Otherwise stringify with limited depth
try {
return JSON.stringify(context, null, 2);
}
catch {
return '[Circular Object]';
}
}
return String(context);
}
/**
* Format log message with colors and timestamp
*/
formatMessage(level, message, context, source) {
const parts = [];
// Timestamp
if (this.config.enableTimestamp) {
const timestamp = new Date().toISOString();
const timestampStr = this.config.enableColors
? `${Logger.COLORS.gray}[${timestamp}]${Logger.COLORS.reset}`
: `[${timestamp}]`;
parts.push(timestampStr);
}
// Level with icon and color
const icon = Logger.ICONS[level];
let levelStr = `${icon} ${level.toUpperCase()}`;
if (this.config.enableColors) {
const color = this.getLevelColor(level);
levelStr = `${color}${levelStr}${Logger.COLORS.reset}`;
}
parts.push(levelStr);
// Source
if (source && this.config.enableSource) {
const sourceStr = this.config.enableColors
? `${Logger.COLORS.cyan}[${source}]${Logger.COLORS.reset}`
: `[${source}]`;
parts.push(sourceStr);
}
// Message
parts.push(message);
// Context
if (context !== undefined) {
const contextStr = this.formatContext(context);
if (contextStr) {
if (this.config.enableColors) {
parts.push(`${Logger.COLORS.dim}${contextStr}${Logger.COLORS.reset}`);
}
else {
parts.push(contextStr);
}
}
}
return parts.join(' ');
}
/**
* Get color for log level
*/
getLevelColor(level) {
switch (level) {
case 'debug': return Logger.COLORS.gray;
case 'info': return Logger.COLORS.blue;
case 'warn': return Logger.COLORS.yellow;
case 'error': return Logger.COLORS.red;
default: return Logger.COLORS.reset;
}
}
/**
* Core log method
*/ log(level, message, context, source) {
if (!this.shouldLog(level))
return;
const logEntry = {
level,
message,
timestamp: new Date(),
context,
...(source && { source })
};
// Store log entry
this.logs.push(logEntry);
// Format and output
const formattedMessage = this.formatMessage(level, message, context, source);
// Output to appropriate stream
if (level === 'error') {
console.error(formattedMessage);
}
else {
console.log(formattedMessage);
}
}
/**
* Debug level logging
*/
debug(message, context, source) {
this.log('debug', message, context, source);
}
/**
* Info level logging
*/
info(message, context, source) {
this.log('info', message, context, source);
}
/**
* Warning level logging
*/
warn(message, context, source) {
this.log('warn', message, context, source);
}
/**
* Error level logging
*/
error(message, context, source) {
this.log('error', message, context, source);
}
/**
* Success logging (special case of info)
*/
success(message, context, source) {
const successMessage = this.config.enableColors
? `${Logger.COLORS.green}â
${message}${Logger.COLORS.reset}`
: `â
${message}`;
this.log('info', successMessage, context, source);
}
/**
* Loading/progress logging
*/
loading(message, context, source) {
const loadingMessage = this.config.enableColors
? `${Logger.COLORS.cyan}đ ${message}${Logger.COLORS.reset}`
: `đ ${message}`;
this.log('info', loadingMessage, context, source);
}
/**
* Command execution logging
*/
command(command, source) {
const commandMessage = this.config.enableColors
? `${Logger.COLORS.magenta}đ Executing: ${Logger.COLORS.bright}${command}${Logger.COLORS.reset}`
: `đ Executing: ${command}`;
this.log('info', commandMessage, undefined, source);
}
/**
* Service status logging
*/
service(serviceName, status, details) {
const statusEmoji = status === 'running' ? 'đĸ' :
status === 'stopped' ? 'đ´' :
status === 'starting' ? 'đĄ' : 'âĢ';
const serviceMessage = `${statusEmoji} Service ${serviceName}: ${status}`;
this.log('info', serviceMessage, details, 'ServiceManager');
}
/**
* Clear console
*/
clear() {
if (!this.config.silent) {
console.clear();
}
}
/**
* Print separator line
*/
separator(char = '=', length = 60) {
if (!this.config.silent) {
const line = char.repeat(length);
console.log(this.config.enableColors
? `${Logger.COLORS.gray}${line}${Logger.COLORS.reset}`
: line);
}
}
/**
* Print header
*/
header(title) {
if (!this.config.silent) {
this.separator();
const headerMessage = this.config.enableColors
? `${Logger.COLORS.bright}${Logger.COLORS.cyan}${title}${Logger.COLORS.reset}`
: title;
console.log(`\n${headerMessage}\n`);
this.separator();
}
}
/**
* Print blank line
*/
newLine() {
if (!this.config.silent) {
console.log();
}
}
/**
* Table logging
*/
table(data, headers) {
if (!this.config.silent && data.length > 0) {
if (headers) {
console.table(data, headers);
}
else {
console.table(data);
}
}
}
/**
* JSON logging
*/
json(data, label) {
if (label) {
this.info(label);
}
if (!this.config.silent) {
console.log(JSON.stringify(data, null, 2));
}
}
/**
* Update logger configuration
*/
configure(config) {
this.config = { ...this.config, ...config };
}
/**
* Get all log entries
*/
getLogs() {
return [...this.logs];
}
/**
* Get logs by level
*/
getLogsByLevel(level) {
return this.logs.filter(log => log.level === level);
}
/**
* Clear log history
*/
clearLogs() {
this.logs = [];
}
/**
* Export logs to string
*/
exportLogs() {
return this.logs
.map(log => `[${log.timestamp.toISOString()}] ${log.level.toUpperCase()}: ${log.message}`)
.join('\n');
}
/**
* Set log level
*/
setLevel(level) {
this.config.level = level;
}
/**
* Enable/disable colors
*/
setColors(enabled) {
this.config.enableColors = enabled;
}
/**
* Enable/disable silent mode
*/
setSilent(silent) {
this.config.silent = silent;
}
/**
* Create child logger with context
*/
child(source) {
const childLogger = new Logger(this.config);
// Override log method to always include source
const originalLog = childLogger.log.bind(childLogger);
childLogger.log = (level, message, context, childSource) => {
originalLog(level, message, context, childSource || source);
};
return childLogger;
}
}
exports.Logger = Logger;
/**
* Log levels hierarchy
*/
Logger.LOG_LEVELS = {
debug: 0,
info: 1,
warn: 2,
error: 3
};
/**
* ANSI color codes for console output
*/
Logger.COLORS = {
reset: '\x1b[0m',
bright: '\x1b[1m',
dim: '\x1b[2m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m',
white: '\x1b[37m',
gray: '\x1b[90m'
};
/**
* Icons for different log levels
*/
Logger.ICONS = {
debug: 'đ',
info: 'âšī¸',
warn: 'â ī¸',
error: 'â'
};
/**
* Default logger instance
*/
exports.logger = new Logger();
//# sourceMappingURL=Logger.js.map