Add core service infrastructure
- NATS event bus (pub/sub, JetStream, KV storage) - Service registry with health monitoring - Base service class with lifecycle management - Config system - Logger with Vi formatting Adapted from Lyra's patterns, namespace changed to vi.* 🦊💕
This commit is contained in:
73
core/logger.py
Normal file
73
core/logger.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
from datetime import datetime
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
|
||||
|
||||
class ViFormatter(logging.Formatter):
|
||||
"""Custom formatter for Vi services with symbolic level indicators"""
|
||||
def format(self, record):
|
||||
timestamp = datetime.now().strftime('%H:%M:%S')
|
||||
level_map = {
|
||||
'DEBUG': '·',
|
||||
'INFO': '✓',
|
||||
'WARNING': '⚠',
|
||||
'ERROR': '✗',
|
||||
'CRITICAL': '☠'
|
||||
}
|
||||
level_symbol = level_map.get(record.levelname, '?')
|
||||
return f"[{timestamp}] {level_symbol} {record.getMessage()}"
|
||||
|
||||
|
||||
def _get_project_root():
|
||||
"""Find the project root directory by looking for core/ directory"""
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
return os.path.dirname(current_dir)
|
||||
|
||||
|
||||
def setup_logger(name="vi", level=logging.INFO, service_name=None):
|
||||
"""Set up a logger with console and optional file output"""
|
||||
# Allow environment variable to override log level
|
||||
env_level = os.getenv('LOG_LEVEL', '').upper()
|
||||
if env_level in ['DEBUG', 'INFO', 'WARNING', 'ERROR']:
|
||||
level = getattr(logging, env_level)
|
||||
|
||||
logger = logging.getLogger(name)
|
||||
|
||||
if logger.handlers:
|
||||
return logger
|
||||
|
||||
logger.setLevel(level)
|
||||
|
||||
# Console handler
|
||||
console_handler = logging.StreamHandler(sys.stdout)
|
||||
console_handler.setFormatter(ViFormatter())
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
# File handler with daily rotation if service_name is specified
|
||||
if service_name:
|
||||
project_root = _get_project_root()
|
||||
logs_dir = os.path.join(project_root, 'logs')
|
||||
|
||||
if not os.path.exists(logs_dir):
|
||||
os.makedirs(logs_dir, exist_ok=True)
|
||||
|
||||
log_file = os.path.join(logs_dir, f"{service_name}.log")
|
||||
|
||||
file_handler = TimedRotatingFileHandler(
|
||||
log_file,
|
||||
when='midnight',
|
||||
interval=1,
|
||||
backupCount=30,
|
||||
encoding='utf-8'
|
||||
)
|
||||
file_handler.setFormatter(ViFormatter())
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
logger.propagate = False
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
logger = setup_logger()
|
||||
Reference in New Issue
Block a user