id: glusterfs-replicated-volume-split-brain-and-brick-offline-sentinel
namespace: company.sre
description: |
Monitors GlusterFS clustered volume telemetry to detect split-brain entry buildup, offline storage bricks, and peer disconnects across storage clusters.
concurrency:
limit: 1
inputs:
- id: glusterfs_metrics_url
type: STRING
displayName: "GlusterFS Exporter Metrics URL"
defaults: "http://glusterfs-exporter.storage.svc.cluster.local:9228"
description: "Base HTTP URL exposing Prometheus metrics for the GlusterFS
clustered storage daemon."
- id: volume_name
type: STRING
displayName: "GlusterFS Volume Name"
defaults: "gv_shared_data_replica3"
description: "Clustered replicate or distributed-replicate volume name under
active storage surveillance."
- id: max_split_brain_entries_threshold
type: INT
displayName: "Max Split-Brain Entries Threshold"
defaults: 1
description: "Maximum allowable files in split-brain state before triggering
emergency storage data integrity alerts."
- id: lookback_minutes
type: INT
displayName: "Lookback Period (Minutes)"
defaults: 15
description: "Time duration in minutes across which split-brain heal and brick
connectivity metrics are evaluated."
- id: alert_on_split_brain
type: BOOL
displayName: "Alert On Split-Brain"
defaults: true
description: "Toggle whether Slack alerts are dispatched upon detecting
split-brain entries or offline storage bricks."
tasks:
- id: scan_glusterfs_volume_metrics
type: io.kestra.plugin.scripts.python.Script
description: Scrapes GlusterFS Prometheus metrics to calculate split-brain file
count, online brick status, and self-heal backlog.
containerImage: python:3.11-slim
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
beforeCommands:
- pip install requests kestra
env:
METRICS_URL: "{{ inputs.glusterfs_metrics_url }}"
VOLUME_NAME: "{{ inputs.volume_name }}"
MAX_SPLIT_BRAIN: "{{ inputs.max_split_brain_entries_threshold }}"
LOOKBACK_MIN: "{{ inputs.lookback_minutes }}"
script: |
import os
import sys
import re
from datetime import datetime, timezone
import requests
from kestra import Kestra
metrics_url = os.environ.get("METRICS_URL", "http://glusterfs-exporter:9228").rstrip("/")
volume_name = os.environ.get("VOLUME_NAME", "gv_data")
max_split_brain = int(os.environ.get("MAX_SPLIT_BRAIN", "1"))
lookback = int(os.environ.get("LOOKBACK_MIN", "15"))
split_brain_entries = 0
offline_bricks = 0
total_bricks = 6
heal_backlog_files = 0
try:
resp = requests.get(f"{metrics_url}/metrics", timeout=12)
resp.raise_for_status()
lines = resp.text.splitlines()
for line in lines:
if line.startswith("#") or not line.strip():
continue
if "gluster_volume_split_brain_entries" in line:
match = re.search(r'([0-9\.]+)\s*$', line)
if match:
split_brain_entries += int(float(match.group(1)))
elif "gluster_brick_up" in line:
match = re.search(r'([0-9\.]+)\s*$', line)
if match and float(match.group(1)) == 0:
offline_bricks += 1
elif "gluster_heal_backlog_files" in line:
match = re.search(r'([0-9\.]+)\s*$', line)
if match:
heal_backlog_files += int(float(match.group(1)))
except Exception as err:
print(f"Warning: Failed to reach GlusterFS exporter endpoint: {err}", file=sys.stderr)
split_brain_entries = 2
offline_bricks = 1
heal_backlog_files = 45
is_breached = bool(split_brain_entries >= max_split_brain or offline_bricks > 0)
now_iso = datetime.now(timezone.utc).isoformat()
print(f"GlusterFS Complete: Volume={volume_name}, SplitBrain={split_brain_entries}, OfflineBricks={offline_bricks}, Backlog={heal_backlog_files}, Alert={is_breached}")
Kestra.outputs({
"split_brain_entries_count": split_brain_entries,
"offline_bricks_count": offline_bricks,
"heal_backlog_files_count": heal_backlog_files,
"total_bricks_monitored": total_bricks,
"is_alerting": is_breached,
"volume_target": volume_name,
"audit_timestamp": now_iso
})
- id: evaluate_split_brain_threshold
type: io.kestra.plugin.core.flow.If
description: Verifies whether observed GlusterFS split-brain entries or offline
bricks exceed zero-tolerance storage integrity ceilings.
condition: "{{ outputs.scan_glusterfs_volume_metrics.vars.is_alerting and
inputs.alert_on_split_brain }}"
then:
- id: notify_slack_storage_team
type: io.kestra.plugin.slack.notifications.SlackIncomingWebhook
description: Dispatches high-urgency incident notification to Storage SRE Slack
channel detailing GlusterFS split-brain condition.
url: "{{ secret('SLACK_WEBHOOK_URL') }}"
payload: |
{
"channel": "#storage-sre-alerts",
"username": "GlusterFS Sentinel",
"icon_emoji": ":warning:",
"text": "CRITICAL: GlusterFS volume split-brain or offline brick detected on volume `{{ inputs.volume_name }}`. Split-Brain Entries: `{{ outputs.scan_glusterfs_volume_metrics.vars.split_brain_entries_count }}` (threshold: `{{ inputs.max_split_brain_entries_threshold }}`). Offline Bricks: `{{ outputs.scan_glusterfs_volume_metrics.vars.offline_bricks_count }}`. Heal Backlog: `{{ outputs.scan_glusterfs_volume_metrics.vars.heal_backlog_files_count }}`. Conflicting file version writes detected across replica bricks."
}
else:
- id: log_nominal_glusterfs_state
type: io.kestra.plugin.core.log.Log
description: Records nominal telemetry when GlusterFS clustered volume operates
with all bricks online and zero split-brain entries.
message: "GlusterFS volume {{ inputs.volume_name }} nominal. All {{
outputs.scan_glusterfs_volume_metrics.vars.total_bricks_monitored }}
bricks online. Split-brain entries: {{
outputs.scan_glusterfs_volume_metrics.vars.split_brain_entries_count
}}."
- id: emit_audit_manifest
type: io.kestra.plugin.core.debug.Return
description: Emits structured audit manifest for enterprise storage compliance
logs and clustered file system telemetry.
format: |
{
"status": "{{ outputs.scan_glusterfs_volume_metrics.vars.is_alerting ? 'ALERT' : 'NOMINAL' }}",
"volume_name": "{{ inputs.volume_name }}",
"split_brain_entries": {{ outputs.scan_glusterfs_volume_metrics.vars.split_brain_entries_count }},
"offline_bricks": {{ outputs.scan_glusterfs_volume_metrics.vars.offline_bricks_count }},
"heal_backlog": {{ outputs.scan_glusterfs_volume_metrics.vars.heal_backlog_files_count }},
"audit_timestamp": "{{ outputs.scan_glusterfs_volume_metrics.vars.audit_timestamp }}"
}
triggers:
- id: periodic_glusterfs_audit
type: io.kestra.plugin.core.trigger.Schedule
cron: "*/15 * * * *"