Database Handler
Store log messages in PostgreSQL, MySQL/MariaDB, or SQLite databases.
Installation
# PostgreSQL
pip install richcolorlog[postgresql]
# or
pip install psycopg2-binary
# MySQL/MariaDB
pip install richcolorlog[mysql]
# or
pip install mysql-connector-python
# SQLite - included with Python
Basic Usage
from richcolorlog import setup_logging
# PostgreSQL
logger = setup_logging(
db=True,
db_type='postgresql',
db_host='localhost',
db_name='logs',
db_user='postgres',
db_password='password',
)
logger.info("This goes to the database!")
Configuration Parameters
Parameter |
Default |
Description |
|---|---|---|
|
|
Enable database handler |
|
|
Database type: postgresql, mysql, mariadb, sqlite |
|
|
Database server hostname |
|
Auto |
Database port (auto-detected by type) |
|
|
Database name (or file path for SQLite) |
|
|
Database username |
|
|
Database password |
|
|
Minimum level for database |
Database-Specific Examples
PostgreSQL
logger = setup_logging(
db=True,
db_type='postgresql',
db_host='localhost',
db_port=5432,
db_name='app_logs',
db_user='logger',
db_password='secure_password',
)
MySQL
logger = setup_logging(
db=True,
db_type='mysql',
db_host='localhost',
db_port=3306,
db_name='app_logs',
db_user='logger',
db_password='secure_password',
)
MariaDB
logger = setup_logging(
db=True,
db_type='mariadb',
db_host='localhost',
db_port=3306,
db_name='app_logs',
db_user='logger',
db_password='secure_password',
)
SQLite
logger = setup_logging(
db=True,
db_type='sqlite',
db_name='logs.db', # File path
)
Table Schema
Tables are created automatically for each log level:
-- Created tables:
-- log_emergency, log_alert, log_fatal, log_critical,
-- log_error, log_warning, log_notice, log_info, log_debug
-- log_syslog (combined)
CREATE TABLE log_info (
id SERIAL PRIMARY KEY,
timestamp TIMESTAMP NOT NULL,
level VARCHAR(20) NOT NULL,
logger VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
module VARCHAR(255),
function VARCHAR(255),
lineno INTEGER,
pathname TEXT,
process INTEGER,
thread BIGINT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Level-Based Tables
Logs are stored in level-specific tables:
Level |
Table Name |
|---|---|
EMERGENCY |
|
ALERT |
|
FATAL |
|
CRITICAL |
|
ERROR |
|
WARNING |
|
NOTICE |
|
INFO |
|
DEBUG |
|
All logs also go to log_syslog for unified queries.
Querying Logs
-- All errors from today
SELECT * FROM log_error
WHERE timestamp >= CURRENT_DATE
ORDER BY timestamp DESC;
-- All logs from a specific logger
SELECT * FROM log_syslog
WHERE logger = 'myapp.auth'
ORDER BY timestamp DESC
LIMIT 100;
-- Count by level
SELECT level, COUNT(*) as count
FROM log_syslog
WHERE timestamp >= NOW() - INTERVAL '1 hour'
GROUP BY level;
-- Search in messages
SELECT * FROM log_syslog
WHERE message LIKE '%user%'
ORDER BY timestamp DESC;
Database Setup
PostgreSQL
-- Create database
CREATE DATABASE app_logs;
-- Create user
CREATE USER logger WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE app_logs TO logger;
-- Connect and grant schema permissions
\\c app_logs
GRANT ALL ON SCHEMA public TO logger;
GRANT ALL ON ALL TABLES IN SCHEMA public TO logger;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO logger;
MySQL
-- Create database
CREATE DATABASE app_logs;
-- Create user
CREATE USER 'logger'@'%' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON app_logs.* TO 'logger'@'%';
FLUSH PRIVILEGES;
Production Configuration
logger = setup_logging(
name='production_app',
level='INFO',
# Database - store warnings and above
db=True,
db_type='postgresql',
db_host='db.example.com',
db_port=5432,
db_name='production_logs',
db_user='logger',
db_password='secure_password',
db_level='WARNING',
)
Connection Pooling
For high-volume logging, use connection pooling:
import logging
from richcolorlog.logger import DatabaseHandler
# Custom handler with pooling
class PooledDatabaseHandler(DatabaseHandler):
def __init__(self, pool, **kwargs):
self.pool = pool
super().__init__(**kwargs)
def _connect(self):
self.connection = self.pool.getconn()
def close(self):
self.pool.putconn(self.connection)
Indexing
Add indexes for better query performance:
-- Index for timestamp queries
CREATE INDEX idx_log_syslog_timestamp
ON log_syslog(timestamp);
-- Index for logger queries
CREATE INDEX idx_log_syslog_logger
ON log_syslog(logger);
-- Composite index
CREATE INDEX idx_log_syslog_timestamp_level
ON log_syslog(timestamp, level);
Cleanup/Retention
Implement log retention:
-- Delete logs older than 30 days
DELETE FROM log_syslog
WHERE timestamp < NOW() - INTERVAL '30 days';
-- PostgreSQL: partitioning for large tables
CREATE TABLE log_syslog_2025_01 PARTITION OF log_syslog
FOR VALUES FROM ('2025-01-01') TO ('2025-02-01');
Direct Handler Usage
import logging
from richcolorlog.logger import DatabaseHandler
handler = DatabaseHandler(
db_type='postgresql',
host='localhost',
port=5432,
database='logs',
user='logger',
password='password',
level=logging.WARNING
)
logger = logging.getLogger('myapp')
logger.addHandler(handler)
Cleanup
# Manual cleanup
for handler in logger.handlers:
if isinstance(handler, DatabaseHandler):
handler.close()
# Or use logging shutdown
logging.shutdown()