2021-01-04 00:35:58 +01:00
|
|
|
import json
|
|
|
|
import logging
|
|
|
|
import threading
|
|
|
|
import time
|
2021-02-03 13:36:13 +01:00
|
|
|
import psutil
|
|
|
|
import shutil
|
2021-01-04 00:35:58 +01:00
|
|
|
|
|
|
|
from frigate.config import FrigateConfig
|
2021-02-03 13:36:13 +01:00
|
|
|
from frigate.const import RECORD_DIR, CLIPS_DIR, CACHE_DIR
|
2021-01-04 00:35:58 +01:00
|
|
|
from frigate.version import VERSION
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
def stats_init(camera_metrics, detectors):
|
|
|
|
stats_tracking = {
|
|
|
|
'camera_metrics': camera_metrics,
|
|
|
|
'detectors': detectors,
|
|
|
|
'started': int(time.time())
|
|
|
|
}
|
|
|
|
return stats_tracking
|
|
|
|
|
2021-02-03 13:36:13 +01:00
|
|
|
def get_fs_type(path):
|
|
|
|
bestMatch = ""
|
|
|
|
fsType = ""
|
|
|
|
for part in psutil.disk_partitions(all=True):
|
|
|
|
if path.startswith(part.mountpoint) and len(bestMatch) < len(part.mountpoint):
|
|
|
|
fsType = part.fstype
|
|
|
|
bestMatch = part.mountpoint
|
|
|
|
return fsType
|
|
|
|
|
2021-01-04 00:35:58 +01:00
|
|
|
def stats_snapshot(stats_tracking):
|
|
|
|
camera_metrics = stats_tracking['camera_metrics']
|
|
|
|
stats = {}
|
|
|
|
|
|
|
|
total_detection_fps = 0
|
|
|
|
|
|
|
|
for name, camera_stats in camera_metrics.items():
|
|
|
|
total_detection_fps += camera_stats['detection_fps'].value
|
|
|
|
stats[name] = {
|
|
|
|
'camera_fps': round(camera_stats['camera_fps'].value, 2),
|
|
|
|
'process_fps': round(camera_stats['process_fps'].value, 2),
|
|
|
|
'skipped_fps': round(camera_stats['skipped_fps'].value, 2),
|
|
|
|
'detection_fps': round(camera_stats['detection_fps'].value, 2),
|
|
|
|
'pid': camera_stats['process'].pid,
|
|
|
|
'capture_pid': camera_stats['capture_process'].pid
|
|
|
|
}
|
|
|
|
|
|
|
|
stats['detectors'] = {}
|
|
|
|
for name, detector in stats_tracking["detectors"].items():
|
|
|
|
stats['detectors'][name] = {
|
|
|
|
'inference_speed': round(detector.avg_inference_speed.value * 1000, 2),
|
|
|
|
'detection_start': detector.detection_start.value,
|
|
|
|
'pid': detector.detect_process.pid
|
|
|
|
}
|
|
|
|
stats['detection_fps'] = round(total_detection_fps, 2)
|
|
|
|
|
|
|
|
stats['service'] = {
|
|
|
|
'uptime': (int(time.time()) - stats_tracking['started']),
|
2021-02-03 13:36:13 +01:00
|
|
|
'version': VERSION,
|
|
|
|
'storage': {}
|
2021-01-04 00:35:58 +01:00
|
|
|
}
|
|
|
|
|
2021-02-03 13:36:13 +01:00
|
|
|
for path in [RECORD_DIR, CLIPS_DIR, CACHE_DIR, "/dev/shm"]:
|
|
|
|
storage_stats = shutil.disk_usage(path)
|
|
|
|
stats['service']['storage'][path] = {
|
|
|
|
'total': round(storage_stats.total/1000000, 1),
|
|
|
|
'used': round(storage_stats.used/1000000, 1),
|
|
|
|
'free': round(storage_stats.free/1000000, 1),
|
|
|
|
'mount_type': get_fs_type(path)
|
|
|
|
}
|
|
|
|
|
2021-01-04 00:35:58 +01:00
|
|
|
return stats
|
|
|
|
|
|
|
|
class StatsEmitter(threading.Thread):
|
|
|
|
def __init__(self, config: FrigateConfig, stats_tracking, mqtt_client, topic_prefix, stop_event):
|
|
|
|
threading.Thread.__init__(self)
|
|
|
|
self.name = 'frigate_stats_emitter'
|
|
|
|
self.config = config
|
|
|
|
self.stats_tracking = stats_tracking
|
|
|
|
self.mqtt_client = mqtt_client
|
|
|
|
self.topic_prefix = topic_prefix
|
|
|
|
self.stop_event = stop_event
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
time.sleep(10)
|
|
|
|
while True:
|
|
|
|
if self.stop_event.is_set():
|
|
|
|
logger.info(f"Exiting watchdog...")
|
|
|
|
break
|
|
|
|
stats = stats_snapshot(self.stats_tracking)
|
|
|
|
self.mqtt_client.publish(f"{self.topic_prefix}/stats", json.dumps(stats), retain=False)
|
|
|
|
time.sleep(self.config.mqtt.stats_interval)
|