Some checks failed
DSS Project Analysis / dss-context-update (push) Has been cancelled
- Update all `from storage.` imports to `from dss.storage.` - Update `from config import config` to use `dss.settings` - Update `from auth.` imports to `from dss.auth.` - Update health check to use `dss.mcp.handler` - Fix SmartMerger import (merger.py not smart_merger.py) - Fix TranslationDictionary import path - Fix test assertion for networkx edges/links - Remove organ/body metaphors from: - API server health check - CLI status command and help text - Admin UI logger and error handler 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
184 lines
4.3 KiB
JavaScript
184 lines
4.3 KiB
JavaScript
/**
|
|
* DSS Logger - Structured Logging System
|
|
*
|
|
* Provides structured logging with categories and levels for the DSS admin UI.
|
|
*
|
|
* Log Categories:
|
|
* 'storage' - Database operations and data persistence
|
|
* 'validation' - Validation, analysis, and decision making
|
|
* 'api' - API calls, webhooks, communication
|
|
* 'parser' - Data ingestion, parsing, transformation
|
|
* 'tokens' - Design token flow and distribution
|
|
* 'transform' - Style-dictionary transformations
|
|
* 'config' - Theme system and configuration
|
|
* 'security' - Validation, error detection, security
|
|
* 'assets' - Asset loading, Figma integration
|
|
* 'ui' - UI rendering, Storybook output
|
|
* 'schema' - Schema and structure validation
|
|
*/
|
|
|
|
const LOG_LEVELS = {
|
|
DEBUG: 0,
|
|
INFO: 1,
|
|
WARN: 2,
|
|
ERROR: 3,
|
|
NONE: 4
|
|
};
|
|
|
|
class Logger {
|
|
constructor(name = 'DSS', level = 'INFO') {
|
|
this.name = name;
|
|
this.level = LOG_LEVELS[level] || LOG_LEVELS.INFO;
|
|
this.logs = [];
|
|
this.maxLogs = 1000;
|
|
this.remoteLoggingEnabled = false;
|
|
}
|
|
|
|
setLevel(level) {
|
|
this.level = LOG_LEVELS[level] || LOG_LEVELS.INFO;
|
|
}
|
|
|
|
enableRemoteLogging() {
|
|
this.remoteLoggingEnabled = true;
|
|
}
|
|
|
|
_shouldLog(level) {
|
|
return LOG_LEVELS[level] >= this.level;
|
|
}
|
|
|
|
_formatMessage(level, category, message, data) {
|
|
const timestamp = new Date().toISOString();
|
|
return {
|
|
timestamp,
|
|
level,
|
|
category,
|
|
name: this.name,
|
|
message,
|
|
data
|
|
};
|
|
}
|
|
|
|
_log(level, category, message, data = null) {
|
|
if (!this._shouldLog(level)) return;
|
|
|
|
const logEntry = this._formatMessage(level, category, message, data);
|
|
|
|
// Store in memory
|
|
this.logs.push(logEntry);
|
|
if (this.logs.length > this.maxLogs) {
|
|
this.logs.shift();
|
|
}
|
|
|
|
const levelIcons = {
|
|
DEBUG: '[D]',
|
|
INFO: '[I]',
|
|
WARN: '[W]',
|
|
ERROR: '[E]'
|
|
};
|
|
|
|
const colors = {
|
|
DEBUG: 'color: #666; font-style: italic',
|
|
INFO: 'color: #2196F3; font-weight: bold',
|
|
WARN: 'color: #FF9800; font-weight: bold',
|
|
ERROR: 'color: #F44336; font-weight: bold'
|
|
};
|
|
|
|
const icon = levelIcons[level] || '[?]';
|
|
const prefix = `${icon} [${category}]`;
|
|
const style = colors[level] || '';
|
|
|
|
if (data) {
|
|
console.log(`%c${prefix} ${message}`, style, data);
|
|
} else {
|
|
console.log(`%c${prefix} ${message}`, style);
|
|
}
|
|
|
|
// Remote logging (if enabled)
|
|
if (this.remoteLoggingEnabled && level === 'ERROR') {
|
|
this._sendToServer(logEntry);
|
|
}
|
|
}
|
|
|
|
async _sendToServer(logEntry) {
|
|
try {
|
|
await fetch('/api/logs', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(logEntry)
|
|
});
|
|
} catch (e) {
|
|
// Fail silently for logging errors
|
|
}
|
|
}
|
|
|
|
/**
|
|
* DEBUG - Detailed internal information
|
|
*/
|
|
debug(category, message, data) {
|
|
this._log('DEBUG', category, message, data);
|
|
}
|
|
|
|
/**
|
|
* INFO - General information
|
|
*/
|
|
info(category, message, data) {
|
|
this._log('INFO', category, message, data);
|
|
}
|
|
|
|
/**
|
|
* WARN - Warning, something unusual detected
|
|
*/
|
|
warn(category, message, data) {
|
|
this._log('WARN', category, message, data);
|
|
}
|
|
|
|
/**
|
|
* ERROR - Error, something went wrong
|
|
*/
|
|
error(category, message, data) {
|
|
this._log('ERROR', category, message, data);
|
|
}
|
|
|
|
/**
|
|
* Get recent log entries
|
|
*/
|
|
getRecentLogs(count = 50) {
|
|
return this.logs.slice(-count);
|
|
}
|
|
|
|
/**
|
|
* Clear all logs
|
|
*/
|
|
clear() {
|
|
this.logs = [];
|
|
}
|
|
|
|
/**
|
|
* Export logs to file
|
|
*/
|
|
export() {
|
|
const dataStr = JSON.stringify(this.logs, null, 2);
|
|
const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);
|
|
|
|
const exportFileDefaultName = `dss-logs-${Date.now()}.json`;
|
|
|
|
const linkElement = document.createElement('a');
|
|
linkElement.setAttribute('href', dataUri);
|
|
linkElement.setAttribute('download', exportFileDefaultName);
|
|
linkElement.click();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* DSS Logger singleton
|
|
*/
|
|
const logger = new Logger('DSS', 'INFO');
|
|
|
|
// Set log level from localStorage or URL param
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const logLevel = urlParams.get('log') || localStorage.getItem('dss_log_level') || 'INFO';
|
|
logger.setLevel(logLevel.toUpperCase());
|
|
|
|
export default logger;
|
|
export { Logger, LOG_LEVELS };
|