diff --git a/spoolman/database/database.py b/spoolman/database/database.py index 2394586..61f1512 100644 --- a/spoolman/database/database.py +++ b/spoolman/database/database.py @@ -1,5 +1,6 @@ """SQLAlchemy database setup.""" +import logging from collections.abc import AsyncGenerator from typing import Optional @@ -7,6 +8,7 @@ from sqlalchemy import URL from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine from spoolman.database.models import Base +from spoolman.env import get_logging_level class Database: @@ -20,13 +22,20 @@ class Database: def connect(self: "Database") -> None: """Connect to the database.""" + if get_logging_level() == logging.DEBUG: + logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) + connect_args = {} if self.connection_url.drivername == "sqlite": connect_args["check_same_thread"] = False elif self.connection_url.drivername == "postgresql": connect_args["options"] = "-c timezone=utc" + connect_args["max_inactive_connection_lifetime"] = 3 - self.engine = create_async_engine(self.connection_url, connect_args=connect_args) + self.engine = create_async_engine( + self.connection_url, + connect_args=connect_args, + ) self.session_maker = async_sessionmaker(self.engine, autocommit=False, autoflush=True) async def create_tables(self: "Database") -> None: diff --git a/spoolman/database/spool.py b/spoolman/database/spool.py index 5d1803c..9ba2cae 100644 --- a/spoolman/database/spool.py +++ b/spoolman/database/spool.py @@ -1,6 +1,6 @@ """Helper functions for interacting with spool database objects.""" -from datetime import datetime, timezone +from datetime import datetime from typing import Optional import sqlalchemy diff --git a/spoolman/env.py b/spoolman/env.py index 66b3d37..8e99934 100644 --- a/spoolman/env.py +++ b/spoolman/env.py @@ -1,5 +1,6 @@ """Utilities for grabbing config from environment variables.""" +import logging import os from enum import Enum from pathlib import Path @@ -153,3 +154,25 @@ def get_password() -> Optional[str]: # Second attempt: grab directly from an environment variable. return os.getenv("SPOOLMAN_DB_PASSWORD") + + +def get_logging_level() -> int: + """Get the logging level from environment variables. + + Returns "INFO" if no environment variable was set for the logging level. + + Returns: + str: The logging level. + """ + log_level_str = os.getenv("SPOOLMAN_LOGGING_LEVEL", "INFO").upper() + if log_level_str == "DEBUG": + return logging.DEBUG + if log_level_str == "INFO": + return logging.INFO + if log_level_str == "WARNING": + return logging.WARNING + if log_level_str == "ERROR": + return logging.ERROR + if log_level_str == "CRITICAL": + return logging.CRITICAL + raise ValueError(f"Failed to parse SPOOLMAN_LOGGING_LEVEL variable: Unknown logging level '{log_level_str}'.") diff --git a/spoolman/main.py b/spoolman/main.py index c3e6e4d..ca2a4d2 100644 --- a/spoolman/main.py +++ b/spoolman/main.py @@ -20,17 +20,21 @@ data_dir.mkdir(parents=True, exist_ok=True) logging.basicConfig( filename=data_dir.joinpath("spoolman.log"), filemode="w", - level=logging.INFO, format="%(asctime)s:%(levelname)s:%(message)s", datefmt="%Y-%m-%d %I:%M:%S%p", ) -# Setup console logger +# Setup the base logger +spoolman_logger = logging.getLogger("spoolman") +spoolman_logger.setLevel(env.get_logging_level()) + +# Log all messages to console formatter = logging.Formatter("%(name)-12s: %(levelname)-8s %(message)s") console = logging.StreamHandler() -console.setLevel(logging.INFO) +console.setLevel(env.get_logging_level()) console.setFormatter(formatter) -logging.getLogger("").addHandler(console) +root_logger = logging.getLogger("") +root_logger.addHandler(console) # Get logger instance logger = logging.getLogger(__name__)