Properly set EV for all profiles so uWSGI daemons can see it.

This commit is contained in:
SergeantPanda 2025-05-10 13:25:03 -05:00
parent ecd9d146c6
commit 67aca64420
3 changed files with 92 additions and 12 deletions

View file

@ -2,35 +2,74 @@
import os
from celery import Celery
import logging
from django.conf import settings # Import Django settings
# Initialize with defaults before Django settings are loaded
DEFAULT_LOG_LEVEL = 'DEBUG'
# Try multiple sources for log level in order of preference
def get_effective_log_level():
# 1. Direct environment variable
env_level = os.environ.get('DISPATCHARR_LOG_LEVEL', '').upper()
if env_level and not env_level.startswith('$(') and not env_level.startswith('%('):
return env_level
# 2. Check temp file that may have been created by settings.py
try:
if os.path.exists('/tmp/dispatcharr_log_level'):
with open('/tmp/dispatcharr_log_level', 'r') as f:
file_level = f.read().strip().upper()
if file_level:
return file_level
except:
pass
# 3. Fallback to default
return DEFAULT_LOG_LEVEL
# Get effective log level before Django loads
effective_log_level = get_effective_log_level()
print(f"Celery using effective log level: {effective_log_level}")
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dispatcharr.settings')
app = Celery("dispatcharr")
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()
# Use environment variable for log level with fallback to INFO
CELERY_LOG_LEVEL = os.environ.get('DISPATCHARR_LOG_LEVEL', 'INFO').upper()
print(f"Celery using log level from environment: {CELERY_LOG_LEVEL}")
# Configure Celery logging
app.conf.update(
worker_log_level=settings.LOG_LEVEL_NAME, # Use same log level from environment
worker_log_level=effective_log_level,
worker_log_format='%(asctime)s %(levelname)s %(name)s: %(message)s',
beat_log_level=settings.LOG_LEVEL_NAME, # Use same log level from environment
beat_log_level=effective_log_level,
worker_hijack_root_logger=False,
worker_task_log_format='%(asctime)s %(levelname)s %(task_name)s: %(message)s',
)
@app.on_after_configure.connect
def setup_celery_logging(**kwargs):
# Check if user has set logging to INFO level
if settings.LOG_LEVEL_NAME.upper() == 'INFO':
# Get the specific loggers that output the noisy INFO messages
for logger_name in ['celery.app.trace', 'celery.beat', 'celery.worker.strategy', 'celery.beat.Scheduler']:
# Create a custom filter to suppress specific messages
logger = logging.getLogger(logger_name)
# Use our directly determined log level
log_level = effective_log_level
print(f"Celery configuring loggers with level: {log_level}")
# Get the specific loggers that output potentially noisy messages
for logger_name in ['celery.app.trace', 'celery.beat', 'celery.worker.strategy', 'celery.beat.Scheduler']:
logger = logging.getLogger(logger_name)
# Remove any existing filters first (in case this runs multiple times)
for filter in logger.filters[:]:
if hasattr(filter, '__class__') and filter.__class__.__name__ == 'SuppressFilter':
logger.removeFilter(filter)
# For INFO level - add a filter to hide repetitive messages
# For DEBUG/TRACE level - don't filter (show everything)
if log_level == 'INFO':
# Add a custom filter to completely filter out the repetitive messages
class SuppressFilter(logging.Filter):
def filter(self, record):
# Return False to completely suppress these specific patterns when at INFO level
# Return False to completely suppress these specific patterns
if (
"succeeded in" in getattr(record, 'msg', '') or
"Scheduler: Sending due task" in getattr(record, 'msg', '') or
@ -41,3 +80,12 @@ def setup_celery_logging(**kwargs):
# Add the filter to each logger
logger.addFilter(SuppressFilter())
# Set all Celery loggers to the configured level
# This ensures they respect TRACE/DEBUG when set
try:
numeric_level = getattr(logging, log_level)
logger.setLevel(numeric_level)
except (AttributeError, TypeError):
# If the log level string is invalid, default to DEBUG
logger.setLevel(logging.DEBUG)

View file

@ -244,7 +244,17 @@ LOG_LEVEL_MAP = {
}
# Get log level from environment variable, default to INFO if not set
LOG_LEVEL_NAME = os.environ.get('DISPATCHARR_LOG_LEVEL', 'INFO').upper()
# Add debugging output to see exactly what's being detected
env_log_level = os.environ.get('DISPATCHARR_LOG_LEVEL', '')
print(f"Environment DISPATCHARR_LOG_LEVEL detected as: '{env_log_level}'")
if not env_log_level:
print("No DISPATCHARR_LOG_LEVEL found in environment, using default INFO")
LOG_LEVEL_NAME = 'INFO'
else:
LOG_LEVEL_NAME = env_log_level.upper()
print(f"Setting log level to: {LOG_LEVEL_NAME}")
LOG_LEVEL = LOG_LEVEL_MAP.get(LOG_LEVEL_NAME, 20) # Default to INFO (20) if invalid
# Add this to your existing LOGGING configuration or create one if it doesn't exist

View file

@ -49,6 +49,14 @@ else
echo "📦 Dispatcharr version: ${DISPATCHARR_VERSION}"
fi
# Set log level with default if not provided
export DISPATCHARR_LOG_LEVEL=${DISPATCHARR_LOG_LEVEL:-info}
echo "Environment DISPATCHARR_LOG_LEVEL detected as: '${DISPATCHARR_LOG_LEVEL}'"
echo "Setting log level to: ${DISPATCHARR_LOG_LEVEL}"
# Also make the log level available in /etc/environment for all login shells
#grep -q "DISPATCHARR_LOG_LEVEL" /etc/environment || echo "DISPATCHARR_LOG_LEVEL=${DISPATCHARR_LOG_LEVEL}" >> /etc/environment
# READ-ONLY - don't let users change these
export POSTGRES_DIR=/data/db
@ -65,12 +73,24 @@ if [[ ! -f /etc/profile.d/dispatcharr.sh ]]; then
echo "export POSTGRES_PORT=$POSTGRES_PORT" >> /etc/profile.d/dispatcharr.sh
echo "export DISPATCHARR_ENV=$DISPATCHARR_ENV" >> /etc/profile.d/dispatcharr.sh
echo "export DISPATCHARR_DEBUG=$DISPATCHARR_DEBUG" >> /etc/profile.d/dispatcharr.sh
echo "export DISPATCHARR_LOG_LEVEL=$DISPATCHARR_LOG_LEVEL" >> /etc/profile.d/dispatcharr.sh
echo "export REDIS_HOST=$REDIS_HOST" >> /etc/profile.d/dispatcharr.sh
echo "export REDIS_DB=$REDIS_DB" >> /etc/profile.d/dispatcharr.sh
echo "export POSTGRES_DIR=$POSTGRES_DIR" >> /etc/profile.d/dispatcharr.sh
echo "export DISPATCHARR_PORT=$DISPATCHARR_PORT" >> /etc/profile.d/dispatcharr.sh
echo "export DISPATCHARR_VERSION=$DISPATCHARR_VERSION" >> /etc/profile.d/dispatcharr.sh
echo "export DISPATCHARR_TIMESTAMP=$DISPATCHARR_TIMESTAMP" >> /etc/profile.d/dispatcharr.sh
# Make sure we also set these variables in /etc/environment
# which is sourced even before /etc/profile.d scripts
for var in PATH VIRTUAL_ENV DJANGO_SETTINGS_MODULE PYTHONUNBUFFERED POSTGRES_DB POSTGRES_USER \
POSTGRES_PASSWORD POSTGRES_HOST POSTGRES_PORT DISPATCHARR_ENV DISPATCHARR_DEBUG \
DISPATCHARR_LOG_LEVEL REDIS_HOST REDIS_DB POSTGRES_DIR DISPATCHARR_PORT \
DISPATCHARR_VERSION DISPATCHARR_TIMESTAMP; do
if [[ -n "${!var}" ]]; then
grep -q "^${var}=" /etc/environment || echo "${var}=${!var}" >> /etc/environment
fi
done
fi
chmod +x /etc/profile.d/dispatcharr.sh
@ -127,7 +147,9 @@ else
uwsgi_file="/app/docker/uwsgi.ini"
fi
su - $POSTGRES_USER -c "cd /app && uwsgi --ini $uwsgi_file &"
# Pass all environment variables to the uwsgi process
# The -p/--preserve-environment flag ensures all environment variables are passed through
su -p - $POSTGRES_USER -c "cd /app && uwsgi --ini $uwsgi_file &"
uwsgi_pid=$(pgrep uwsgi | sort | head -n1)
echo "✅ uwsgi started with PID $uwsgi_pid"
pids+=("$uwsgi_pid")