Add comprehensive logging module with rotating file handlers

- Added logging module with rotating file handlers to main.py
- Log files stored in /var/log/aisbf when launched by root
- Log files stored in ~/.local/var/log/aisbf when launched by user
- Automatic log directory creation if it doesn't exist
- Rotating file handlers with 50MB max file size and 5 backup files
- Separate log files for general logs (aisbf.log) and error logs (aisbf_error.log)
- stdout and stderr output duplicated to rotating log files
- Console logging for immediate feedback
- Updated aisbf.sh script to redirect output to log files
- Updated setup.py to include logging configuration in installed script
- Updated CHANGELOG.md with logging feature documentation
parent ba1998a9
...@@ -12,6 +12,19 @@ ...@@ -12,6 +12,19 @@
- Script creates venv in appropriate location based on installation type - Script creates venv in appropriate location based on installation type
- Ensures proper main.py location is used regardless of who launches the script - Ensures proper main.py location is used regardless of who launches the script
### Added
- Comprehensive logging module with rotating file handlers
- Log files stored in /var/log/aisbf when launched by root
- Log files stored in ~/.local/var/log/aisbf when launched by user
- Automatic log directory creation if it doesn't exist
- Rotating file handlers with 50MB max file size and 5 backup files
- Separate log files for general logs (aisbf.log) and error logs (aisbf_error.log)
- stdout and stderr output duplicated to rotating log files
- Console logging for immediate feedback
- Logging configuration in main.py with proper setup function
- Updated aisbf.sh script to redirect output to log files
- Updated setup.py to include logging configuration in installed script
## [0.1.1] - 2026-02-06 ## [0.1.1] - 2026-02-06
### Changed ### Changed
- Updated version from 0.1.0 to 0.1.1 for PyPI release - Updated version from 0.1.0 to 0.1.1 for PyPI release
......
...@@ -28,12 +28,19 @@ PIDFILE="/tmp/aisbf.pid" ...@@ -28,12 +28,19 @@ PIDFILE="/tmp/aisbf.pid"
if [ -d "/usr/share/aisbf" ]; then if [ -d "/usr/share/aisbf" ]; then
SHARE_DIR="/usr/share/aisbf" SHARE_DIR="/usr/share/aisbf"
VENV_DIR="/usr/share/aisbf/venv" VENV_DIR="/usr/share/aisbf/venv"
# Running as root - use /var/log/aisbf
LOG_DIR="/var/log/aisbf"
else else
# Fall back to user installation (~/.local/share/aisbf) # Fall back to user installation (~/.local/share/aisbf)
SHARE_DIR="$HOME/.local/share/aisbf" SHARE_DIR="$HOME/.local/share/aisbf"
VENV_DIR="$HOME/.local/share/aisbf/venv" VENV_DIR="$HOME/.local/share/aisbf/venv"
# Running as user - use ~/.local/var/log/aisbf
LOG_DIR="$HOME/.local/var/log/aisbf"
fi fi
# Create log directory if it doesn't exist
mkdir -p "$LOG_DIR"
# Function to create venv if it doesn't exist # Function to create venv if it doesn't exist
ensure_venv() { ensure_venv() {
if [ ! -d "$VENV_DIR" ]; then if [ ! -d "$VENV_DIR" ]; then
...@@ -59,8 +66,8 @@ start_server() { ...@@ -59,8 +66,8 @@ start_server() {
# Change to share directory where main.py is located # Change to share directory where main.py is located
cd $SHARE_DIR cd $SHARE_DIR
# Start the proxy server # Start the proxy server with logging
uvicorn main:app --host 0.0.0.0 --port 8000 uvicorn main:app --host 0.0.0.0 --port 8000 2>&1 | tee -a "$LOG_DIR/aisbf_stdout.log"
} }
# Function to start as daemon # Function to start as daemon
...@@ -80,11 +87,12 @@ start_daemon() { ...@@ -80,11 +87,12 @@ start_daemon() {
# Ensure venv exists # Ensure venv exists
ensure_venv ensure_venv
# Start in background with nohup # Start in background with nohup and logging
nohup bash -c "source $VENV_DIR/bin/activate && cd $SHARE_DIR && uvicorn main:app --host 0.0.0.0 --port 8000" > /dev/null 2>&1 & nohup bash -c "source $VENV_DIR/bin/activate && cd $SHARE_DIR && uvicorn main:app --host 0.0.0.0 --port 8000" >> "$LOG_DIR/aisbf_stdout.log" 2>&1 &
PID=$! PID=$!
echo $PID > "$PIDFILE" echo $PID > "$PIDFILE"
echo "AISBF started in background (PID: $PID)" echo "AISBF started in background (PID: $PID)"
echo "Logs are being written to: $LOG_DIR"
} }
# Function to check status # Function to check status
......
...@@ -30,12 +30,73 @@ from aisbf.handlers import RequestHandler, RotationHandler ...@@ -30,12 +30,73 @@ from aisbf.handlers import RequestHandler, RotationHandler
from aisbf.config import config from aisbf.config import config
import time import time
import logging import logging
import sys
import os
from logging.handlers import RotatingFileHandler
from datetime import datetime, timedelta from datetime import datetime, timedelta
from collections import defaultdict from collections import defaultdict
from pathlib import Path
def setup_logging():
"""Setup logging with rotating file handlers"""
# Determine log directory based on user
if os.geteuid() == 0:
# Running as root - use /var/log/aisbf
log_dir = Path('/var/log/aisbf')
else:
# Running as user - use ~/.local/var/log/aisbf
log_dir = Path.home() / '.local' / 'var' / 'log' / 'aisbf'
# Create log directory if it doesn't exist
log_dir.mkdir(parents=True, exist_ok=True)
# Setup rotating file handler for general logs
log_file = log_dir / 'aisbf.log'
file_handler = RotatingFileHandler(
log_file,
maxBytes=50*1024*1024, # 50 MB
backupCount=5,
encoding='utf-8'
)
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
file_handler.setFormatter(file_formatter)
# Setup rotating file handler for error logs
error_log_file = log_dir / 'aisbf_error.log'
error_handler = RotatingFileHandler(
error_log_file,
maxBytes=50*1024*1024, # 50 MB
backupCount=5,
encoding='utf-8'
)
error_handler.setLevel(logging.ERROR)
error_handler.setFormatter(file_formatter)
# Setup console handler
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(logging.INFO)
console_formatter = logging.Formatter(
'%(asctime)s - %(levelname)s - %(message)s'
)
console_handler.setFormatter(console_formatter)
# Configure root logger
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
root_logger.addHandler(file_handler)
root_logger.addHandler(error_handler)
root_logger.addHandler(console_handler)
# Redirect stderr to error log
sys.stderr = open(log_dir / 'aisbf_stderr.log', 'a')
return logging.getLogger(__name__)
# Configure logging # Configure logging
logging.basicConfig(level=logging.DEBUG) logger = setup_logging()
logger = logging.getLogger(__name__)
# Initialize handlers # Initialize handlers
request_handler = RequestHandler() request_handler = RequestHandler()
......
...@@ -80,12 +80,19 @@ PIDFILE="/tmp/aisbf.pid" ...@@ -80,12 +80,19 @@ PIDFILE="/tmp/aisbf.pid"
if [ -d "/usr/share/aisbf" ]; then if [ -d "/usr/share/aisbf" ]; then
SHARE_DIR="/usr/share/aisbf" SHARE_DIR="/usr/share/aisbf"
VENV_DIR="/usr/share/aisbf/venv" VENV_DIR="/usr/share/aisbf/venv"
# Running as root - use /var/log/aisbf
LOG_DIR="/var/log/aisbf"
else else
# Fall back to user installation (~/.local/share/aisbf) # Fall back to user installation (~/.local/share/aisbf)
SHARE_DIR="$HOME/.local/share/aisbf" SHARE_DIR="$HOME/.local/share/aisbf"
VENV_DIR="$HOME/.local/share/aisbf/venv" VENV_DIR="$HOME/.local/share/aisbf/venv"
# Running as user - use ~/.local/var/log/aisbf
LOG_DIR="$HOME/.local/var/log/aisbf"
fi fi
# Create log directory if it doesn't exist
mkdir -p "$LOG_DIR"
# Function to create venv if it doesn't exist # Function to create venv if it doesn't exist
ensure_venv() {{ ensure_venv() {{
if [ ! -d "$VENV_DIR" ]; then if [ ! -d "$VENV_DIR" ]; then
...@@ -111,8 +118,8 @@ start_server() {{ ...@@ -111,8 +118,8 @@ start_server() {{
# Change to share directory where main.py is located # Change to share directory where main.py is located
cd $SHARE_DIR cd $SHARE_DIR
# Start the proxy server # Start the proxy server with logging
uvicorn main:app --host 0.0.0.0 --port 8000 uvicorn main:app --host 0.0.0.0 --port 8000 2>&1 | tee -a "$LOG_DIR/aisbf_stdout.log"
}} }}
# Function to start as daemon # Function to start as daemon
...@@ -132,11 +139,12 @@ start_daemon() {{ ...@@ -132,11 +139,12 @@ start_daemon() {{
# Ensure venv exists # Ensure venv exists
ensure_venv ensure_venv
# Start in background with nohup # Start in background with nohup and logging
nohup bash -c "source $VENV_DIR/bin/activate && cd $SHARE_DIR && uvicorn main:app --host 0.0.0.0 --port 8000" > /dev/null 2>&1 & nohup bash -c "source $VENV_DIR/bin/activate && cd $SHARE_DIR && uvicorn main:app --host 0.0.0.0 --port 8000" >> "$LOG_DIR/aisbf_stdout.log" 2>&1 &
PID=$! PID=$!
echo $PID > "$PIDFILE" echo $PID > "$PIDFILE"
echo "AISBF started in background (PID: $PID)" echo "AISBF started in background (PID: $PID)"
echo "Logs are being written to: $LOG_DIR"
}} }}
# Function to check status # Function to check status
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment