Automated APM & FinOps engine for Apache Spark and Databricks
Project description
๐ APM Spark Auditor - Automated Performance Monitoring & FinOps Engine
Enterprise-grade automated performance auditor for Apache Spark and Databricks workloads
APM Spark Auditor is an intelligent performance monitoring framework that automatically detects anti-patterns in Spark execution plans, provides actionable remediation suggestions, and estimates the financial impact of performance issues. It works seamlessly with both traditional Spark clusters and modern Databricks Serverless/Connect architectures.
๐ Table of Contents
- Overview
- Key Features
- Detected Performance Issues
- Architecture
- Installation
- Quick Start
- Usage Examples
- Configuration
- Testing
- Project Structure
- Contributing
- License
๐ฏ Overview
The APM Spark Auditor analyzes Spark execution plans (Catalyst optimizer output) and DataFrame schemas to identify performance bottlenecks, inefficient query patterns, and cost optimization opportunities. It provides:
- Automated Detection: 10 comprehensive rules covering the most common Spark performance anti-patterns
- FinOps Integration: Financial impact estimation for identified issues (DBU cost calculation)
- Actionable Remediation: Code-level suggestions and templates for fixing detected problems
- Multi-Environment Support: Works with vanilla Spark, Databricks clusters, and Serverless/Connect
- Zero-Overhead Analysis: Non-intrusive inspection of execution plans without job execution
โจ Key Features
๐ Intelligent Analysis Engine
- Parses Catalyst physical execution plans
- Analyzes DataFrame schemas and metadata
- Detects structural and query-level anti-patterns
- Context-aware recommendations based on cluster type
๐ฐ FinOps Cost Estimation
- Calculates estimated waste in USD
- Factors in DBU pricing and cluster configuration
- Provides monthly cost projections for persistent issues
- Supports both real Databricks costs and simulation mode
๐ ๏ธ Comprehensive Remediation
- Generates targeted suggestions for each detected issue
- Includes executable code templates
- Adapts recommendations to cluster context (Serverless vs Classic)
๐ญ Multi-Platform Compatibility
- Traditional Spark: Local and cluster deployments
- Databricks Classic: Single-user and shared clusters
- Databricks Serverless: Spark Connect architecture
- Docker: Containerized execution support
๐ Rich Reporting
- Console output with detailed alerts
- Severity levels (CRITICAL, HIGH, WARNING)
- Metrics capture for audit trails
- Structured data models for integration
๐ Detected Performance Issues
The engine detects 10 critical performance anti-patterns (PERF-001 to PERF-010):
| Rule ID | Issue | Impact | Severity |
|---|---|---|---|
| PERF-001 | Small Files Problem | Excessive metadata management, slow reads | WARNING |
| PERF-002 | Missed Broadcast Join | Unnecessary shuffle operations on small tables | WARNING |
| PERF-003 | Type Casting in Filters | Blocks Data Skipping indexes, forces full table scans | WARNING |
| PERF-004 | Over-Partitioning | Directory explosion, Driver JVM paralysis | HIGH |
| PERF-005 | Cartesian Product | Memory explosion, OutOfMemory risk | CRITICAL |
| PERF-006 | Data Skew | Unbalanced workload distribution | HIGH |
| PERF-007 | Missing Physical Optimization | No Z-Order/Liquid Clustering indexes | WARNING |
| PERF-008 | Explode Abuse | Avalanche row multiplication in memory | WARNING |
| PERF-009 | Redundant Table Scan | Multiple reads of same source without caching | WARNING |
| PERF-010 | Non-Vectorized UDF | Row-by-row processing, JVM/Python serialization overhead | HIGH |
๐๏ธ Architecture
System Components
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ APMAutomatedOrchestrator โ
โ (Main Entry Point & Coordinator) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Readers โ โ Auditor โ โ Reporters โ
โ - DataFrame โโโโโถโ - Engine โโโโโถโ - Console โ
โ - EventLog โ โ - Models โ โ - (Extensible) โ
โโโโโโโโโโโโโโโโโ โโโโโโโโฌโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โ Rules โ โ Suggestions โ โ FinOps โ
โ - Physical โ โ - Templates โ โ - Cost Calc โ
โ - Query โ โ - Remediationโ โ - Waste Est. โ
โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โ โ โ
โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโโโโโ
โ Context โ
โ - Env Provider โ
โ - Policies โ
โโโโโโโโโโโโโโโโโโ
Core Modules
1. Auditor (src/auditor/)
engine.py- Main orchestration engine coordinating all componentsmodels.py- Data models (Alert, ClusterContext, AuditReport, Suggestion)
2. Rules (src/rules/)
physical_rules.py- Infrastructure-level detections (files, partitioning, indexing)query_rules.py- Query-level detections (joins, UDFs, type casting)
3. Readers (src/readers/)
dataframe_reader.py- Extracts plans and metrics from DataFramesevent_log_reader.py- Parses Spark event logs for runtime metrics
4. Suggestions (src/suggestions/)
remediation_engine.py- Generates context-aware recommendationssuggestions_templates.py- Predefined remediation code templates
5. FinOps (src/finops/)
cost_translator.py- Converts performance issues to financial estimates
6. Context (src/context/)
environment_provider.py- Detects cluster type (Serverless, AQE, Photon)
7. Policies (src/policies/)
policy_manager.py- Manages detection thresholds and FinOps parameters
8. Reporters (src/reporters/)
console_reporter.py- Formats and displays audit results
๐ฆ Installation
Prerequisites
- Python 3.11 (strictly enforced for environment parity)
- PySpark 4.0.3+
- Databricks Runtime 13.x+ (for cloud deployments)
Method 1: Local Development (Editable Install)
# Clone the repository
git clone https://github.com/your-org/databricks-engine-optimization.git
cd databricks-engine-optimization
# Create virtual environment with Python 3.11
python3.11 -m venv venv
source venv/bin/activate
# Install in editable mode with all dependencies
pip install -e .[dev,test]
Method 2: Via Wheel Distribution
# Build the wheel package
make package
# Install the wheel
pip install dist/apm_spark_auditor-1.0.0-py3-none-any.whl
Method 3: Docker Environment
# Build the Docker image
make docker-build
# Run the container
make docker-up
Method 4: Databricks Deployment
# 1. Build the wheel package
make package
# 2. Upload to Databricks workspace
databricks fs cp dist/apm_spark_auditor-1.0.0-py3-none-any.whl dbfs:/FileStore/libs/
# 3. Install in notebook
%pip install /dbfs/FileStore/libs/apm_spark_auditor-1.0.0-py3-none-any.whl
๐ Quick Start
Basic Usage - Analyze a DataFrame
from pyspark.sql import SparkSession
from apm_spark_auditor.run.main_trigger import APMAutomatedOrchestrator
# Initialize Spark session
spark = SparkSession.builder \
.appName("APM-Audit-Demo") \
.getOrCreate()
# Load your data
df = spark.read.table("my_catalog.my_schema.my_table")
# Run the audit
orchestrator = APMAutomatedOrchestrator(spark)
result = orchestrator.run_smart_scan(df=df, custom_context="my_etl_pipeline")
print(f"Scan completed: {result}")
Command-Line Interface
# Install the package to enable CLI command
pip install -e .
# Run audit on a specific table
apm-audit --table "catalog.schema.table_name"
# Run with custom context
apm-audit --table "catalog.schema.table_name" --context "production_etl"
๐ก Usage Examples
Example 1: Detecting Small Files Problem
from pyspark.sql import SparkSession
from apm_spark_auditor.run.main_trigger import APMAutomatedOrchestrator
spark = SparkSession.builder.master("local[*]").appName("Small-Files-Demo").getOrCreate()
# Create a DataFrame with fragmented writes (anti-pattern)
df = spark.range(1000).repartition(500) # 500 tiny partitions!
df.write.mode("overwrite").format("delta").save("/tmp/fragmented_table")
# Audit the result
df_read = spark.read.format("delta").load("/tmp/fragmented_table")
orchestrator = APMAutomatedOrchestrator(spark)
orchestrator.run_smart_scan(df=df_read, custom_context="fragmented_demo")
Expected Output:
[1] Alert ID: PERF-001 (WARNING)
Title: Small files problem detected
Description: Table contains 500 files, exceeding recommended threshold of 100...
๐ก Recommendation: Run data compaction operation (OPTIMIZE) on Delta Lake table
๐ป Fix Template:
spark.sql("OPTIMIZE {table_name}")
Example 2: Multi-Anomaly Detection (Demo Script)
The included demo.py demonstrates multiple anti-patterns:
python demo.py
This script intentionally creates:
- String-typed numeric metrics (PERF-003)
- Non-vectorized Python UDF (PERF-010)
- Explode abuse (PERF-008)
- Redundant scans without caching (PERF-009)
- Cartesian product (PERF-005)
Example 3: FinOps Cost Simulation
orchestrator = APMAutomatedOrchestrator(spark)
# Enable cost simulation for local testing
result = orchestrator.run_smart_scan(
df=my_dataframe,
custom_context="production_pipeline",
simulate_cloud_costs=True # Estimates monthly waste
)
Example 4: Batch Audit Multiple Tables
tables = [
"catalog.bronze.bess_telemetry",
"catalog.bronze.pv_metrics",
"catalog.silver.enriched_data"
]
orchestrator = APMAutomatedOrchestrator(spark)
for table_name in tables:
print(f"\n{'='*60}")
print(f"Auditing: {table_name}")
print('='*60)
orchestrator.run_smart_scan(target_table=table_name)
โ๏ธ Configuration
Policy Configuration
Customize detection thresholds via PolicyManager:
from apm_spark_auditor.policies.policy_manager import PolicyManager
custom_policies = {
"small_files": {
"max_file_count": 200, # Alert when exceeding 200 files
"threshold_size_mb": 5.0 # Minimum file size threshold
},
"data_skew": {
"max_duration_ratio": 10.0 # Max acceptable task duration variance
},
"over_partitioning": {
"max_partitions": 500 # Maximum safe partition count
},
"finops": {
"dbu_cost_per_hour": 0.55, # DBU pricing (USD)
"estimated_core_count": 16 # Cluster core count
}
}
policy_manager = PolicyManager(custom_policies)
Environment Detection
The system automatically detects runtime context:
- Databricks Serverless: Spark Connect architecture detection
- Databricks Classic: Cluster ID and configuration inspection
- Vanilla Spark: Local or standalone cluster mode
Override detection if needed:
from apm_spark_auditor.context.environment_provider import EnvironmentProvider
env_provider = EnvironmentProvider(spark)
cluster_ctx = env_provider.determine_cluster_context()
print(f"Is Serverless: {cluster_ctx.is_serverless}")
print(f"AQE Enabled: {cluster_ctx.aqe_enabled}")
print(f"Photon Enabled: {cluster_ctx.photon_enabled}")
๐งช Testing
The project includes comprehensive test coverage with environment-aware routing.
Run All Tests (Local Environment)
# Using make
make test
# Using pytest directly
pytest tests/ --env=local
Run Databricks-Specific Tests
pytest tests/ --env=databricks
Test Categories
Tests are organized by markers:
@pytest.mark.unit- Fast, isolated unit tests with mocks@pytest.mark.integration- Component integration tests@pytest.mark.system- End-to-end scenario tests@pytest.mark.local_spark- Local Spark environment only@pytest.mark.databricks- Databricks runtime required
Run Specific Test Category
# Unit tests only
pytest tests/ -m unit
# Integration tests
pytest tests/ -m integration
# Databricks tests (requires Databricks environment)
pytest tests/ -m databricks --env=databricks
Test Structure
tests/
โโโ conftest.py # Shared fixtures and environment routing
โโโ unit/ # Fast unit tests with mocks
โ โโโ test_engine_local.py
โ โโโ test_engine_databricks.py
โ โโโ test_rules_local.py
โ โโโ test_rules_databricks.py
โโโ integration/ # Component integration tests
โ โโโ test_engine_integration_local.py
โโโ system/ # End-to-end tests
โโโ test_e2e_local.py
โโโ test_e2e_databricks.py
Coverage Report
pytest tests/ --cov=src --cov-report=html
open htmlcov/index.html
๐ Project Structure
databricks-engine-optimization/
โโโ src/ # Main source code
โ โโโ adapters/ # Execution plan readers
โ โ โโโ base.py # Abstract interfaces
โ โ โโโ vanilla_spark.py # Traditional Spark adapter
โ โโโ auditor/ # Core auditing engine
โ โ โโโ engine.py # Main orchestration engine
โ โ โโโ models.py # Data models (Alert, Report, etc.)
โ โโโ context/ # Environment detection
โ โ โโโ environment_provider.py # Cluster context analyzer
โ โโโ decorators/ # Utility decorators
โ โ โโโ __init__.py # Tracing and error handling
โ โโโ finops/ # Cost calculation
โ โ โโโ cost_translator.py # Financial impact estimator
โ โโโ policies/ # Configuration management
โ โ โโโ policy_manager.py # Threshold and policy manager
โ โโโ readers/ # Metrics extraction
โ โ โโโ dataframe_reader.py # DataFrame plan/metrics reader
โ โ โโโ event_log_reader.py # Event log parser
โ โโโ reporters/ # Output formatting
โ โ โโโ console_reporter.py # Console output formatter
โ โโโ rules/ # Detection rules
โ โ โโโ physical_rules.py # Infrastructure-level rules
โ โ โโโ query_rules.py # Query-level rules
โ โโโ suggestions/ # Remediation engine
โ โ โโโ remediation_engine.py # Suggestion generator
โ โ โโโ suggestions_templates.py # Code templates
โ โโโ run/ # Entry points
โ โโโ main_trigger.py # Main orchestrator & CLI
โโโ tests/ # Test suite
โ โโโ conftest.py # Pytest configuration & fixtures
โ โโโ unit/ # Unit tests
โ โโโ integration/ # Integration tests
โ โโโ system/ # End-to-end tests
โโโ generators/ # Test data generators
โ โโโ data/
โ โ โโโ mock_raw_generator.py # Mock telemetry data
โ โโโ etl/
โ โโโ bronze_pipelines.py # ETL anti-pattern generators
โโโ notebooks/ # Databricks notebooks
โ โโโ 01_laboratory_setup.ipynb # Environment setup
โ โโโ 02_performance_auditor.ipynb # Audit demonstrations
โ โโโ trigger.ipynb # Quick run notebook
โโโ docker/ # Docker configuration
โ โโโ app/
โ โโโ dockerfile # Container definition
โโโ demo.py # Standalone demo script
โโโ docker-compose.yaml # Docker orchestration
โโโ Makefile # Development automation
โโโ pyproject.toml # Project metadata & dependencies
โโโ requirements.txt # Dependency lock file
โโโ README.md # This file
โโโ .gitignore # Git exclusions
๐ง Development
Make Commands
The project includes a Makefile for common tasks:
make help # Display all available commands
make venv # Create Python 3.11 virtual environment
make test # Run unit tests with coverage
make package # Build .whl distribution artifact
make docker-build # Build Docker image
make docker-up # Start Docker container
make docker-down # Stop Docker container
make clean # Remove build artifacts
make clean-all # Remove build artifacts and venv
Code Quality
The project uses:
- Black for code formatting (line length: 100)
- Ruff for linting (Python 3.11 target)
- Pytest for testing
# Format code
black src/ tests/ --line-length 100
# Lint code
ruff check src/ tests/
# Run tests with coverage
pytest tests/ --cov=src --cov-report=term-missing
Adding New Rules
To add a new detection rule:
- Create rule class in
src/rules/physical_rules.pyorsrc/rules/query_rules.py:
class MyNewRule(IAnalysisRule):
def evaluate(self, plan_text: str, metrics: Dict[str, Any],
policies: Dict[str, Any] = None) -> Optional[Alert]:
# Detection logic here
if condition_detected:
return Alert(
rule_id="PERF-011",
title="My New Issue",
description="Detailed description...",
fix="How to fix this...",
severity="WARNING"
)
return None
- Add suggestion template in
src/suggestions/suggestions_templates.py:
TEMPLATES["PERF-011"] = {
"text": "Do this to fix the issue...",
"code": """# Example code
df.optimized_operation()"""
}
- Register rule in
src/run/main_trigger.py:
self.active_rules = [
# ... existing rules ...
MyNewRule() # Add your new rule
]
๐ Output Example
============================================================
๐ [APM CORE REPORT] Context: enterprise_bess_heavy_telemetry_pipeline
Timestamp: 2026-06-29T09:20:15.123456
Estimated FinOps waste: $124.85 / month
============================================================
[1] Alert ID: PERF-003 (WARNING)
Title: Improper data typing (Type Casting & Metric Degradation)
Description: Critical typing anomalies detected: metric 'temperature' stored as STRING...
๐ก Recommendation: Remove explicit type casting in filter conditions
๐ป Fix Template:
# Instead of:
df.filter(F.col("temperature").cast("string") == "25")
# Use correct data type:
df.filter(F.col("temperature") == 25)
[2] Alert ID: PERF-010 (HIGH)
Title: Unverified UDF function usage (Row-by-Row Execution)
Description: Standard Python UDF function detected. This disables processor vectorization...
๐ก Recommendation: Replace custom Python code with built-in functions
๐ป Fix Template:
# Replace Python UDF with built-in functions from pyspark.sql.functions
[3] Alert ID: PERF-008 (WARNING)
Title: Inefficient structure explosion (Explode Abuse)
Description: Use of explode() function forces physical row duplication...
๐ก Recommendation: Replace explode() with vectorized higher-order functions
๐ป Fix Template:
# Replace explode() with transform(), filter(), or aggregate()
[4] Alert ID: PERF-009 (WARNING)
Title: Redundant Source Scanning (Redundant Table Scan)
Description: Detected that same Delta Lake data source is read 3 times...
๐ก Recommendation: Apply caching before logic branching
๐ป Fix Template:
df.cache() or df.persist()
[5] Alert ID: PERF-005 (CRITICAL)
Title: Cartesian product detected
Description: Catalyst engine was forced to perform join without condition...
๐ก Recommendation: Check join conditions or use broadcast() for intentional CROSS JOIN
๐ป Fix Template:
# Ensure proper join condition or use broadcast for small table
============================================================
๐ Use Cases
1. Development-Time Quality Gates
Integrate into CI/CD pipelines to catch performance issues before production deployment.
2. Production Monitoring
Run periodic audits on production tables to identify optimization opportunities.
3. Cost Optimization
Identify high-cost anti-patterns and estimate savings from remediation.
4. Training & Education
Use the detailed explanations and code templates to educate teams on Spark best practices.
5. Migration Assessment
Audit legacy Spark jobs before migrating to Databricks or upgrading Spark versions.
๐ค Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Follow code style (Black formatting, type hints)
- Add tests for new functionality
- Ensure all tests pass (
make test) - Commit with clear messages (
git commit -m 'Add amazing feature') - Push to your branch (
git push origin feature/amazing-feature) - Open a Pull Request
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ค Author
Kacper Grodecki
- Email: kacpra.grodeckiego@gmail.com
๐ Acknowledgments
- Apache Spark community for the powerful distributed computing framework
- Databricks for innovation in lakehouse architecture and Photon engine
- All contributors to the PySpark ecosystem
๐ Additional Resources
- Apache Spark Performance Tuning Guide
- Databricks Best Practices
- Delta Lake Optimization
- Catalyst Optimizer Deep Dive
๐ Known Issues & Limitations
- Event Log Reader: Requires Spark history server or event log directory access
- Databricks Connect: Some JVM-level metrics may be unavailable in Serverless mode
- Cost Estimation: FinOps calculations are estimates based on configurable DBU pricing
- EXPLAIN Plan Parsing: Custom Catalyst optimizations may not be fully recognized
๐บ๏ธ Roadmap
- Integration with Databricks Jobs API for automated scanning
- REST API for remote auditing
- Support for Spark Structured Streaming query analysis
- Grafana/Prometheus metrics export
- Machine learning-based anomaly detection
- Integration with Git hooks for pre-commit checks
- Web UI dashboard for historical audit tracking
Made with โค๏ธ for the Spark performance community
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file apm_spark_auditor-1.0.0.tar.gz.
File metadata
- Download URL: apm_spark_auditor-1.0.0.tar.gz
- Upload date:
- Size: 33.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5a6e64f83eb384d007d212d9b1c75f75f2c888625c8ca8adfc4658fc312d04e
|
|
| MD5 |
d0ca36981fa5297866579a52284bbdab
|
|
| BLAKE2b-256 |
26ea9838165452e95b0fb8239a03b9c09a285414f379b51d2148ac197b28a381
|
File details
Details for the file apm_spark_auditor-1.0.0-py3-none-any.whl.
File metadata
- Download URL: apm_spark_auditor-1.0.0-py3-none-any.whl
- Upload date:
- Size: 32.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7fb319e63a39946cdf2d4d223a8acbf730ebe39961123595be33bc5600917aa
|
|
| MD5 |
76b292a5a38eed1936ff3f423fdfc42b
|
|
| BLAKE2b-256 |
182a75395e6e6e834bb1b92503b0c49c71c212f636f42165373ca65a8aa5550d
|