Skip to main content

A secure flexible Prometheus exporter for commands, databases, functions.

Project description

FlexMetric

PyPI version License: MIT

FlexMetric is a lightweight, pluggable, and extensible Prometheus exporter that helps you collect, expose, and visualize custom metrics with minimal setup and maximum flexibility.

Features

  • Command Execution: Run system commands and expose their output as Prometheus metrics
  • Database Monitoring: Execute SQL queries against SQLite, PostgreSQL, and ClickHouse databases
  • Python Functions: Call custom Python functions and export their results as metrics
  • REST API: Receive externally submitted metrics via a secure Flask-based API with optional HTTPS (TLS)
  • Security First: Built-in command and query sanitization to prevent dangerous operations
  • Prometheus Ready: All metrics are exposed in Prometheus-compatible format for Grafana visualization

Safety Features

  • Command Safety: Harmful commands (file deletion, system shutdown) are automatically blocked
  • Query Protection: Potentially dangerous SQL queries (DROP, DELETE, TRUNCATE) are blocked by default
  • Input Validation: Comprehensive sanitization and validation ensure only safe operations are executed

Installation

Install FlexMetric from PyPI:

pip install flexmetric

Quick Start

Run FlexMetric with command execution mode:

flexmetric --commands --commands-config commands.yaml --port 8000

Access your metrics at: http://localhost:8000/metrics

Available Modes

FlexMetric supports multiple modes that can be used individually or combined:

Mode Description Configuration Files
--commands Execute system commands and export outputs as metrics commands.yaml
--database Execute SQL queries on databases and export results database.yaml, queries.yaml
--functions Discover and run user-defined Python functions executable_functions.txt
--expose-api Expose Flask API to receive external metrics None required

Using Multiple Modes Together

flexmetric \
  --commands --commands-config commands.yaml \
  --database --database-config database.yaml --queries-config queries.yaml \
  --functions --functions-file executable_functions.txt \
  --expose-api --port 8000

Configuration Examples

Commands Mode

Create a commands.yaml file to define system commands to execute:

commands:
  - name: disk_usage
    command: df -h
    main_label: disk_usage_filesystem_mount_point
    labels: ["filesystem", "mounted"]
    label_columns: [0, -1]
    value_column: 4
    timeout_seconds: 60

Example command output:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   20G   28G  42% /
/dev/sdb1       100G   10G   85G  10% /data

Configuration Fields

Field Description
name A nickname for this command (e.g., "disk_usage")
command The actual shell command to run (e.g., "df -h")
main_label The metric name that will appear in Prometheus
labels List of label names for different dimensions
label_columns Column indexes to extract label values (e.g., [0, -1])
value_column Column index to extract the numeric value
timeout_seconds Maximum time to wait for command completion

Database Mode

FlexMetric supports multiple databases with simple YAML configuration:

Supported Databases

Database Type Description
SQLite sqlite Lightweight, file-based database
PostgreSQL postgres Production-grade relational database
ClickHouse clickhouse High-performance analytical database

Database Configuration (database.yaml)

databases:
  - id: "local_sqlite"
    type: "sqlite"
    db_connection: "/path/to/example.db"

  - id: "analytics_pg"
    type: "postgres"
    host: "localhost"
    port: 5432
    database: "metricsdb"
    username: "postgres"
    password: "postgres_password"
    sslmode: "disable"

  - id: "clickhouse_cluster"
    type: "clickhouse"
    host: "localhost"
    port: 8443
    username: "default"
    password: "clickhouse_password"
    secure: true

Query Configuration (queries.yaml)

commands:
  - id: "active_user_count_pg"
    type: "postgres"
    database_id: "analytics_pg"
    query: |
      SELECT
        country AS country_name,
        COUNT(*) AS active_user_count
      FROM users
      WHERE is_active = true
      GROUP BY country;
    main_label: "active_user_count"
    labels: ["country_name"]
    value_column: "active_user_count"

Functions Mode

Create an executable_functions.txt file listing your Python functions:

function_name_1
function_name_2

Python Function Output Format

Each function should return a dictionary:

{
    'result': [
        { 'label': [label_value1, label_value2, ...], 'value': numeric_value }
    ],
    'labels': [label_name1, label_name2, ...],
    'main_label': 'your_main_metric_name'
}

Flask API Mode

Start FlexMetric with the Flask API:

flexmetric --expose-api --port 5000 --host 0.0.0.0

Endpoints:

  • Metrics: http://localhost:5000/metrics
  • API: http://localhost:5000/update_metric

Submit Metrics via API

curl -X POST http://localhost:5000/update_metric \
-H "Content-Type: application/json" \
-d '{
  "result": [
    { 
      "label": ["cpu", "core_1"], 
      "value": 42.5 
    }
  ],
  "labels": ["metric_type", "core"],
  "main_label": "cpu_usage_metric"
}'

Secure HTTPS Mode

flexmetric --expose-api --enable-https --ssl-cert=cert.pem --ssl-key=key.pem

HTTPS Endpoints:

  • Metrics: https://localhost:5000/metrics
  • API: https://localhost:5000/update_metric

Submit Metrics via HTTPS API

curl -k -X POST https://localhost:5000/update_metric \
-H "Content-Type: application/json" \
-d '{
  "result": [
    { 
      "label": ["cpu", "core_1"], 
      "value": 42.5 
    }
  ],
  "labels": ["metric_type", "core"],
  "main_label": "cpu_usage_metric"
}'

Python HTTPS Client Example

import requests
import json
import urllib3

# Disable SSL warnings for self-signed certificates
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

url = "https://localhost:5000/update_metric"
headers = {
    "Content-Type": "application/json"
}
data = {
    "result": [
        {
            "label": ["cpu", "core_1"],
            "value": 42.5
        }
    ],
    "labels": ["metric_type", "core"],
    "main_label": "cpu_usage_metric"
}

# Use verify=False for self-signed certificates (not recommended for production)
response = requests.post(url, headers=headers, data=json.dumps(data), verify=False)

print(f"Status Code: {response.status_code}")
print("Response:", response.text)

SSL Certificate Generation

For development/testing, you can generate self-signed certificates:

# Generate private key
openssl genrsa -out key.pem 2048

# Generate certificate
openssl req -new -x509 -key key.pem -out cert.pem -days 365 -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"

Note: For production use, use certificates from a trusted Certificate Authority (CA).

Command-Line Options

Option Description Default
--port Prometheus metrics server port 8000
--commands Enable commands mode
--commands-config Path to commands YAML file commands.yaml
--database Enable database mode
--database-config Path to database YAML file database.yaml
--queries-config Path to queries YAML file queries.yaml
--functions Enable Python functions mode
--functions-file Path to functions file executable_functions.txt
--expose-api Enable Flask API mode
--flask-port Flask API port 5000
--flask-host Flask API hostname 0.0.0.0
--enable-https Enable HTTPS for Flask API
--ssl-cert SSL certificate file path
--ssl-key SSL private key file path

Example Output

FlexMetric exposes metrics in Prometheus format:

# HELP disk_usage_gauge Disk usage percentage
# TYPE disk_usage_gauge gauge
disk_usage_gauge{filesystem="/dev/sda1",mounted="/"} 42.0
disk_usage_gauge{filesystem="/dev/sdb1",mounted="/data"} 10.0

Future Enhancements

  • Support for additional databases (MySQL, MongoDB)
  • Enhanced label extraction and parsing
  • Web UI for configuration management
  • Advanced security features and authentication

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flexmetric-0.5.7.tar.gz (20.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flexmetric-0.5.7-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file flexmetric-0.5.7.tar.gz.

File metadata

  • Download URL: flexmetric-0.5.7.tar.gz
  • Upload date:
  • Size: 20.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.6

File hashes

Hashes for flexmetric-0.5.7.tar.gz
Algorithm Hash digest
SHA256 52847dc7f6bd697f0bf74232acfe571589e870b6871154f8702a5e58536248a8
MD5 241e0531473f85c3dedfbfa04d57a12b
BLAKE2b-256 8033b2669a1b8367b027ad09ac152beb5aa08c7244a265f11b5ec1806d20880d

See more details on using hashes here.

File details

Details for the file flexmetric-0.5.7-py3-none-any.whl.

File metadata

  • Download URL: flexmetric-0.5.7-py3-none-any.whl
  • Upload date:
  • Size: 20.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.6

File hashes

Hashes for flexmetric-0.5.7-py3-none-any.whl
Algorithm Hash digest
SHA256 3a9c33e115c33eb000ba53e191b43b158cf6d08a23c731192edeba1e9ebe3fcb
MD5 1b454cfbb971070a88342154c5aca3ff
BLAKE2b-256 209690c9756a5c714ef15351fb98ca951ebd921eb14623a874ab74d82403f3a2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page