-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstatistics_widget.py
More file actions
147 lines (113 loc) · 5.29 KB
/
statistics_widget.py
File metadata and controls
147 lines (113 loc) · 5.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"""
Statistics Widget
Displays statistics dashboard with charts and metrics.
"""
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QGroupBox
from PyQt5.QtCore import Qt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from log_statistics import LogStatistics
# Chart colors for consistent theming
CHART_COLORS = {
'debug': '#808080',
'info': '#4CAF50',
'warning': '#FFA500',
'error': '#FF0000',
'critical': '#8B0000',
'unknown': '#000000',
'primary': '#4CAF50'
}
class StatisticsWidget(QWidget):
"""Widget for displaying statistics dashboard"""
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
"""Initialize the UI"""
layout = QVBoxLayout()
# Title
title = QLabel("Log Statistics Dashboard")
title.setAlignment(Qt.AlignCenter)
title.setStyleSheet("font-size: 16px; font-weight: bold; padding: 10px;")
layout.addWidget(title)
# Create matplotlib figure for charts
self.figure = Figure(figsize=(12, 8))
self.canvas = FigureCanvas(self.figure)
layout.addWidget(self.canvas)
# Summary metrics
self.metrics_panel = QGroupBox("Summary Metrics")
metrics_layout = QHBoxLayout()
self.lbl_total = QLabel("Total: 0")
self.lbl_errors = QLabel("Errors: 0")
self.lbl_anomalies = QLabel("Anomalies: 0")
self.lbl_sources = QLabel("Sources: 0")
for lbl in [self.lbl_total, self.lbl_errors, self.lbl_anomalies, self.lbl_sources]:
lbl.setStyleSheet("font-size: 14px; padding: 10px;")
metrics_layout.addWidget(lbl)
self.metrics_panel.setLayout(metrics_layout)
layout.addWidget(self.metrics_panel)
self.setLayout(layout)
def update_statistics(self, statistics: LogStatistics):
"""Update statistics with new data"""
self.figure.clear()
summary = statistics.get_summary()
# Update metrics
self.lbl_total.setText(f"Total: {summary['total_entries']}")
self.lbl_errors.setText(f"Error Rate: {summary['error_rate']:.2f}%")
self.lbl_anomalies.setText(f"Anomalies: {summary['anomaly_count']}")
self.lbl_sources.setText(f"Unique Sources: {summary['unique_sources']}")
# Create subplots
if summary['total_entries'] == 0:
ax = self.figure.add_subplot(111)
ax.text(0.5, 0.5, 'No data available',
ha='center', va='center', fontsize=14)
self.canvas.draw()
return
# 1. Log Level Distribution (Pie Chart)
ax1 = self.figure.add_subplot(2, 2, 1)
level_dist = summary['level_distribution']
if level_dist:
labels = list(level_dist.keys())
sizes = list(level_dist.values())
colors = [CHART_COLORS['debug'], CHART_COLORS['info'], CHART_COLORS['warning'],
CHART_COLORS['error'], CHART_COLORS['critical'], CHART_COLORS['unknown']]
ax1.pie(sizes, labels=labels, autopct='%1.1f%%', colors=colors[:len(labels)],
startangle=90)
ax1.set_title('Log Level Distribution', fontweight='bold')
# 2. Top Sources (Bar Chart)
ax2 = self.figure.add_subplot(2, 2, 2)
top_sources = summary['top_sources']
if top_sources:
sources = [s[0][:20] for s in top_sources] # Truncate long names
counts = [s[1] for s in top_sources]
ax2.barh(sources, counts, color=CHART_COLORS['primary'])
ax2.set_xlabel('Count', fontweight='bold')
ax2.set_title('Top Log Sources', fontweight='bold')
ax2.invert_yaxis()
# 3. Error vs Non-Error (Bar Chart)
ax3 = self.figure.add_subplot(2, 2, 3)
error_count = sum(count for level, count in level_dist.items()
if level in ['ERROR', 'CRITICAL'])
non_error_count = summary['total_entries'] - error_count
ax3.bar(['Non-Errors', 'Errors'], [non_error_count, error_count],
color=[CHART_COLORS['info'], CHART_COLORS['error']])
ax3.set_ylabel('Count', fontweight='bold')
ax3.set_title('Error Distribution', fontweight='bold')
ax3.grid(axis='y', alpha=0.3)
# 4. Anomaly Count (Text Display)
ax4 = self.figure.add_subplot(2, 2, 4)
ax4.axis('off')
anomaly_pct = (summary['anomaly_count'] / summary['total_entries'] * 100) if summary['total_entries'] > 0 else 0
metrics_text = f"""
Total Entries: {summary['total_entries']:,}
Anomalies: {summary['anomaly_count']:,}
Anomaly Rate: {anomaly_pct:.2f}%
Error Rate: {summary['error_rate']:.2f}%
Unique Sources: {summary['unique_sources']}
"""
ax4.text(0.5, 0.5, metrics_text, ha='center', va='center',
fontsize=12, family='monospace',
bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))
# Tight layout
self.figure.tight_layout()
self.canvas.draw()