fix: clear all mypy errors
Annotate untyped containers and Optional attributes, type the stdlib-shaped metric dicts in the client plugins, and add types-PyYAML/types-psutil to the dev extras plus a mypy override for nio/mattermostdriver (no stubs). Behaviour fixes found on the way: enable_kernel_timestamps() now returns False when SO_TIMESTAMP is unknown instead of raising TypeError, send_shutdown is defined at module level so cleanup() cannot hit a NameError, and a failed subprocess returncode falls back to UNKNOWN. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,15 +2,16 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import yaml
|
import yaml
|
||||||
except Exception:
|
except Exception:
|
||||||
yaml = None
|
yaml = None # type: ignore[assignment]
|
||||||
|
|
||||||
CLIENT_DEFAULTS = {
|
CLIENT_DEFAULTS: Dict[str, Any] = {
|
||||||
# Network settings
|
# Network settings
|
||||||
"hb_port": 50003, # Port where hbd servers listen
|
"hb_port": 50003, # Port where hbd servers listen
|
||||||
"interval": 10, # Heartbeat interval in seconds
|
"interval": 10, # Heartbeat interval in seconds
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ MAXRECV = 32767
|
|||||||
# Global state
|
# Global state
|
||||||
running = True
|
running = True
|
||||||
dorestart = False
|
dorestart = False
|
||||||
|
send_shutdown = False
|
||||||
shutdown_event: Optional[asyncio.Event] = None
|
shutdown_event: Optional[asyncio.Event] = None
|
||||||
active_tasks: List[asyncio.Task] = []
|
active_tasks: List[asyncio.Task] = []
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import logging
|
|||||||
import sys
|
import sys
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, Optional, Type
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
|
||||||
class Plugin(ABC):
|
class Plugin(ABC):
|
||||||
@@ -256,7 +256,7 @@ class PluginRegistry:
|
|||||||
"""Get all enabled plugins."""
|
"""Get all enabled plugins."""
|
||||||
return [p for p in self._plugins.values() if p.enabled]
|
return [p for p in self._plugins.values() if p.enabled]
|
||||||
|
|
||||||
def get_by_type(self, plugin_type: Type[Plugin]) -> List[Plugin]:
|
def get_by_type(self, plugin_type: type) -> List[Plugin]:
|
||||||
"""Get all plugins of a specific type.
|
"""Get all plugins of a specific type.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class CPUMonitorPlugin(MonitorPlugin):
|
|||||||
|
|
||||||
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
||||||
super().__init__(config)
|
super().__init__(config)
|
||||||
self.psutil = None
|
self.psutil: Any = None
|
||||||
self.per_core = config.get("per_core", False) if config else False
|
self.per_core = config.get("per_core", False) if config else False
|
||||||
self.interval = config.get("interval", 300) if config else 300
|
self.interval = config.get("interval", 300) if config else 300
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from typing import Dict, Any, Optional
|
|||||||
try:
|
try:
|
||||||
import psutil
|
import psutil
|
||||||
except ImportError:
|
except ImportError:
|
||||||
psutil = None
|
psutil = None # type: ignore[assignment]
|
||||||
|
|
||||||
from hbd.client.plugin import MonitorPlugin
|
from hbd.client.plugin import MonitorPlugin
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ class DiskMonitorPlugin(MonitorPlugin):
|
|||||||
raise ImportError("psutil library is required for disk_monitor plugin")
|
raise ImportError("psutil library is required for disk_monitor plugin")
|
||||||
|
|
||||||
# Store previous I/O counters for delta calculation
|
# Store previous I/O counters for delta calculation
|
||||||
self._prev_io = {}
|
self._prev_io: Dict[str, Any] = {}
|
||||||
|
|
||||||
async def initialize(self):
|
async def initialize(self):
|
||||||
"""Initialize the plugin (check psutil availability)."""
|
"""Initialize the plugin (check psutil availability)."""
|
||||||
@@ -114,7 +114,7 @@ class DiskMonitorPlugin(MonitorPlugin):
|
|||||||
|
|
||||||
async def _collect_metrics(self) -> Dict[str, Any]:
|
async def _collect_metrics(self) -> Dict[str, Any]:
|
||||||
"""Collect disk metrics from psutil."""
|
"""Collect disk metrics from psutil."""
|
||||||
metrics = {}
|
metrics: Dict[str, Any] = {}
|
||||||
|
|
||||||
# Collect partition usage
|
# Collect partition usage
|
||||||
partitions_data = {}
|
partitions_data = {}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from typing import Dict, Any, Optional
|
|||||||
try:
|
try:
|
||||||
import psutil
|
import psutil
|
||||||
except ImportError:
|
except ImportError:
|
||||||
psutil = None
|
psutil = None # type: ignore[assignment]
|
||||||
|
|
||||||
from hbd.client.plugin import InfoPlugin
|
from hbd.client.plugin import InfoPlugin
|
||||||
|
|
||||||
@@ -98,8 +98,8 @@ class FilesystemInfoPlugin(InfoPlugin):
|
|||||||
|
|
||||||
async def _collect_info(self) -> Dict[str, Any]:
|
async def _collect_info(self) -> Dict[str, Any]:
|
||||||
"""Collect filesystem information from psutil."""
|
"""Collect filesystem information from psutil."""
|
||||||
info = {}
|
info: Dict[str, Any] = {}
|
||||||
filesystems = []
|
filesystems: list = []
|
||||||
filesystem_types = set()
|
filesystem_types = set()
|
||||||
|
|
||||||
# Get mounted disk partitions
|
# Get mounted disk partitions
|
||||||
@@ -112,7 +112,7 @@ class FilesystemInfoPlugin(InfoPlugin):
|
|||||||
if partition.fstype in self.exclude_types:
|
if partition.fstype in self.exclude_types:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
fs_info = {
|
fs_info: Dict[str, Any] = {
|
||||||
'device': partition.device,
|
'device': partition.device,
|
||||||
'mountpoint': partition.mountpoint,
|
'mountpoint': partition.mountpoint,
|
||||||
'fstype': partition.fstype,
|
'fstype': partition.fstype,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from typing import Dict, Any, Optional
|
|||||||
try:
|
try:
|
||||||
import psutil
|
import psutil
|
||||||
except ImportError:
|
except ImportError:
|
||||||
psutil = None
|
psutil = None # type: ignore[assignment]
|
||||||
|
|
||||||
from hbd.client.plugin import MonitorPlugin
|
from hbd.client.plugin import MonitorPlugin
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ class MemoryMonitorPlugin(MonitorPlugin):
|
|||||||
|
|
||||||
async def _collect_metrics(self) -> Dict[str, Any]:
|
async def _collect_metrics(self) -> Dict[str, Any]:
|
||||||
"""Collect memory metrics from psutil."""
|
"""Collect memory metrics from psutil."""
|
||||||
metrics = {}
|
metrics: Dict[str, Any] = {}
|
||||||
|
|
||||||
# Virtual (physical) memory statistics
|
# Virtual (physical) memory statistics
|
||||||
vmem = psutil.virtual_memory()
|
vmem = psutil.virtual_memory()
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ class NagiosRunnerPlugin(MonitorPlugin):
|
|||||||
Returns:
|
Returns:
|
||||||
Dictionary with results from all plugins
|
Dictionary with results from all plugins
|
||||||
"""
|
"""
|
||||||
results = {}
|
results: Dict[str, Any] = {}
|
||||||
|
|
||||||
for cmd_config in self.commands:
|
for cmd_config in self.commands:
|
||||||
name = cmd_config.get("name")
|
name = cmd_config.get("name")
|
||||||
@@ -181,7 +181,8 @@ class NagiosRunnerPlugin(MonitorPlugin):
|
|||||||
self.logger.error(f"Command timed out: {command}")
|
self.logger.error(f"Command timed out: {command}")
|
||||||
return NAGIOS_UNKNOWN, f"Command timed out after {self.timeout}s", {}
|
return NAGIOS_UNKNOWN, f"Command timed out after {self.timeout}s", {}
|
||||||
|
|
||||||
status_code = proc.returncode
|
# communicate() has finished, so the process has exited and returncode is set
|
||||||
|
status_code = proc.returncode if proc.returncode is not None else NAGIOS_UNKNOWN
|
||||||
|
|
||||||
if status_code < 0:
|
if status_code < 0:
|
||||||
return NAGIOS_UNKNOWN, f"Process killed by signal {-status_code}", {}
|
return NAGIOS_UNKNOWN, f"Process killed by signal {-status_code}", {}
|
||||||
@@ -225,7 +226,7 @@ class NagiosRunnerPlugin(MonitorPlugin):
|
|||||||
Returns:
|
Returns:
|
||||||
Dictionary of metric_name: value
|
Dictionary of metric_name: value
|
||||||
"""
|
"""
|
||||||
perfdata = {}
|
perfdata: Dict[str, Any] = {}
|
||||||
|
|
||||||
# Performance data comes after the pipe character
|
# Performance data comes after the pipe character
|
||||||
if '|' not in output:
|
if '|' not in output:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from typing import Dict, Any, Optional
|
|||||||
try:
|
try:
|
||||||
import psutil
|
import psutil
|
||||||
except ImportError:
|
except ImportError:
|
||||||
psutil = None
|
psutil = None # type: ignore[assignment]
|
||||||
|
|
||||||
from hbd.client.plugin import MonitorPlugin
|
from hbd.client.plugin import MonitorPlugin
|
||||||
from hbd.client.connectivity import get_shared
|
from hbd.client.connectivity import get_shared
|
||||||
@@ -63,7 +63,7 @@ class NetworkMonitorPlugin(MonitorPlugin):
|
|||||||
raise ImportError("psutil library is required for network_monitor plugin")
|
raise ImportError("psutil library is required for network_monitor plugin")
|
||||||
|
|
||||||
# Store previous I/O counters for delta calculation
|
# Store previous I/O counters for delta calculation
|
||||||
self._prev_io = {}
|
self._prev_io: Dict[str, Any] = {}
|
||||||
|
|
||||||
async def initialize(self):
|
async def initialize(self):
|
||||||
"""Initialize the plugin (check psutil availability)."""
|
"""Initialize the plugin (check psutil availability)."""
|
||||||
@@ -124,7 +124,7 @@ class NetworkMonitorPlugin(MonitorPlugin):
|
|||||||
|
|
||||||
async def _collect_metrics(self) -> Dict[str, Any]:
|
async def _collect_metrics(self) -> Dict[str, Any]:
|
||||||
"""Collect network metrics from psutil."""
|
"""Collect network metrics from psutil."""
|
||||||
metrics = {}
|
metrics: Dict[str, Any] = {}
|
||||||
|
|
||||||
# Collect per-interface I/O counters
|
# Collect per-interface I/O counters
|
||||||
try:
|
try:
|
||||||
@@ -169,7 +169,7 @@ class NetworkMonitorPlugin(MonitorPlugin):
|
|||||||
if self.include_connections:
|
if self.include_connections:
|
||||||
try:
|
try:
|
||||||
connections = psutil.net_connections(kind='inet')
|
connections = psutil.net_connections(kind='inet')
|
||||||
conn_stats = {}
|
conn_stats: Dict[str, int] = {}
|
||||||
|
|
||||||
# Count connections by state
|
# Count connections by state
|
||||||
for conn in connections:
|
for conn in connections:
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ class PingMonitorPlugin(MonitorPlugin):
|
|||||||
self.timeout = int(cfg.get("timeout", 5))
|
self.timeout = int(cfg.get("timeout", 5))
|
||||||
# hosts: dict of {hostname: {warning: x, critical: y}} or list of hostnames
|
# hosts: dict of {hostname: {warning: x, critical: y}} or list of hostnames
|
||||||
raw_hosts = cfg.get("hosts", {})
|
raw_hosts = cfg.get("hosts", {})
|
||||||
|
self.hosts: Dict[str, Any]
|
||||||
if isinstance(raw_hosts, list):
|
if isinstance(raw_hosts, list):
|
||||||
self.hosts = {h: {} for h in raw_hosts}
|
self.hosts = {h: {} for h in raw_hosts}
|
||||||
else:
|
else:
|
||||||
|
|||||||
+1
-1
@@ -92,7 +92,7 @@ def stodict(msg: bytes):
|
|||||||
'!' and decodes accordingly. Returns a dict with key 'ID' set to the
|
'!' and decodes accordingly. Returns a dict with key 'ID' set to the
|
||||||
message ID and the parsed key/value pairs.
|
message ID and the parsed key/value pairs.
|
||||||
"""
|
"""
|
||||||
d = {}
|
d: Dict[str, Any] = {}
|
||||||
if len(msg) > 0 and chr(msg[0]) == "!":
|
if len(msg) > 0 and chr(msg[0]) == "!":
|
||||||
# message is: b'!ID:' + compressed_payload
|
# message is: b'!ID:' + compressed_payload
|
||||||
# original code used msg[1:4].decode() for ID (3 bytes including colon)
|
# original code used msg[1:4].decode() for ID (3 bytes including colon)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import os
|
|||||||
try:
|
try:
|
||||||
import yaml
|
import yaml
|
||||||
except Exception:
|
except Exception:
|
||||||
yaml = None
|
yaml = None # type: ignore[assignment]
|
||||||
|
|
||||||
SERVER_DEFAULTS = {
|
SERVER_DEFAULTS = {
|
||||||
# Network settings
|
# Network settings
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
msgs = [] # in-memory list of recent messages for new websocket clients; also logged to file via notify.eventlog
|
msgs: list = [] # in-memory list of recent messages for new websocket clients; also logged to file via notify.eventlog
|
||||||
|
|
||||||
|
|
||||||
class Data:
|
class Data:
|
||||||
|
|||||||
+5
-5
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
from typing import Optional
|
from typing import Any, Callable, Optional
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -79,8 +79,8 @@ async def dns_update_worker(
|
|||||||
hbdclass,
|
hbdclass,
|
||||||
cfg: dict,
|
cfg: dict,
|
||||||
async_queue=None,
|
async_queue=None,
|
||||||
log: Optional[callable] = None,
|
log: Optional[Callable[..., Any]] = None,
|
||||||
pushmsg: Optional[callable] = None,
|
pushmsg: Optional[Callable[..., Any]] = None,
|
||||||
loop: Optional[asyncio.AbstractEventLoop] = None,
|
loop: Optional[asyncio.AbstractEventLoop] = None,
|
||||||
):
|
):
|
||||||
"""Pure async DNS worker that processes updates from asyncio.Queue.
|
"""Pure async DNS worker that processes updates from asyncio.Queue.
|
||||||
@@ -164,7 +164,7 @@ async def dns_update_worker(
|
|||||||
def start_dns_worker(
|
def start_dns_worker(
|
||||||
hbdclass,
|
hbdclass,
|
||||||
cfg: dict,
|
cfg: dict,
|
||||||
log: Optional[callable] = None,
|
log: Optional[Callable[..., Any]] = None,
|
||||||
loop: Optional[asyncio.AbstractEventLoop] = None,
|
loop: Optional[asyncio.AbstractEventLoop] = None,
|
||||||
):
|
):
|
||||||
"""Start the async DNS worker and return the Task.
|
"""Start the async DNS worker and return the Task.
|
||||||
@@ -176,7 +176,7 @@ def start_dns_worker(
|
|||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
# Create asyncio.Queue and wrap in a bridge for thread-safe puts
|
# Create asyncio.Queue and wrap in a bridge for thread-safe puts
|
||||||
async_q = asyncio.Queue()
|
async_q: asyncio.Queue[Any] = asyncio.Queue()
|
||||||
|
|
||||||
class _QueueBridge:
|
class _QueueBridge:
|
||||||
"""Thread-safe wrapper around asyncio.Queue for synchronous callers."""
|
"""Thread-safe wrapper around asyncio.Queue for synchronous callers."""
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import time
|
|||||||
import json
|
import json
|
||||||
import copy
|
import copy
|
||||||
import queue
|
import queue
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
num = 0
|
num = 0
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ def log(host, m):
|
|||||||
class Connection:
|
class Connection:
|
||||||
# map of addrs to names
|
# map of addrs to names
|
||||||
|
|
||||||
htab = {}
|
htab: Dict[str, Any] = {}
|
||||||
UNKNOWN = "unknown"
|
UNKNOWN = "unknown"
|
||||||
UP = "up"
|
UP = "up"
|
||||||
DOWN = "down"
|
DOWN = "down"
|
||||||
@@ -278,8 +279,8 @@ class Connection:
|
|||||||
#
|
#
|
||||||
class Host:
|
class Host:
|
||||||
# Table of Hosts
|
# Table of Hosts
|
||||||
hosts = {}
|
hosts: Dict[str, "Host"] = {}
|
||||||
dnsQ = queue.Queue()
|
dnsQ: "queue.Queue[Any]" = queue.Queue()
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
global num
|
global num
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import os
|
|||||||
import asyncio
|
import asyncio
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Any, Optional, Callable, Iterable, List, Tuple, Union
|
from typing import Dict, Any, Optional, Callable, Iterable, List, TextIO, Tuple, Union
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ class MessageJournal:
|
|||||||
self.enabled = self.config.get('journal_enabled', True)
|
self.enabled = self.config.get('journal_enabled', True)
|
||||||
|
|
||||||
# Runtime state
|
# Runtime state
|
||||||
self._file_handle = None
|
self._file_handle: Optional[TextIO] = None
|
||||||
self._current_size = 0
|
self._current_size = 0
|
||||||
self._lock = asyncio.Lock()
|
self._lock = asyncio.Lock()
|
||||||
self._initialized = False
|
self._initialized = False
|
||||||
|
|||||||
+1
-1
@@ -128,7 +128,7 @@ def get_providers(config: dict) -> list[ResolvedProvider]:
|
|||||||
Entries with missing required fields or unknown types are skipped with
|
Entries with missing required fields or unknown types are skipped with
|
||||||
a warning log. Order follows config declaration order.
|
a warning log. Order follows config declaration order.
|
||||||
"""
|
"""
|
||||||
result = []
|
result: list = []
|
||||||
oauth_cfg = config.get("oauth", {})
|
oauth_cfg = config.get("oauth", {})
|
||||||
if not isinstance(oauth_cfg, dict):
|
if not isinstance(oauth_cfg, dict):
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -53,16 +53,16 @@ class AlertState:
|
|||||||
self.metric_path = metric_path
|
self.metric_path = metric_path
|
||||||
self.level = AlertLevel.OK
|
self.level = AlertLevel.OK
|
||||||
self.since = time.time()
|
self.since = time.time()
|
||||||
self.last_value = None
|
self.last_value: Any = None
|
||||||
self.last_check = time.time()
|
self.last_check = time.time()
|
||||||
self.notification_count = 0
|
self.notification_count = 0
|
||||||
self.last_notification = None
|
self.last_notification: Optional[float] = None
|
||||||
self.threshold_value = None # The threshold value that triggered alert
|
self.threshold_value: Optional[float] = None # The threshold value that triggered alert
|
||||||
self.operator = None # The comparison operator (>, <, >=, etc.)
|
self.operator: Optional[str] = None # The comparison operator (>, <, >=, etc.)
|
||||||
self.hysteresis: Optional[float] = None # Hysteresis fraction used for recovery
|
self.hysteresis: Optional[float] = None # Hysteresis fraction used for recovery
|
||||||
self.formatted_message = None # Formatted display message for UI
|
self.formatted_message: Optional[str] = None # Formatted display message for UI
|
||||||
self.acknowledged = False # Whether alert has been acknowledged
|
self.acknowledged = False # Whether alert has been acknowledged
|
||||||
self.acknowledged_at = None # Timestamp when acknowledged
|
self.acknowledged_at: Optional[float] = None # Timestamp when acknowledged
|
||||||
self.consecutive_count = 0 # Consecutive exceedances while still OK (for count gating)
|
self.consecutive_count = 0 # Consecutive exceedances while still OK (for count gating)
|
||||||
self.pending_since: Optional[float] = None # non-None while waiting out grace period before notifying
|
self.pending_since: Optional[float] = None # non-None while waiting out grace period before notifying
|
||||||
|
|
||||||
@@ -362,13 +362,13 @@ class ThresholdChecker:
|
|||||||
journal: Optional MessageJournal instance for logging threshold events
|
journal: Optional MessageJournal instance for logging threshold events
|
||||||
"""
|
"""
|
||||||
# Named threshold configurations (pre-merged: defaults + overrides): {config_name: {metric_path: ThresholdConfig}}
|
# Named threshold configurations (pre-merged: defaults + overrides): {config_name: {metric_path: ThresholdConfig}}
|
||||||
self.threshold_configs = {}
|
self.threshold_configs: Dict[str, Dict[str, ThresholdConfig]] = {}
|
||||||
|
|
||||||
# Raw overrides only for each named config (no defaults baked in): {config_name: {metric_path: ThresholdConfig}}
|
# Raw overrides only for each named config (no defaults baked in): {config_name: {metric_path: ThresholdConfig}}
|
||||||
self.threshold_raw_configs: Dict[str, Dict[str, ThresholdConfig]] = {}
|
self.threshold_raw_configs: Dict[str, Dict[str, ThresholdConfig]] = {}
|
||||||
|
|
||||||
# Single threshold set for backward compatibility: {metric_path: ThresholdConfig}
|
# Single threshold set for backward compatibility: {metric_path: ThresholdConfig}
|
||||||
self.thresholds = {}
|
self.thresholds: Dict[str, ThresholdConfig] = {}
|
||||||
|
|
||||||
# Host to ordered list of config names: {host_name: [config_name, ...]}
|
# Host to ordered list of config names: {host_name: [config_name, ...]}
|
||||||
self.host_config_mapping: Dict[str, List[str]] = {}
|
self.host_config_mapping: Dict[str, List[str]] = {}
|
||||||
@@ -1276,7 +1276,7 @@ class ThresholdChecker:
|
|||||||
|
|
||||||
def _format_display(
|
def _format_display(
|
||||||
self,
|
self,
|
||||||
display_format: str,
|
display_format: Optional[str],
|
||||||
value: Any,
|
value: Any,
|
||||||
threshold_value: Optional[float],
|
threshold_value: Optional[float],
|
||||||
op_symbol: str,
|
op_symbol: str,
|
||||||
|
|||||||
+7
-5
@@ -5,6 +5,7 @@ import socket
|
|||||||
import struct
|
import struct
|
||||||
import time
|
import time
|
||||||
import zlib
|
import zlib
|
||||||
|
from typing import Optional
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from platform import system as platform_system
|
from platform import system as platform_system
|
||||||
@@ -25,6 +26,7 @@ _STALE_INTERVAL_MULTIPLIER = 3
|
|||||||
# Supported on Linux, FreeBSD, and macOS. The constant is not exposed by
|
# Supported on Linux, FreeBSD, and macOS. The constant is not exposed by
|
||||||
# Python's socket module on all platforms
|
# Python's socket module on all platforms
|
||||||
platform = platform_system()
|
platform = platform_system()
|
||||||
|
_SO_TIMESTAMP: Optional[int]
|
||||||
if platform == "Darwin":
|
if platform == "Darwin":
|
||||||
_SO_TIMESTAMP = 1024 # SO_TIMESTAMP on macOS (not in Python's socket module)
|
_SO_TIMESTAMP = 1024 # SO_TIMESTAMP on macOS (not in Python's socket module)
|
||||||
elif platform == "Linux":
|
elif platform == "Linux":
|
||||||
@@ -45,6 +47,8 @@ def enable_kernel_timestamps(sock) -> bool:
|
|||||||
Returns True if the kernel will supply receive timestamps, False otherwise
|
Returns True if the kernel will supply receive timestamps, False otherwise
|
||||||
(unsupported platform, older kernel, or insufficient permissions).
|
(unsupported platform, older kernel, or insufficient permissions).
|
||||||
"""
|
"""
|
||||||
|
if _SO_TIMESTAMP is None:
|
||||||
|
return False
|
||||||
try:
|
try:
|
||||||
sock.setsockopt(socket.SOL_SOCKET, _SO_TIMESTAMP, 1)
|
sock.setsockopt(socket.SOL_SOCKET, _SO_TIMESTAMP, 1)
|
||||||
return True
|
return True
|
||||||
@@ -430,7 +434,7 @@ def handle_datagram(msg: dict, addr, transport, ctx: dict):
|
|||||||
return
|
return
|
||||||
|
|
||||||
cfg = ctx.get("config", {})
|
cfg = ctx.get("config", {})
|
||||||
hbdcls = ctx.get("hbdclass")
|
hbdcls = ctx["hbdclass"]
|
||||||
msg_to_websockets = ctx.get("msg_to_websockets")
|
msg_to_websockets = ctx.get("msg_to_websockets")
|
||||||
DEBUG = ctx.get("DEBUG", 0)
|
DEBUG = ctx.get("DEBUG", 0)
|
||||||
|
|
||||||
@@ -459,10 +463,8 @@ def handle_datagram(msg: dict, addr, transport, ctx: dict):
|
|||||||
newh = False
|
newh = False
|
||||||
|
|
||||||
cid = msg.get("id", 0)
|
cid = msg.get("id", 0)
|
||||||
try:
|
rtt_raw = msg.get("rtt")
|
||||||
rtt = float(msg.get("rtt"))
|
rtt = float(rtt_raw) if rtt_raw is not None else None
|
||||||
except TypeError:
|
|
||||||
rtt = None
|
|
||||||
|
|
||||||
if msg.get("ID") == "HTB":
|
if msg.get("ID") == "HTB":
|
||||||
host.doesack = msg.get("acks", -1)
|
host.doesack = msg.get("acks", -1)
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ dev = [
|
|||||||
"pytest-cov>=4.0",
|
"pytest-cov>=4.0",
|
||||||
"flake8>=5.0",
|
"flake8>=5.0",
|
||||||
"mypy>=1.10",
|
"mypy>=1.10",
|
||||||
|
"types-PyYAML",
|
||||||
|
"types-psutil",
|
||||||
"black>=23.0",
|
"black>=23.0",
|
||||||
"isort>=5.0",
|
"isort>=5.0",
|
||||||
"tox>=4.0",
|
"tox>=4.0",
|
||||||
@@ -92,5 +94,10 @@ max-line-length = 111
|
|||||||
[tool.pylint.format]
|
[tool.pylint.format]
|
||||||
max-line-length = 111
|
max-line-length = 111
|
||||||
|
|
||||||
|
[[tool.mypy.overrides]]
|
||||||
|
# optional notification libraries that ship neither stubs nor py.typed
|
||||||
|
module = ["nio", "nio.*", "mattermostdriver", "mattermostdriver.*"]
|
||||||
|
ignore_missing_imports = true
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
testpaths = ["tests"]
|
testpaths = ["tests"]
|
||||||
|
|||||||
Reference in New Issue
Block a user