Refactor logging configuration to use AppData directory

- Updated config.example.json to set default log_file to null.
- Modified config.py to resolve log file paths relative to the AppData directory.
- Added methods to get default log directory and log file path in AppData.
- Ensured logging behavior is consistent whether a log_file is specified or not.
This commit is contained in:
claudi 2026-02-20 07:45:21 +01:00
parent b3fd61aed2
commit a8aa54fa5e
8 changed files with 2932 additions and 2884 deletions

View file

@ -10,7 +10,8 @@ WEBAPP_URL=file:///./webapp/index.html
# Logging # Logging
LOG_LEVEL=DEBUG LOG_LEVEL=DEBUG
LOG_FILE=logs/webdrop_bridge.log # LOG_FILE defaults to AppData/Roaming/webdrop_bridge/logs/webdrop_bridge.log if not set
# LOG_FILE=logs/webdrop_bridge.log
ENABLE_LOGGING=true ENABLE_LOGGING=true
# Security - Path Whitelist # Security - Path Whitelist

View file

@ -103,6 +103,13 @@ Z:\aN5PysnXIuRECzcRbvHkjL7g0\Hintergrund_Agravity.png
- Options: `"DEBUG"`, `"INFO"`, `"WARNING"`, `"ERROR"`, `"CRITICAL"` - Options: `"DEBUG"`, `"INFO"`, `"WARNING"`, `"ERROR"`, `"CRITICAL"`
- Default: `"INFO"` - Default: `"INFO"`
- **`log_file`** (string, optional): Path to log file
- If `null` or not specified: Logs to `%APPDATA%\webdrop_bridge\logs\webdrop_bridge.log` (Windows) or `~/.local/share/webdrop_bridge/logs/webdrop_bridge.log` (macOS/Linux)
- If relative path: Resolved relative to the app data directory (same as above location)
- If absolute path: Used as-is
- Default: `null` (uses AppData directory for permissions compatibility)
- **Important**: Logs are always stored in the user's AppData directory to ensure the app can write logs in both development and installed scenarios
- **`enable_logging`** (boolean): Whether to write logs to file - **`enable_logging`** (boolean): Whether to write logs to file
- Default: `true` - Default: `true`

File diff suppressed because one or more lines are too long

View file

@ -5,7 +5,7 @@
Manufacturer="HIM-Tools" Manufacturer="HIM-Tools"
UpgradeCode="12345678-1234-1234-1234-123456789012"> UpgradeCode="12345678-1234-1234-1234-123456789012">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perUser" Platform="x64" /> <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Platform="x64" />
<Media Id="1" Cabinet="WebDropBridge.cab" EmbedCab="yes" /> <Media Id="1" Cabinet="WebDropBridge.cab" EmbedCab="yes" />
<!-- Required property for WixUI_InstallDir dialog set --> <!-- Required property for WixUI_InstallDir dialog set -->
@ -30,7 +30,7 @@
</Feature> </Feature>
<Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="LocalAppDataFolder"> <Directory Id="ProgramFiles64Folder">
<Directory Id="INSTALLFOLDER" Name="WebDrop Bridge" /> <Directory Id="INSTALLFOLDER" Name="WebDrop Bridge" />
</Directory> </Directory>
<Directory Id="ProgramMenuFolder"> <Directory Id="ProgramMenuFolder">

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,7 @@
"auto_check_updates": true, "auto_check_updates": true,
"update_check_interval_hours": 24, "update_check_interval_hours": 24,
"log_level": "INFO", "log_level": "INFO",
"log_file": "logs/webdrop_bridge.log", "log_file": null,
"window_width": 1024, "window_width": 1024,
"window_height": 768, "window_height": 768,
"enable_logging": true "enable_logging": true

View file

@ -126,8 +126,15 @@ class Config:
# Get log file path # Get log file path
log_file = None log_file = None
if data.get("enable_logging", True): if data.get("enable_logging", True):
log_file_str = data.get("log_file", "logs/webdrop_bridge.log") log_file_str = data.get("log_file", None)
log_file = Path(log_file_str).resolve() if log_file_str:
log_file = Path(log_file_str)
# If relative path, resolve relative to app data directory instead of cwd
if not log_file.is_absolute():
log_file = Config.get_default_log_dir() / log_file
else:
# Use default log path in app data
log_file = Config.get_default_log_path()
app_name = data.get("app_name", "WebDrop Bridge") app_name = data.get("app_name", "WebDrop Bridge")
window_title = data.get("window_title", f"{app_name} v{__version__}") window_title = data.get("window_title", f"{app_name} v{__version__}")
@ -178,7 +185,7 @@ class Config:
else: else:
app_version = os.getenv("APP_VERSION") app_version = os.getenv("APP_VERSION")
log_level = os.getenv("LOG_LEVEL", "INFO").upper() log_level = os.getenv("LOG_LEVEL", "INFO").upper()
log_file_str = os.getenv("LOG_FILE", "logs/webdrop_bridge.log") log_file_str = os.getenv("LOG_FILE", None)
allowed_roots_str = os.getenv("ALLOWED_ROOTS", "Z:/,C:/Users/Public") allowed_roots_str = os.getenv("ALLOWED_ROOTS", "Z:/,C:/Users/Public")
allowed_urls_str = os.getenv("ALLOWED_URLS", "") allowed_urls_str = os.getenv("ALLOWED_URLS", "")
webapp_url = os.getenv("WEBAPP_URL", "https://dev.agravity.io/") webapp_url = os.getenv("WEBAPP_URL", "https://dev.agravity.io/")
@ -227,7 +234,14 @@ class Config:
# Create log file path if logging enabled # Create log file path if logging enabled
log_file = None log_file = None
if enable_logging: if enable_logging:
log_file = Path(log_file_str).resolve() if log_file_str:
log_file = Path(log_file_str)
# If relative path, resolve relative to app data directory instead of cwd
if not log_file.is_absolute():
log_file = Config.get_default_log_dir() / log_file
else:
# Use default log path in app data
log_file = Config.get_default_log_path()
# Validate webapp URL is not empty # Validate webapp URL is not empty
if not webapp_url: if not webapp_url:
@ -320,7 +334,7 @@ class Config:
"""Get the default configuration file path. """Get the default configuration file path.
Returns: Returns:
Path to default config file Path to default config file in user's AppData/Roaming
""" """
import platform import platform
if platform.system() == "Windows": if platform.system() == "Windows":
@ -329,6 +343,32 @@ class Config:
base = Path.home() / ".config" base = Path.home() / ".config"
return base / "webdrop_bridge" / "config.json" return base / "webdrop_bridge" / "config.json"
@staticmethod
def get_default_log_dir() -> Path:
"""Get the default directory for log files.
Always uses user's AppData directory to ensure permissions work
correctly in both development and installed scenarios.
Returns:
Path to default logs directory in user's AppData/Roaming
"""
import platform
if platform.system() == "Windows":
base = Path.home() / "AppData" / "Roaming"
else:
base = Path.home() / ".local" / "share"
return base / "webdrop_bridge" / "logs"
@staticmethod
def get_default_log_path() -> Path:
"""Get the default log file path.
Returns:
Path to default log file in user's AppData/Roaming/webdrop_bridge/logs
"""
return Config.get_default_log_dir() / "webdrop_bridge.log"
def __repr__(self) -> str: def __repr__(self) -> str:
"""Return developer-friendly representation.""" """Return developer-friendly representation."""
return ( return (