ZCore LogoZCore
How to

How to configure Database and Logging

Configure asynchronous database engines with DatabaseSettings and customize structured logging with LoggingSettings and file rotation.

ZCore provides structured configuration schemas for the database engine (DatabaseSettings) and observability pipeline (LoggingSettings), supporting environment variable synchronization, declarative classes, and programmatic runtime initialization.


1. Configuring the Database Engine

Option A: Environment Variables (Zero-Code)

Set database variables in your .env file. ZCore automatically synchronizes flat environment variables with settings.DATABASE:

# .env
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/production_db
POOL_SIZE=20
MAX_OVERFLOW=10

Bootstrap db_manager in main.py:

# main.py
from zcore import db_manager, settings

db_manager.init_app(config=settings.DATABASE)

Option B: Declarative Settings Subclass

To configure engine options like connection arguments (connect_args) or execution options (execution_options), declare DATABASE in your custom Settings class:

# config.py
from zcore.config import Settings, DatabaseSettings

class AppSettings(Settings):
    DATABASE: DatabaseSettings = DatabaseSettings(
        url="postgresql+asyncpg://postgres:postgres@localhost:5432/production_db",
        pool_size=20,
        max_overflow=30,
        pool_recycle=3600,
        pool_pre_ping=True,
        connect_args={"server_settings": {"jit": "off"}},
        execution_options={"isolation_level": "REPEATABLE READ"},
        extra_engine_kwargs={}
    )

Option C: Direct db_manager.init_app Invocation

Pass a DatabaseSettings model instance or dictionary directly during startup:

# main.py
from zcore import db_manager
from zcore.config import DatabaseSettings

db_manager.init_app(
    config=DatabaseSettings(
        url="postgresql+asyncpg://postgres:postgres@localhost:5432/production_db",
        pool_size=15,
        connect_args={"timeout": 30}
    )
)

2. Configuring Structured Logging

Option A: Standard Setup with .env

# .env
LOG_LEVEL=INFO
LOG_SQL_QUERIES=False              # Flat setting for query logging
SLOW_QUERY_THRESHOLD_MS=200.0      # Independently track slow queries

Initialize logging at the beginning of main.py:

# main.py
from zcore.logging import setup_logging

setup_logging()

Option B: Declarative LoggingSettings

Configure file rotation boundaries (max_bytes, backup_count), slow SQL query thresholds, and distinct logger behaviors (muted, passthrough, intercept) in your Settings subclass:

# config.py
from zcore.config import Settings, LoggingSettings

class AppSettings(Settings):
    LOGGING: LoggingSettings = LoggingSettings(
        level="INFO",
        json_format=None,              # None: Console in Debug, JSON in Production
        log_sql_queries=False,         # Disabled by default in rc.2 to avoid noise
        slow_query_threshold_ms=200.0, # Log only queries exceeding 200ms (works independently!)
        file_path="./logs/app.log",    # Enables RotatingFileHandler
        max_bytes=20 * 1024 * 1024,    # Rotate when file reaches 20MB (default: 10MB)
        backup_count=10,               # Retain 10 rotated log backups (default: 5)
        muted_loggers=["sqlalchemy.engine"],
        passthrough_loggers=["uvicorn", "uvicorn.access", "uvicorn.error"]
    )

Option C: Advanced Programmatic Overrides

setup_logging supports custom structlog processors, extra standard library handlers, and complete logging.config.dictConfig overrides:

# main.py
import logging
from zcore.logging import setup_logging, LoggingSettings

# 1. Custom handlers and processors
setup_logging(
    config=LoggingSettings(
        level="DEBUG",
        file_path="./logs/app.log",
        max_bytes=10 * 1024 * 1024,
        backup_count=5
    ),
    extra_handlers=[logging.StreamHandler()],
    log_level="DEBUG"
)

# 2. Complete dictConfig override
setup_logging(
    dict_config={
        "version": 1,
        "disable_existing_loggers": False,
        "handlers": {
            "console": {"class": "logging.StreamHandler", "level": "INFO"}
        },
        "root": {"handlers": ["console"], "level": "INFO"}
    }
)

SQL Query Logging: When log_sql_queries is enabled, executed statements are formatted with duration metrics (duration_ms). If slow_query_threshold_ms is set, queries exceeding this limit are tracked and logged independently, even if general query logging is turned off.

On this page