CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-prometheus

Django middlewares to monitor your application with Prometheus.io

Pending
Overview
Eval results
Files

migration-monitoring.mddocs/

Migration Monitoring

Track applied and unapplied Django migrations across database connections to monitor deployment and migration status. Provides visibility into database schema state and migration progress.

Capabilities

Migration Export Functions

Functions to track and export Django migration status as Prometheus metrics.

def ExportMigrations():
    """
    Exports counts of unapplied migrations.
    
    This is meant to be called during app startup, ideally by
    django_prometheus.apps.AppConfig.ready().
    
    Iterates through all database connections and exports migration
    counts for each database alias.
    """

def ExportMigrationsForDatabase(alias: str, executor):
    """
    Exports migration counts for a specific database.
    
    Parameters:
    - alias: str, database connection alias name (e.g., 'default', 'analytics')
    - executor: Django MigrationExecutor instance for the database connection
    """

Django AppConfig Integration

class DjangoPrometheusConfig(AppConfig):
    """Django app configuration that automatically sets up monitoring."""
    
    def ready(self):
        """
        Initializes Prometheus exports when Django apps are ready.
        
        Automatically calls ExportMigrations() if migration export is enabled
        via PROMETHEUS_EXPORT_MIGRATIONS setting.
        """

Monitored Metrics

Migration Status Metrics

  • django_migrations_unapplied_total: Gauge showing count of unapplied migrations by database connection
  • django_migrations_applied_total: Gauge showing count of applied migrations by database connection

Both metrics include the connection label indicating the database alias.

Configuration

Settings Configuration

Enable migration monitoring in Django settings:

# settings.py

# Enable migration monitoring (disabled by default)
PROMETHEUS_EXPORT_MIGRATIONS = True

# Custom metric namespace (optional)
PROMETHEUS_METRIC_NAMESPACE = "myapp"

# Multiple database configuration
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'main_db',
        # ... connection settings
    },
    'analytics': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'analytics_db',
        # ... connection settings
    }
}

App Configuration

Migration monitoring is automatically enabled when django_prometheus is in INSTALLED_APPS:

# settings.py
INSTALLED_APPS = [
    'django_prometheus',  # Must be in INSTALLED_APPS
    # ... other apps
]

# Migration monitoring happens automatically in AppConfig.ready()

Usage Examples

Basic Migration Monitoring

# settings.py
INSTALLED_APPS = ['django_prometheus', ...]
PROMETHEUS_EXPORT_MIGRATIONS = True

# Migration metrics will be automatically exported when Django starts
# Available at /metrics endpoint or configured export port

Multiple Database Monitoring

# settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'main_app',
    },
    'user_data': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'user_database', 
    },
    'cache_db': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': '/tmp/cache.db',
    }
}

PROMETHEUS_EXPORT_MIGRATIONS = True

# Each database will have separate migration metrics:
# django_migrations_applied_total{connection="default"} 
# django_migrations_applied_total{connection="user_data"}
# django_migrations_applied_total{connection="cache_db"}

Manual Migration Export

from django_prometheus.migrations import ExportMigrations, ExportMigrationsForDatabase
from django.db import connections
from django.db.migrations.executor import MigrationExecutor

# Manual export for all databases
ExportMigrations()

# Manual export for specific database
connection = connections['default']
executor = MigrationExecutor(connection)
ExportMigrationsForDatabase('default', executor)

Custom App Configuration

from django.apps import AppConfig
from django_prometheus.migrations import ExportMigrations

class MyAppConfig(AppConfig):
    name = 'myapp'
    
    def ready(self):
        # Custom logic before migration export
        if self.should_export_migrations():
            ExportMigrations()
    
    def should_export_migrations(self):
        """Custom logic to determine if migrations should be exported."""
        return os.environ.get('EXPORT_MIGRATIONS', 'false').lower() == 'true'

Metric Interpretation

Understanding Migration Counts

# Example metric values:
# django_migrations_applied_total{connection="default"} 42
# django_migrations_unapplied_total{connection="default"} 3

# This means:
# - 42 migrations have been applied to the 'default' database
# - 3 migrations are pending application
# - Total migrations defined: 45 (42 + 3)

Deployment Monitoring

Use migration metrics to monitor deployment status:

# Alerting rules for migration status:
# - Alert if unapplied_migrations > 0 after deployment
# - Alert if applied_migrations decreases (rollback scenario)
# - Monitor migration counts across different environments

Integration with Django Migration System

Migration Planning

The monitoring system uses Django's migration framework internally:

from django.db.migrations.executor import MigrationExecutor
from django.db.migrations.loader import MigrationLoader

# Migration planning (done internally)
executor = MigrationExecutor(connection)
plan = executor.migration_plan(executor.loader.graph.leaf_nodes())

# Applied migrations count
applied_count = len(executor.loader.applied_migrations)

# Unapplied migrations count  
unapplied_count = len(plan)

Migration Graph Analysis

# The system analyzes the complete migration graph
loader = MigrationLoader(connection)

# All defined migrations
all_migrations = loader.graph.nodes

# Applied migrations (from django_migrations table)
applied_migrations = loader.applied_migrations

# Unapplied migrations (calculated difference)
unapplied_migrations = set(all_migrations) - applied_migrations

Error Handling

Database Connection Issues

# Graceful handling of database connection problems
from django.db.backends.dummy.base import DatabaseWrapper

# If DATABASES = {} (no database configured)
if isinstance(connections["default"], DatabaseWrapper):
    # Skip migration export - no real database configured
    return

# Connection-specific error handling
for alias in connections.databases:
    try:
        executor = MigrationExecutor(connections[alias])
        ExportMigrationsForDatabase(alias, executor)
    except Exception as e:
        # Log error but don't crash application startup
        logger.warning(f"Could not export migrations for {alias}: {e}")

Migration Loader Errors

# Handle migration loading errors gracefully
try:
    loader = MigrationLoader(connection)
    applied_migrations = loader.applied_migrations
except Exception as e:
    # Set metrics to -1 to indicate error state
    applied_migrations.labels(connection=alias).set(-1)
    unapplied_migrations.labels(connection=alias).set(-1)

Best Practices

Deployment Monitoring

  • Monitor migration metrics before and after deployments
  • Set up alerts for unexpected migration counts
  • Track migration timing across environments
  • Use metrics to validate deployment success

Database Management

  • Monitor migration status across all database connections
  • Track migration rollbacks (decreasing applied count)
  • Alert on schema drift between environments
  • Integrate with CI/CD pipelines for automated checks

Performance Considerations

  • Migration export happens once at Django startup
  • Minimal performance impact on running application
  • Database queries only executed during AppConfig.ready()
  • Suitable for production use with multiple databases

Install with Tessl CLI

npx tessl i tessl/pypi-django-prometheus

docs

cache-monitoring.md

database-monitoring.md

http-monitoring.md

index.md

metrics-export.md

migration-monitoring.md

model-monitoring.md

testing-utilities.md

tile.json