fix web page issues
This commit is contained in:
+33
-13
@@ -308,19 +308,29 @@ class Host:
|
|||||||
d["dyn"] = str(self.dyn)
|
d["dyn"] = str(self.dyn)
|
||||||
d["num"] = self.num
|
d["num"] = self.num
|
||||||
|
|
||||||
# Add alert counts
|
# Add alert counts (split by acknowledged status)
|
||||||
warning_count = 0
|
warning_unacked = 0
|
||||||
critical_count = 0
|
warning_acked = 0
|
||||||
|
critical_unacked = 0
|
||||||
|
critical_acked = 0
|
||||||
for metric_path, alert_state in self.alert_states.items():
|
for metric_path, alert_state in self.alert_states.items():
|
||||||
# Import AlertLevel here to avoid circular imports
|
# Import AlertLevel here to avoid circular imports
|
||||||
from .threshold import AlertLevel
|
from .threshold import AlertLevel
|
||||||
if alert_state.level == AlertLevel.WARNING:
|
if alert_state.level == AlertLevel.WARNING:
|
||||||
warning_count += 1
|
if alert_state.acknowledged:
|
||||||
|
warning_acked += 1
|
||||||
|
else:
|
||||||
|
warning_unacked += 1
|
||||||
elif alert_state.level == AlertLevel.CRITICAL:
|
elif alert_state.level == AlertLevel.CRITICAL:
|
||||||
critical_count += 1
|
if alert_state.acknowledged:
|
||||||
|
critical_acked += 1
|
||||||
|
else:
|
||||||
|
critical_unacked += 1
|
||||||
|
|
||||||
d["alert_warning_count"] = warning_count
|
d["alert_warning_unacked"] = warning_unacked
|
||||||
d["alert_critical_count"] = critical_count
|
d["alert_warning_acked"] = warning_acked
|
||||||
|
d["alert_critical_unacked"] = critical_unacked
|
||||||
|
d["alert_critical_acked"] = critical_acked
|
||||||
|
|
||||||
for c in ["IPv4", "IPv6"]:
|
for c in ["IPv4", "IPv6"]:
|
||||||
if c in self.connections:
|
if c in self.connections:
|
||||||
@@ -380,18 +390,28 @@ class Host:
|
|||||||
ddict[d] = self.__dict__[d]
|
ddict[d] = self.__dict__[d]
|
||||||
|
|
||||||
# Add alert counts (computed from alert_states)
|
# Add alert counts (computed from alert_states)
|
||||||
warning_count = 0
|
warning_unacked = 0
|
||||||
critical_count = 0
|
warning_acked = 0
|
||||||
|
critical_unacked = 0
|
||||||
|
critical_acked = 0
|
||||||
if hasattr(self, 'alert_states'):
|
if hasattr(self, 'alert_states'):
|
||||||
from .threshold import AlertLevel
|
from .threshold import AlertLevel
|
||||||
for metric_path, alert_state in self.alert_states.items():
|
for metric_path, alert_state in self.alert_states.items():
|
||||||
if alert_state.level == AlertLevel.WARNING:
|
if alert_state.level == AlertLevel.WARNING:
|
||||||
warning_count += 1
|
if alert_state.acknowledged:
|
||||||
|
warning_acked += 1
|
||||||
|
else:
|
||||||
|
warning_unacked += 1
|
||||||
elif alert_state.level == AlertLevel.CRITICAL:
|
elif alert_state.level == AlertLevel.CRITICAL:
|
||||||
critical_count += 1
|
if alert_state.acknowledged:
|
||||||
|
critical_acked += 1
|
||||||
|
else:
|
||||||
|
critical_unacked += 1
|
||||||
|
|
||||||
ddict["alert_warning_count"] = warning_count
|
ddict["alert_warning_unacked"] = warning_unacked
|
||||||
ddict["alert_critical_count"] = critical_count
|
ddict["alert_warning_acked"] = warning_acked
|
||||||
|
ddict["alert_critical_unacked"] = critical_unacked
|
||||||
|
ddict["alert_critical_acked"] = critical_acked
|
||||||
|
|
||||||
return ddict
|
return ddict
|
||||||
|
|
||||||
|
|||||||
@@ -276,11 +276,23 @@
|
|||||||
c_name.innerHTML = data.name;
|
c_name.innerHTML = data.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set alert counts
|
// Set alert counts in "x/y" format (unacked/acked)
|
||||||
var warningCount = data.alert_warning_count || 0;
|
var warningUnacked = data.alert_warning_unacked || 0;
|
||||||
var criticalCount = data.alert_critical_count || 0;
|
var warningAcked = data.alert_warning_acked || 0;
|
||||||
c_warning.innerHTML = warningCount > 0 ? warningCount : "";
|
var criticalUnacked = data.alert_critical_unacked || 0;
|
||||||
c_critical.innerHTML = criticalCount > 0 ? criticalCount : "";
|
var criticalAcked = data.alert_critical_acked || 0;
|
||||||
|
|
||||||
|
if (warningUnacked > 0 || warningAcked > 0) {
|
||||||
|
c_warning.innerHTML = warningAcked > 0 ? warningUnacked + "/" + warningAcked : warningUnacked;
|
||||||
|
} else {
|
||||||
|
c_warning.innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (criticalUnacked > 0 || criticalAcked > 0) {
|
||||||
|
c_critical.innerHTML = criticalAcked > 0 ? criticalUnacked + "/" + criticalAcked : criticalUnacked;
|
||||||
|
} else {
|
||||||
|
c_critical.innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
c_ipv4addr.innerHTML = data.connections[0].addr;
|
c_ipv4addr.innerHTML = data.connections[0].addr;
|
||||||
c_ipv4state.innerHTML = data.connections[0].state;
|
c_ipv4state.innerHTML = data.connections[0].state;
|
||||||
@@ -305,11 +317,23 @@
|
|||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update warning and critical counts
|
// Update warning and critical counts in "x/y" format (unacked/acked)
|
||||||
var warningCount = data.alert_warning_count || 0;
|
var warningUnacked = data.alert_warning_unacked || 0;
|
||||||
var criticalCount = data.alert_critical_count || 0;
|
var warningAcked = data.alert_warning_acked || 0;
|
||||||
name_idx[data.name].cells[1].innerHTML = warningCount > 0 ? warningCount : "";
|
var criticalUnacked = data.alert_critical_unacked || 0;
|
||||||
name_idx[data.name].cells[2].innerHTML = criticalCount > 0 ? criticalCount : "";
|
var criticalAcked = data.alert_critical_acked || 0;
|
||||||
|
|
||||||
|
if (warningUnacked > 0 || warningAcked > 0) {
|
||||||
|
name_idx[data.name].cells[1].innerHTML = warningAcked > 0 ? warningUnacked + "/" + warningAcked : warningUnacked;
|
||||||
|
} else {
|
||||||
|
name_idx[data.name].cells[1].innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (criticalUnacked > 0 || criticalAcked > 0) {
|
||||||
|
name_idx[data.name].cells[2].innerHTML = criticalAcked > 0 ? criticalUnacked + "/" + criticalAcked : criticalUnacked;
|
||||||
|
} else {
|
||||||
|
name_idx[data.name].cells[2].innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < data.connections.length; i++) {
|
for (var i = 0; i < data.connections.length; i++) {
|
||||||
// Offset by 2 for the warning/critical count columns
|
// Offset by 2 for the warning/critical count columns
|
||||||
@@ -428,8 +452,20 @@
|
|||||||
{% for host in hosts %}
|
{% for host in hosts %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ host.name }}</td>
|
<td>{{ host.name }}</td>
|
||||||
<td style="text-align: center; color: #ff9800; font-weight: bold;">{{ host.alert_warning_count if host.alert_warning_count > 0 else '' }}</td>
|
<td style="text-align: center; color: #ff9800; font-weight: bold;">
|
||||||
<td style="text-align: center; color: #f44336; font-weight: bold;">{{ host.alert_critical_count if host.alert_critical_count > 0 else '' }}</td>
|
{%- set warning_unacked = host.alert_warning_unacked -%}
|
||||||
|
{%- set warning_acked = host.alert_warning_acked -%}
|
||||||
|
{%- if warning_unacked > 0 or warning_acked > 0 -%}
|
||||||
|
{{ warning_unacked }}{% if warning_acked > 0 %}/{{ warning_acked }}{% endif %}
|
||||||
|
{%- endif -%}
|
||||||
|
</td>
|
||||||
|
<td style="text-align: center; color: #f44336; font-weight: bold;">
|
||||||
|
{%- set critical_unacked = host.alert_critical_unacked -%}
|
||||||
|
{%- set critical_acked = host.alert_critical_acked -%}
|
||||||
|
{%- if critical_unacked > 0 or critical_acked > 0 -%}
|
||||||
|
{{ critical_unacked }}{% if critical_acked > 0 %}/{{ critical_acked }}{% endif %}
|
||||||
|
{%- endif -%}
|
||||||
|
</td>
|
||||||
{% for conn in host.connections %}
|
{% for conn in host.connections %}
|
||||||
<td>{{ conn.addr if conn.addr else '' }}</td>
|
<td>{{ conn.addr if conn.addr else '' }}</td>
|
||||||
<td>{{ conn.state if conn.state else '' }}</td>
|
<td>{{ conn.state if conn.state else '' }}</td>
|
||||||
|
|||||||
+10
-2
@@ -114,11 +114,19 @@ class AlertState:
|
|||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
"""Convert alert state to dictionary for serialization."""
|
"""Convert alert state to dictionary for serialization."""
|
||||||
|
import math
|
||||||
|
|
||||||
|
# Helper to sanitize numeric values for JSON (handle inf/nan)
|
||||||
|
def sanitize_value(val):
|
||||||
|
if isinstance(val, float) and (math.isinf(val) or math.isnan(val)):
|
||||||
|
return None
|
||||||
|
return val
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"metric_path": self.metric_path,
|
"metric_path": self.metric_path,
|
||||||
"level": self.level.name,
|
"level": self.level.name,
|
||||||
"since": self.since,
|
"since": self.since,
|
||||||
"last_value": self.last_value,
|
"last_value": sanitize_value(self.last_value),
|
||||||
"last_check": self.last_check,
|
"last_check": self.last_check,
|
||||||
"notification_count": self.notification_count,
|
"notification_count": self.notification_count,
|
||||||
"acknowledged": self.acknowledged,
|
"acknowledged": self.acknowledged,
|
||||||
@@ -130,7 +138,7 @@ class AlertState:
|
|||||||
|
|
||||||
# Include threshold info if available
|
# Include threshold info if available
|
||||||
if self.threshold_value is not None:
|
if self.threshold_value is not None:
|
||||||
result["threshold_value"] = self.threshold_value
|
result["threshold_value"] = sanitize_value(self.threshold_value)
|
||||||
if self.operator is not None:
|
if self.operator is not None:
|
||||||
result["operator"] = self.operator
|
result["operator"] = self.operator
|
||||||
if self.formatted_message is not None:
|
if self.formatted_message is not None:
|
||||||
|
|||||||
Reference in New Issue
Block a user