mirror of
https://github.com/taylanbakircioglu/haproxy-openmanager.git
synced 2026-09-11 21:38:55 +00:00
203 lines
6.3 KiB
Python
Executable File
203 lines
6.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
"""
|
||
HAProxy Stats CSV Parser Test Script
|
||
Bu script HAProxy stats CSV'sini parse edip sonuçları gösterir.
|
||
"""
|
||
|
||
import sys
|
||
import base64
|
||
import csv
|
||
import io
|
||
from datetime import datetime
|
||
|
||
def parse_csv_stats(csv_data):
|
||
"""Parse HAProxy stats CSV"""
|
||
if not csv_data or not csv_data.strip():
|
||
print("❌ CSV data is empty!")
|
||
return None
|
||
|
||
# Parse CSV
|
||
reader = csv.DictReader(io.StringIO(csv_data))
|
||
|
||
frontends = {}
|
||
backends = {}
|
||
servers = []
|
||
|
||
for row in reader:
|
||
try:
|
||
# Skip comment lines
|
||
if not row or row.get('# pxname', '').startswith('#'):
|
||
continue
|
||
|
||
pxname = row.get('# pxname') or row.get('pxname', '')
|
||
svname = row.get('svname', '')
|
||
stat_type = int(row.get('type', -1)) if row.get('type', '').isdigit() else -1
|
||
|
||
# Frontend (type=0)
|
||
if stat_type == 0:
|
||
frontends[pxname] = {
|
||
'name': pxname,
|
||
'status': row.get('status', 'UNKNOWN'),
|
||
'requests_total': int(row.get('stot', 0) or 0),
|
||
'current_sessions': int(row.get('scur', 0) or 0),
|
||
'hrsp_2xx': int(row.get('hrsp_2xx', 0) or 0),
|
||
'hrsp_4xx': int(row.get('hrsp_4xx', 0) or 0),
|
||
'hrsp_5xx': int(row.get('hrsp_5xx', 0) or 0),
|
||
}
|
||
|
||
# Backend (type=1)
|
||
elif stat_type == 1:
|
||
backends[pxname] = {
|
||
'name': pxname,
|
||
'status': row.get('status', 'UNKNOWN'),
|
||
'requests_total': int(row.get('stot', 0) or 0),
|
||
'current_sessions': int(row.get('scur', 0) or 0),
|
||
'response_time_avg': int(row.get('rtime', 0) or 0),
|
||
}
|
||
|
||
# Server (type=2)
|
||
elif stat_type == 2:
|
||
if svname and svname not in ['BACKEND', 'FRONTEND']:
|
||
servers.append({
|
||
'backend': pxname,
|
||
'name': svname,
|
||
'status': row.get('status', 'UNKNOWN'),
|
||
})
|
||
|
||
except Exception as e:
|
||
print(f"⚠️ Failed to parse row: {e}")
|
||
continue
|
||
|
||
return {
|
||
'frontends': frontends,
|
||
'backends': backends,
|
||
'servers': servers,
|
||
'timestamp': datetime.utcnow().isoformat()
|
||
}
|
||
|
||
def main():
|
||
"""Main test function"""
|
||
print("=" * 80)
|
||
print("HAProxy Stats CSV Parser Test")
|
||
print("=" * 80)
|
||
print()
|
||
|
||
# Read CSV from stdin or file
|
||
if len(sys.argv) > 1:
|
||
# From file
|
||
csv_file = sys.argv[1]
|
||
print(f"📂 Reading from file: {csv_file}")
|
||
|
||
with open(csv_file, 'r') as f:
|
||
csv_data = f.read()
|
||
|
||
# Check if base64 encoded
|
||
if len(sys.argv) > 2 and sys.argv[2] == '--base64':
|
||
print("🔓 Decoding base64...")
|
||
csv_data = base64.b64decode(csv_data).decode('utf-8')
|
||
else:
|
||
# From stdin
|
||
print("📥 Reading from stdin (paste CSV and press Ctrl+D)...")
|
||
csv_data = sys.stdin.read()
|
||
|
||
print(f"📊 CSV Data Size: {len(csv_data)} bytes")
|
||
print()
|
||
|
||
# Show preview
|
||
lines = csv_data.split('\n')
|
||
print("📋 CSV Preview (first 5 lines):")
|
||
print("-" * 80)
|
||
for line in lines[:5]:
|
||
print(line[:100] + ('...' if len(line) > 100 else ''))
|
||
print("-" * 80)
|
||
print()
|
||
|
||
# Parse
|
||
print("🔍 Parsing CSV...")
|
||
result = parse_csv_stats(csv_data)
|
||
|
||
if not result:
|
||
print("❌ Parse failed!")
|
||
return 1
|
||
|
||
# Display results
|
||
print("✅ Parse successful!")
|
||
print()
|
||
print("=" * 80)
|
||
print("PARSE RESULTS")
|
||
print("=" * 80)
|
||
print()
|
||
|
||
# Frontends
|
||
print(f"🌐 FRONTENDS: {len(result['frontends'])}")
|
||
if result['frontends']:
|
||
print("-" * 80)
|
||
for name, stats in result['frontends'].items():
|
||
print(f" • {name}")
|
||
print(f" - Status: {stats['status']}")
|
||
print(f" - Requests: {stats['requests_total']:,}")
|
||
print(f" - Sessions: {stats['current_sessions']}")
|
||
print(f" - 2xx: {stats['hrsp_2xx']:,}, 4xx: {stats['hrsp_4xx']:,}, 5xx: {stats['hrsp_5xx']:,}")
|
||
else:
|
||
print(" ⚠️ No frontends found!")
|
||
print()
|
||
|
||
# Backends
|
||
print(f"☁️ BACKENDS: {len(result['backends'])}")
|
||
if result['backends']:
|
||
print("-" * 80)
|
||
for name, stats in result['backends'].items():
|
||
print(f" • {name}")
|
||
print(f" - Status: {stats['status']}")
|
||
print(f" - Requests: {stats['requests_total']:,}")
|
||
print(f" - Sessions: {stats['current_sessions']}")
|
||
print(f" - Response Time: {stats['response_time_avg']}ms")
|
||
else:
|
||
print(" ⚠️ No backends found!")
|
||
print()
|
||
|
||
# Servers
|
||
print(f"🖥️ SERVERS: {len(result['servers'])}")
|
||
if result['servers']:
|
||
print("-" * 80)
|
||
# Group by backend
|
||
by_backend = {}
|
||
for server in result['servers']:
|
||
backend = server['backend']
|
||
if backend not in by_backend:
|
||
by_backend[backend] = []
|
||
by_backend[backend].append(server)
|
||
|
||
for backend, servers in by_backend.items():
|
||
print(f" Backend: {backend}")
|
||
for server in servers:
|
||
status_icon = "🟢" if server['status'] == 'UP' else "🔴"
|
||
print(f" {status_icon} {server['name']} - {server['status']}")
|
||
else:
|
||
print(" ⚠️ No servers found!")
|
||
print()
|
||
|
||
# Summary
|
||
print("=" * 80)
|
||
print("SUMMARY")
|
||
print("=" * 80)
|
||
print(f"✅ Successfully parsed:")
|
||
print(f" - {len(result['frontends'])} frontends")
|
||
print(f" - {len(result['backends'])} backends")
|
||
print(f" - {len(result['servers'])} servers")
|
||
print()
|
||
|
||
if len(result['frontends']) == 0 and len(result['backends']) == 0:
|
||
print("⚠️ WARNING: No frontends or backends found!")
|
||
print(" This CSV might be:")
|
||
print(" - Empty")
|
||
print(" - Corrupted")
|
||
print(" - Not from HAProxy stats socket")
|
||
return 1
|
||
|
||
return 0
|
||
|
||
if __name__ == '__main__':
|
||
sys.exit(main())
|
||
|