Generate Prometheus scrape configs for multiple systems - IBM/ibm-spectrum-scale-bridge-for-grafana GitHub Wiki

When monitoring multiple IBM Storage Scale clusters (e.g., storage cluster + client/compute clusters, or multi-site deployments), or when integrating IBM Storage Scale metrics into an existing enterprise Prometheus server, you should not overwrite the central prometheus.yml configuration file.

Instead, use the Grafana Bridge GET /scrape_configs.yml endpoint combined with the Prometheus scrape_config_files feature (available in Prometheus 2.43 and later).


Why Use /scrape_configs.yml Instead of /prometheus.yml?

Feature GET /prometheus.yml GET /scrape_configs.yml
Intended Use Single cluster with dedicated Prometheus instance Multiple clusters or existing Prometheus infrastructure
Output Content Complete standalone prometheus.yml (global, storage, alerting, rule_files, scrape_configs) Modular YAML containing only scrape_configs
Job Name Clashes Can collide if multiple bridges use default job names Solved using ?job_suffix=<suffix> per cluster
Prometheus Integration Replaces the whole configuration file Placed into /etc/prometheus/scrape_configs/*.yml and loaded via scrape_config_files

The /scrape_configs.yml Endpoint

The /scrape_configs.yml endpoint generates a YAML snippet containing only the scrape_configs list corresponding to active Storage Scale sensors and optional bridge telemetry.

Query Parameters

Parameter Type / Pattern Default Description
job_suffix String (^[A-Za-z0-9_.:-]{1,64}$) (empty) Appends a unique suffix to every generated job name (e.g., GPFSFilesystem_clusterA, GPFSNSDDisk_clusterA). Essential when monitoring multiple clusters to avoid job name collisions.
internal_metrics Boolean (true | false) false When true, adds scrape jobs for the bridge's internal telemetry: GrafanaBridgeHttpMetrics<suffix> (/http_metrics) and GrafanaBridgeInternalStats<suffix> (/internal_stats), scraped every 60 s.
target Host or Host:Port (auto-detected) Overrides the scrape target address in static_configs. Required when running the bridge inside a container (Podman/Docker) to replace the internal container IP with the reachable host IP/FQDN.
path Absolute filesystem path (empty) Instructs the bridge to write the generated YAML directly to a file or directory on the bridge host.

Step-by-Step Multi-System Configuration

Step 1: Configure Central prometheus.yml

On your Prometheus server, edit /etc/prometheus/prometheus.yml to include scrape_config_files and out_of_order_time_window:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

storage:
  tsdb:
    out_of_order_time_window: 2d   # Required for historical/internal metrics

scrape_configs:
  # Central Prometheus self-monitoring
  - job_name: prometheus
    static_configs:
      - targets:
          - localhost:9090

# Include modular scrape configuration files for all Storage Scale clusters
scrape_config_files:
  - /etc/prometheus/scrape_configs/*.yml

Create the directory for external scrape configurations:

mkdir -p /etc/prometheus/scrape_configs

Step 2: Fetch Scrape Configurations from Each Cluster

For each IBM Storage Scale cluster, fetch its scrape configuration using curl with a unique job_suffix.

Example: Monitoring Two Clusters (Cluster A and Cluster B)

# 1. Fetch scrape jobs for Cluster A (Storage Cluster)
curl -sf "http://10.0.100.11:9250/scrape_configs.yml?job_suffix=_clusterA&internal_metrics=true" \
     -u scale_admin:PasswordA! \
     -o /etc/prometheus/scrape_configs/scale_clusterA.yml.tmp \
  && mv /etc/prometheus/scrape_configs/scale_clusterA.yml.tmp \
        /etc/prometheus/scrape_configs/scale_clusterA.yml

# 2. Fetch scrape jobs for Cluster B (Client Cluster)
curl -sf "http://10.0.200.22:9250/scrape_configs.yml?job_suffix=_clusterB&internal_metrics=true" \
     -u scale_admin:PasswordB! \
     -o /etc/prometheus/scrape_configs/scale_clusterB.yml.tmp \
  && mv /etc/prometheus/scrape_configs/scale_clusterB.yml.tmp \
        /etc/prometheus/scrape_configs/scale_clusterB.yml

Containerized Bridges (Podman / Docker): If a bridge runs inside a container with published ports, add &target=<container-host-ip> to the curl request so Prometheus scrapes the reachable container host IP rather than the internal container virtual IP:

curl -sf "http://10.0.100.11:9250/scrape_configs.yml?target=10.0.100.11&job_suffix=_clusterA&internal_metrics=true" \
     -u scale_admin:PasswordA! \
     -o /etc/prometheus/scrape_configs/scale_clusterA.yml.tmp \
  && mv /etc/prometheus/scrape_configs/scale_clusterA.yml.tmp \
        /etc/prometheus/scrape_configs/scale_clusterA.yml

Tip – Atomic File Replacement: Notice the use of .tmp and mv. The atomic mv operation prevents Prometheus from reading a partially downloaded or incomplete configuration file during a scrape reload.


Step 3: Validate and Reload Prometheus

Validate the combined configuration with promtool and reload Prometheus without restarting:

promtool check config /etc/prometheus/prometheus.yml \
  && curl -sf -XPOST http://localhost:9090/-/reload

Example Generated Scrape File (scale_clusterA.yml)

Below is an example of what /etc/prometheus/scrape_configs/scale_clusterA.yml contains:

# Generated by IBM Storage Scale bridge for Grafana.
# Do not edit, changes will be lost on the next update.
# Reference this file in prometheus.yml under scrape_config_files.
scrape_configs:
- basic_auth:
    password: PasswordA!
    username: scale_admin
  honor_timestamps: true
  job_name: GPFSFilesystem_clusterA
  metrics_path: /metrics_gpfs_filesystem
  scheme: http
  scrape_interval: 10s
  static_configs:
  - targets:
    - 10.0.100.11:9250

- basic_auth:
    password: PasswordA!
    username: scale_admin
  honor_timestamps: true
  job_name: GPFSNSDDisk_clusterA
  metrics_path: /metrics_gpfs_nsddisk
  scheme: http
  scrape_interval: 10s
  static_configs:
  - targets:
    - 10.0.100.11:9250

- basic_auth:
    password: PasswordA!
    username: scale_admin
  honor_timestamps: true
  job_name: GPFSNode_clusterA
  metrics_path: /metrics_gpfs_node
  scheme: http
  scrape_interval: 10s
  static_configs:
  - targets:
    - 10.0.100.11:9250

- basic_auth:
    password: PasswordA!
    username: scale_admin
  honor_timestamps: true
  job_name: GrafanaBridgeHttpMetrics_clusterA
  metrics_path: /http_metrics
  scheme: http
  scrape_interval: 60s
  static_configs:
  - targets:
    - 10.0.100.11:9250

- basic_auth:
    password: PasswordA!
    username: scale_admin
  honor_timestamps: true
  job_name: GrafanaBridgeInternalStats_clusterA
  metrics_path: /internal_stats
  scheme: http
  scrape_interval: 60s
  static_configs:
  - targets:
    - 10.0.100.11:9250

Automating Updates (Cron / Systemd Timer)

When cluster sensors change (e.g. new sensors activated or sensor periods altered), the scrape configurations can be refreshed automatically via a cron job or systemd timer.

Example Cron Job (/etc/cron.d/update_scale_scrape_configs):

# Refresh scrape configurations daily at 02:00
0 2 * * * root /usr/local/bin/refresh_scale_scrape_configs.sh >/var/log/refresh_scale_scrape.log 2>&1

Script (/usr/local/bin/refresh_scale_scrape_configs.sh):

#!/bin/bash
set -e

CONFIG_DIR="/etc/prometheus/scrape_configs"
mkdir -p "$CONFIG_DIR"

# Cluster A
curl -sf "http://10.0.100.11:9250/scrape_configs.yml?job_suffix=_clusterA&internal_metrics=true" \
     -u scale_admin:PasswordA! \
     -o "$CONFIG_DIR/scale_clusterA.yml.tmp"
mv "$CONFIG_DIR/scale_clusterA.yml.tmp" "$CONFIG_DIR/scale_clusterA.yml"

# Cluster B
curl -sf "http://10.0.200.22:9250/scrape_configs.yml?job_suffix=_clusterB&internal_metrics=true" \
     -u scale_admin:PasswordB! \
     -o "$CONFIG_DIR/scale_clusterB.yml.tmp"
mv "$CONFIG_DIR/scale_clusterB.yml.tmp" "$CONFIG_DIR/scale_clusterB.yml"

# Validate and reload
promtool check config /etc/prometheus/prometheus.yml
curl -sf -XPOST http://localhost:9090/-/reload
echo "Scrape configurations updated successfully at $(date)"

Related Documentation

⚠️ **GitHub.com Fallback** ⚠️