Fixed several logic issues / generation of secondary paths. Cleaned up Policy Prep text to be accurate to current functionality. Fixed issue with going back from policy prep menu. Switched to logging.dict from standard logging config.

This commit is contained in:
2025-10-22 17:24:39 -04:00
parent 908316dc34
commit f8302e15c1
6 changed files with 117 additions and 82 deletions
+52 -32
View File
@@ -15,6 +15,7 @@
import json
import logging
import logging.config
import logging.handlers
import os
import platform
@@ -36,49 +37,69 @@ def get_base_directory() -> Path:
else:
return home / '.local' / 'share' / "AirlockTools"
def configure_logging(log_dir: Path, log_level: str = "DEBUG"):
log_file = log_dir / "airlocktools.log"
logger = logging.getLogger()
# Always allow all messages to propagate to handlers
logger.setLevel(logging.DEBUG)
config = {
"version": 1, # Required key for dictConfig format version
"disable_existing_loggers": False, # Keeps existing loggers active
"formatters": {
"detailed": {
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
# Includes timestamp, logger name, level, and message
},
"simple": {
"format": "%(levelname)s - %(message)s"
# Minimal format for console output
},
},
"handlers": {
"file": {
"class": "logging.handlers.TimedRotatingFileHandler",
"filename": str(log_file),
"when": "midnight", # Rotate logs at midnight
"interval": 1, # Every 1 day
"backupCount": 7, # Keep 7 days of logs
"encoding": "utf-8", # Ensure UTF-8 encoding
"level": "DEBUG", # Always log DEBUG and above
"formatter": "detailed", # Use detailed format
},
"console": {
"class": "logging.StreamHandler",
"level": log_level.upper(), # Configurable log level
"formatter": "simple", # Use simple format
},
},
"root": {
"level": "DEBUG", # Root logger level
"handlers": ["file", "console"], # Attach both handlers
},
}
# Remove existing handlers
for handler in logger.handlers[:]:
logger.removeHandler(handler)
# File handler always logs DEBUG and above
file_handler = logging.handlers.RotatingFileHandler(
log_file, maxBytes=5_000_000, backupCount=5, encoding='utf-8'
)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
))
logger.addHandler(file_handler)
# Console handler respects the configured log level
console_handler = logging.StreamHandler()
console_handler.setLevel(getattr(logging, log_level.upper(), logging.INFO))
console_handler.setFormatter(logging.Formatter('%(levelname)s - %(message)s'))
logger.addHandler(console_handler)
# Optional Windows Event Log handler
# Add Windows Event Log handler if on Windows
if platform.system() == "Windows":
try:
event_handler = logging.handlers.NTEventLogHandler("AirlockTools")
event_handler.setLevel(logging.CRITICAL)
event_handler.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
logger.addHandler(event_handler)
config["handlers"]["eventlog"] = {
"class": "logging.handlers.NTEventLogHandler",
"appname": "AirlockTools", # Event log source name
"level": "CRITICAL", # Only log critical errors
"formatter": "simple", # Use simple format
}
config["root"]["handlers"].append("eventlog")
except Exception as e:
logger.warning(f"Could not attach Windows Event Log handler: {e}")
logging.warning(f"Could not attach Windows Event Log handler: {e}")
# Apply the logging configuration
logging.config.dictConfig(config)
logging.getLogger().debug("✅ Logging configured.")
logger.debug("✅ Logging configured.")
def get_system_config_path() -> Path:
base_path = Path(getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__))))
return base_path.parent / "system_config.json"
def load_system_config() -> dict:
try:
config_path = get_system_config_path()
@@ -179,5 +200,4 @@ def setup():
os.environ["URL"] = url
logging.debug(f"Service URL set to: {url}")
write_config_to_env(merged_config, env_path)
write_config_to_env(merged_config, env_path)