Spaces:
Runtime error
Runtime error
| # modules/visualizer.py | |
| import pandas as pd | |
| import matplotlib.pyplot as plt | |
| from datetime import datetime | |
| import os | |
| import logging | |
| def load_status_log(log_file="server_status_log.csv"): | |
| """Load server status log from CSV file""" | |
| if not os.path.exists(log_file): | |
| raise FileNotFoundError(f"Log file not found: {log_file}") | |
| try: | |
| df = pd.read_csv(log_file, parse_dates=["timestamp"]) | |
| return df | |
| except Exception as e: | |
| logging.error(f"Error loading log file: {e}") | |
| raise | |
| def plot_uptime_trend(df, output_file="server_uptime_trend.png"): | |
| """Plot server uptime trend over time""" | |
| try: | |
| # Sort by timestamp | |
| df = df.sort_values("timestamp") | |
| # Convert status to boolean | |
| df["status_bool"] = df["status"].map({"UP": 1, "DOWN": 0}) | |
| plt.figure(figsize=(12, 4)) | |
| plt.plot(df["timestamp"], df["status_bool"], drawstyle='steps-post', | |
| marker='o', linestyle='-', markersize=3, color='#1f77b4') | |
| plt.title("Server Uptime Trend", fontsize=14, pad=20) | |
| plt.xlabel("Time", fontsize=12) | |
| plt.ylabel("Status", fontsize=12) | |
| plt.yticks([0, 1], ["DOWN", "UP"]) | |
| plt.grid(True, linestyle='--', alpha=0.5) | |
| plt.tight_layout() | |
| plt.savefig(output_file) | |
| plt.close() | |
| print(f"๐ Chart saved to: {output_file}") | |
| logging.info(f"Uptime trend chart saved to: {output_file}") | |
| return output_file | |
| except Exception as e: | |
| logging.error(f"Error plotting uptime trend: {e}") | |
| raise | |
| def plot_uptime_summary(df, output_file="server_uptime_summary.png"): | |
| """Plot server uptime summary as pie chart""" | |
| try: | |
| # Calculate uptime percentage | |
| total = len(df) | |
| up = df[df["status"] == "UP"].shape[0] | |
| down = df[df["status"] == "DOWN"].shape[0] | |
| if total == 0: | |
| raise ValueError("No data in log file") | |
| uptime_pct = (up / total) * 100 | |
| downtime_pct = (down / total) * 100 | |
| labels = [f'UP ({uptime_pct:.1f}%)', f'DOWN ({downtime_pct:.1f}%)'] | |
| sizes = [up, down] | |
| colors = ['#28a745', '#dc3545'] | |
| plt.figure(figsize=(6, 6)) | |
| wedges, texts, autotexts = plt.pie(sizes, labels=labels, autopct='%1.1f%%', | |
| startangle=140, colors=colors) | |
| # Make percentage text white and bold | |
| for autotext in autotexts: | |
| autotext.set_color('white') | |
| autotext.set_fontweight('bold') | |
| plt.title("Server Uptime Summary", fontsize=14, pad=20) | |
| plt.axis('equal') | |
| plt.tight_layout() | |
| plt.savefig(output_file) | |
| plt.close() | |
| print(f"๐ Summary chart saved to: {output_file}") | |
| logging.info(f"Uptime summary chart saved to: {output_file}") | |
| return output_file | |
| except Exception as e: | |
| logging.error(f"Error plotting uptime summary: {e}") | |
| raise | |
| def get_uptime_stats(df): | |
| """Get uptime statistics""" | |
| try: | |
| total = len(df) | |
| up = df[df["status"] == "UP"].shape[0] | |
| down = df[df["status"] == "DOWN"].shape[0] | |
| if total == 0: | |
| return {"total_checks": 0, "uptime_pct": 0, "downtime_pct": 0} | |
| uptime_pct = (up / total) * 100 | |
| downtime_pct = (down / total) * 100 | |
| return { | |
| "total_checks": total, | |
| "up_checks": up, | |
| "down_checks": down, | |
| "uptime_pct": round(uptime_pct, 2), | |
| "downtime_pct": round(downtime_pct, 2) | |
| } | |
| except Exception as e: | |
| logging.error(f"Error calculating uptime stats: {e}") | |
| raise |