or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cache-monitoring.mddatabase-monitoring.mdhttp-monitoring.mdindex.mdmetrics-export.mdmigration-monitoring.mdmodel-monitoring.mdtesting-utilities.md

migration-monitoring.mddocs/

0

# Migration Monitoring

1

2

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

3

4

## Capabilities

5

6

### Migration Export Functions

7

8

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

9

10

```python { .api }

11

def ExportMigrations():

12

"""

13

Exports counts of unapplied migrations.

14

15

This is meant to be called during app startup, ideally by

16

django_prometheus.apps.AppConfig.ready().

17

18

Iterates through all database connections and exports migration

19

counts for each database alias.

20

"""

21

22

def ExportMigrationsForDatabase(alias: str, executor):

23

"""

24

Exports migration counts for a specific database.

25

26

Parameters:

27

- alias: str, database connection alias name (e.g., 'default', 'analytics')

28

- executor: Django MigrationExecutor instance for the database connection

29

"""

30

```

31

32

### Django AppConfig Integration

33

34

```python { .api }

35

class DjangoPrometheusConfig(AppConfig):

36

"""Django app configuration that automatically sets up monitoring."""

37

38

def ready(self):

39

"""

40

Initializes Prometheus exports when Django apps are ready.

41

42

Automatically calls ExportMigrations() if migration export is enabled

43

via PROMETHEUS_EXPORT_MIGRATIONS setting.

44

"""

45

```

46

47

## Monitored Metrics

48

49

### Migration Status Metrics

50

- `django_migrations_unapplied_total`: Gauge showing count of unapplied migrations by database connection

51

- `django_migrations_applied_total`: Gauge showing count of applied migrations by database connection

52

53

Both metrics include the `connection` label indicating the database alias.

54

55

## Configuration

56

57

### Settings Configuration

58

59

Enable migration monitoring in Django settings:

60

61

```python

62

# settings.py

63

64

# Enable migration monitoring (disabled by default)

65

PROMETHEUS_EXPORT_MIGRATIONS = True

66

67

# Custom metric namespace (optional)

68

PROMETHEUS_METRIC_NAMESPACE = "myapp"

69

70

# Multiple database configuration

71

DATABASES = {

72

'default': {

73

'ENGINE': 'django.db.backends.postgresql',

74

'NAME': 'main_db',

75

# ... connection settings

76

},

77

'analytics': {

78

'ENGINE': 'django.db.backends.mysql',

79

'NAME': 'analytics_db',

80

# ... connection settings

81

}

82

}

83

```

84

85

### App Configuration

86

87

Migration monitoring is automatically enabled when `django_prometheus` is in `INSTALLED_APPS`:

88

89

```python

90

# settings.py

91

INSTALLED_APPS = [

92

'django_prometheus', # Must be in INSTALLED_APPS

93

# ... other apps

94

]

95

96

# Migration monitoring happens automatically in AppConfig.ready()

97

```

98

99

## Usage Examples

100

101

### Basic Migration Monitoring

102

103

```python

104

# settings.py

105

INSTALLED_APPS = ['django_prometheus', ...]

106

PROMETHEUS_EXPORT_MIGRATIONS = True

107

108

# Migration metrics will be automatically exported when Django starts

109

# Available at /metrics endpoint or configured export port

110

```

111

112

### Multiple Database Monitoring

113

114

```python

115

# settings.py

116

DATABASES = {

117

'default': {

118

'ENGINE': 'django.db.backends.postgresql',

119

'NAME': 'main_app',

120

},

121

'user_data': {

122

'ENGINE': 'django.db.backends.mysql',

123

'NAME': 'user_database',

124

},

125

'cache_db': {

126

'ENGINE': 'django.db.backends.sqlite3',

127

'NAME': '/tmp/cache.db',

128

}

129

}

130

131

PROMETHEUS_EXPORT_MIGRATIONS = True

132

133

# Each database will have separate migration metrics:

134

# django_migrations_applied_total{connection="default"}

135

# django_migrations_applied_total{connection="user_data"}

136

# django_migrations_applied_total{connection="cache_db"}

137

```

138

139

### Manual Migration Export

140

141

```python

142

from django_prometheus.migrations import ExportMigrations, ExportMigrationsForDatabase

143

from django.db import connections

144

from django.db.migrations.executor import MigrationExecutor

145

146

# Manual export for all databases

147

ExportMigrations()

148

149

# Manual export for specific database

150

connection = connections['default']

151

executor = MigrationExecutor(connection)

152

ExportMigrationsForDatabase('default', executor)

153

```

154

155

### Custom App Configuration

156

157

```python

158

from django.apps import AppConfig

159

from django_prometheus.migrations import ExportMigrations

160

161

class MyAppConfig(AppConfig):

162

name = 'myapp'

163

164

def ready(self):

165

# Custom logic before migration export

166

if self.should_export_migrations():

167

ExportMigrations()

168

169

def should_export_migrations(self):

170

"""Custom logic to determine if migrations should be exported."""

171

return os.environ.get('EXPORT_MIGRATIONS', 'false').lower() == 'true'

172

```

173

174

## Metric Interpretation

175

176

### Understanding Migration Counts

177

178

```python

179

# Example metric values:

180

# django_migrations_applied_total{connection="default"} 42

181

# django_migrations_unapplied_total{connection="default"} 3

182

183

# This means:

184

# - 42 migrations have been applied to the 'default' database

185

# - 3 migrations are pending application

186

# - Total migrations defined: 45 (42 + 3)

187

```

188

189

### Deployment Monitoring

190

191

Use migration metrics to monitor deployment status:

192

193

```python

194

# Alerting rules for migration status:

195

# - Alert if unapplied_migrations > 0 after deployment

196

# - Alert if applied_migrations decreases (rollback scenario)

197

# - Monitor migration counts across different environments

198

```

199

200

## Integration with Django Migration System

201

202

### Migration Planning

203

204

The monitoring system uses Django's migration framework internally:

205

206

```python

207

from django.db.migrations.executor import MigrationExecutor

208

from django.db.migrations.loader import MigrationLoader

209

210

# Migration planning (done internally)

211

executor = MigrationExecutor(connection)

212

plan = executor.migration_plan(executor.loader.graph.leaf_nodes())

213

214

# Applied migrations count

215

applied_count = len(executor.loader.applied_migrations)

216

217

# Unapplied migrations count

218

unapplied_count = len(plan)

219

```

220

221

### Migration Graph Analysis

222

223

```python

224

# The system analyzes the complete migration graph

225

loader = MigrationLoader(connection)

226

227

# All defined migrations

228

all_migrations = loader.graph.nodes

229

230

# Applied migrations (from django_migrations table)

231

applied_migrations = loader.applied_migrations

232

233

# Unapplied migrations (calculated difference)

234

unapplied_migrations = set(all_migrations) - applied_migrations

235

```

236

237

## Error Handling

238

239

### Database Connection Issues

240

241

```python

242

# Graceful handling of database connection problems

243

from django.db.backends.dummy.base import DatabaseWrapper

244

245

# If DATABASES = {} (no database configured)

246

if isinstance(connections["default"], DatabaseWrapper):

247

# Skip migration export - no real database configured

248

return

249

250

# Connection-specific error handling

251

for alias in connections.databases:

252

try:

253

executor = MigrationExecutor(connections[alias])

254

ExportMigrationsForDatabase(alias, executor)

255

except Exception as e:

256

# Log error but don't crash application startup

257

logger.warning(f"Could not export migrations for {alias}: {e}")

258

```

259

260

### Migration Loader Errors

261

262

```python

263

# Handle migration loading errors gracefully

264

try:

265

loader = MigrationLoader(connection)

266

applied_migrations = loader.applied_migrations

267

except Exception as e:

268

# Set metrics to -1 to indicate error state

269

applied_migrations.labels(connection=alias).set(-1)

270

unapplied_migrations.labels(connection=alias).set(-1)

271

```

272

273

## Best Practices

274

275

### Deployment Monitoring

276

277

- Monitor migration metrics before and after deployments

278

- Set up alerts for unexpected migration counts

279

- Track migration timing across environments

280

- Use metrics to validate deployment success

281

282

### Database Management

283

284

- Monitor migration status across all database connections

285

- Track migration rollbacks (decreasing applied count)

286

- Alert on schema drift between environments

287

- Integrate with CI/CD pipelines for automated checks

288

289

### Performance Considerations

290

291

- Migration export happens once at Django startup

292

- Minimal performance impact on running application

293

- Database queries only executed during AppConfig.ready()

294

- Suitable for production use with multiple databases