Version: 1.0.0
Date: December 18, 2025
Status: Production Ready ✅
- Pre-Deployment Checklist
- Database Migrations
- API Integration
- Testing
- Production Deployment
- Monitoring & Verification
- Rollback Procedures
- Troubleshooting
Before deploying the enhanced audit logging system, ensure:
- All code changes are committed and reviewed
- Database backup is created
- Test environment is available
- Deployment window is scheduled (recommended: off-peak hours)
- Rollback plan is documented
- Team is notified of deployment
PostgreSQL:
pg_dump -U postgres -d pangolin > pangolin_backup_$(date +%Y%m%d_%H%M%S).sqlSQLite:
cp pangolin.db pangolin_backup_$(date +%Y%m%d_%H%M%S).dbMongoDB:
mongodump --db pangolin --out=pangolin_backup_$(date +%Y%m%d_%H%M%S)# Navigate to migrations directory
cd migrations/postgres
# Review the migration script
cat 001_enhanced_audit_logging.sql
# Run the migration
psql -U postgres -d pangolin < 001_enhanced_audit_logging.sql
# Verify the migration
psql -U postgres -d pangolin -c "SELECT COUNT(*) FROM audit_logs;"
psql -U postgres -d pangolin -c "SELECT action, COUNT(*) FROM audit_logs GROUP BY action LIMIT 10;"# Navigate to migrations directory
cd migrations/sqlite
# Review the migration script
cat 001_enhanced_audit_logging.sql
# Run the migration
sqlite3 pangolin.db < 001_enhanced_audit_logging.sql
# Verify the migration
sqlite3 pangolin.db "SELECT COUNT(*) FROM audit_logs;"
sqlite3 pangolin.db "SELECT action, COUNT(*) FROM audit_logs GROUP BY action LIMIT 10;"No migration needed - the enhanced schema is automatically applied when new audit events are logged.
Run these verification queries:
PostgreSQL/SQLite:
-- Check table structure
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'audit_logs';
-- Check for NULL values in required fields
SELECT
COUNT(*) FILTER (WHERE username IS NULL) as null_username,
COUNT(*) FILTER (WHERE action IS NULL) as null_action,
COUNT(*) FILTER (WHERE resource_name IS NULL) as null_resource_name,
COUNT(*) FILTER (WHERE result IS NULL) as null_result
FROM audit_logs;
-- Check index creation
SELECT indexname FROM pg_indexes WHERE tablename = 'audit_logs';Expected Results:
- All required fields should have 0 NULL values
- At least 7 indexes should be created
- Old data should be migrated successfully
The following files have been updated:
-
pangolin_api/src/lib.rs:- Added
pub mod audit_handlers; - Updated audit routes to use new handlers
- Added
-
pangolin_api/src/audit_handlers.rs:- New file with 3 endpoint handlers
- Supports filtering, pagination, and counting
# Compile the API
cargo build --release --manifest-path pangolin/Cargo.toml -p pangolin_api
# Run unit tests
cargo test --manifest-path pangolin/Cargo.toml -p pangolin_store audit
# Run integration tests (if DATABASE_URL is set)
export DATABASE_URL="postgresql://postgres:postgres@localhost/pangolin"
cargo test --manifest-path pangolin/Cargo.toml -p pangolin_store postgres_audit# Set environment variables
export DATABASE_URL="postgresql://postgres:postgres@localhost/pangolin"
export PANGOLIN_STORAGE_TYPE="postgres" # or "mongodb", "sqlite"
# Start the server
cargo run --release --manifest-path pangolin/Cargo.toml -p pangolin_apicurl -H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Pangolin-Tenant: YOUR_TENANT_ID" \
"http://localhost:8080/api/v1/audit"Expected Response: JSON array of audit events
curl -H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Pangolin-Tenant: YOUR_TENANT_ID" \
"http://localhost:8080/api/v1/audit?action=create_table&limit=10"Expected Response: JSON array of CreateTable audit events (max 10)
curl -H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Pangolin-Tenant: YOUR_TENANT_ID" \
"http://localhost:8080/api/v1/audit?result=failure"Expected Response: JSON array of failed audit events
START_TIME=$(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ)
END_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)
curl -H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Pangolin-Tenant: YOUR_TENANT_ID" \
"http://localhost:8080/api/v1/audit?start_time=$START_TIME&end_time=$END_TIME"Expected Response: JSON array of audit events from the last 7 days
# First page
curl -H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Pangolin-Tenant: YOUR_TENANT_ID" \
"http://localhost:8080/api/v1/audit?limit=50&offset=0"
# Second page
curl -H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Pangolin-Tenant: YOUR_TENANT_ID" \
"http://localhost:8080/api/v1/audit?limit=50&offset=50"Expected Response: Different sets of 50 audit events
curl -H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Pangolin-Tenant: YOUR_TENANT_ID" \
"http://localhost:8080/api/v1/audit/count?action=create_table"Expected Response: {"count": N} where N is the number of CreateTable events
curl -H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Pangolin-Tenant: YOUR_TENANT_ID" \
"http://localhost:8080/api/v1/audit/EVENT_UUID"Expected Response: Single audit event object or 404 if not found
Run the live test script:
cd scripts
chmod +x test_audit_logging.sh
./test_audit_logging.shExpected Output: All test scenarios should pass
-
Stop the API Server:
systemctl stop pangolin-api # or pkill -f pangolin_api -
Run Database Migrations:
# Follow steps in "Database Migrations" section above -
Deploy New Code:
# Pull latest code git pull origin main # Build release binary cargo build --release --manifest-path pangolin/Cargo.toml -p pangolin_api # Copy binary to deployment location cp target/release/pangolin_api /usr/local/bin/
-
Start the API Server:
systemctl start pangolin-api # or /usr/local/bin/pangolin_api &
-
Verify Deployment:
# Check server is running curl http://localhost:8080/health # Test audit endpoint curl -H "Authorization: Bearer TOKEN" \ -H "X-Pangolin-Tenant: TENANT_ID" \ "http://localhost:8080/api/v1/audit?limit=1"
Ensure these environment variables are set:
# Database connection
export DATABASE_URL="postgresql://user:pass@host:5432/pangolin"
# Storage type
export PANGOLIN_STORAGE_TYPE="postgres" # or "mongodb", "sqlite"
# Optional: Logging level
export RUST_LOG="info,pangolin_api=debug"-
API Health:
curl http://localhost:8080/health
Expected:
OK -
Database Connectivity:
psql -U postgres -d pangolin -c "SELECT 1;"Expected:
1 -
Audit Logging:
# Create a test event (e.g., create a catalog) curl -X POST -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -H "X-Pangolin-Tenant: TENANT_ID" \ -d '{"name":"test_catalog"}' \ "http://localhost:8080/api/v1/catalogs" # Verify it was logged curl -H "Authorization: Bearer TOKEN" \ -H "X-Pangolin-Tenant: TENANT_ID" \ "http://localhost:8080/api/v1/audit?action=create_catalog&limit=1"
Expected: Audit event for catalog creation
- Audit Event Count: Should increase with system activity
- Query Performance: Audit queries should complete in <100ms
- Error Rate: Should be <0.1% for audit operations
- Database Size: Monitor audit_logs table growth
Expected performance (with proper indexes):
- List audit events (100 records): <50ms
- Count audit events: <20ms
- Get specific event: <10ms
- Insert audit event: <5ms
If issues are encountered, follow these rollback steps:
systemctl stop pangolin-apiPostgreSQL:
psql -U postgres -d pangolin < pangolin_backup_TIMESTAMP.sqlSQLite:
cp pangolin_backup_TIMESTAMP.db pangolin.dbMongoDB:
mongorestore --db pangolin pangolin_backup_TIMESTAMP/pangolingit revert HEAD # or specific commit
cargo build --release --manifest-path pangolin/Cargo.toml -p pangolin_apisystemctl start pangolin-apicurl http://localhost:8080/health
curl -H "Authorization: Bearer TOKEN" \
-H "X-Pangolin-Tenant: TENANT_ID" \
"http://localhost:8080/api/v1/audit?limit=1"Cause: Referenced tables (tenants, users) don't exist
Solution:
-- Temporarily disable foreign key checks
SET CONSTRAINTS ALL DEFERRED; -- PostgreSQL
PRAGMA foreign_keys = OFF; -- SQLite
-- Run migration
-- ...
-- Re-enable foreign key checks
SET CONSTRAINTS ALL IMMEDIATE; -- PostgreSQL
PRAGMA foreign_keys = ON; -- SQLiteCause: Database connection issue or missing indexes
Solution:
-
Check database connectivity:
psql -U postgres -d pangolin -c "SELECT 1;" -
Verify indexes exist:
SELECT indexname FROM pg_indexes WHERE tablename = 'audit_logs';
-
Check API logs:
journalctl -u pangolin-api -n 100
Cause: Missing indexes or large dataset
Solution:
-
Verify indexes:
EXPLAIN ANALYZE SELECT * FROM audit_logs WHERE tenant_id = 'UUID' ORDER BY timestamp DESC LIMIT 100;
-
Add missing indexes if needed
-
Consider partitioning for very large tables (>10M rows)
Cause: Missing type annotations
Solution: Add explicit type annotations:
let store: PostgresStore = PostgresStore::new(&connection_string).await?;- API Documentation: http://localhost:8080/swagger-ui
- Migration Scripts:
/migrations/ - Test Scripts:
/scripts/test_audit_logging.sh - Implementation Guide:
.gemini/brain/.../final_summary.md
After deployment, verify:
- Database migration completed successfully
- API server is running
- Health check passes
- Audit endpoints return data
- Filtering works correctly
- Pagination works correctly
- Performance is acceptable (<100ms for queries)
- No errors in logs
- Monitoring is active
- Team is notified of successful deployment
Deployment is successful when:
- ✅ All database migrations complete without errors
- ✅ API compiles and starts successfully
- ✅ All audit endpoints return expected responses
- ✅ Query performance meets benchmarks
- ✅ No errors in application logs
- ✅ Existing functionality remains unaffected
Deployment completed successfully! 🚀
For questions or issues, contact the development team.