- 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.* 🦊💕
74 lines
2.1 KiB
Python
74 lines
2.1 KiB
Python
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()
|