From 07a824d3c22c6e1cb5dfcd4ce654de0fa7ae6201 Mon Sep 17 00:00:00 2001 From: Kim Huebel Date: Wed, 14 Apr 2021 22:04:34 +0100 Subject: [PATCH] Added Service-Monitoring New Tab with service-monitoring added --- .gitmodules | 4 +++ html/css/styles.css | 3 +++ html/data/TG_List.csv | 4 +-- html/index.html | 20 +++++++++++++++ html/js/config.js | 5 ++-- html/js/functions.js | 59 ++++++++++++++++++++++++++++++++++++++++++- html/js/version.js | 2 +- html/open-iconic | 1 + logtailer.ini | 6 +++++ logtailer.py | 31 ++++++++++++++++++++++- 10 files changed, 128 insertions(+), 7 deletions(-) create mode 160000 html/open-iconic diff --git a/.gitmodules b/.gitmodules index d0b6407..52ea8f1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "html/metar.js"] path = html/metar.js url = https://github.com/skydivejkl/metar.js +[submodule "html/open-iconic"] + path = html/open-iconic + url = https://github.com/iconic/open-iconic + branch = master diff --git a/html/css/styles.css b/html/css/styles.css index d16b55b..01d2adf 100644 --- a/html/css/styles.css +++ b/html/css/styles.css @@ -30,3 +30,6 @@ td.dt-nowrap { white-space: nowrap } .red { background-color: Coral !important; } + + +#services_monitor_list {list-style-type: none;} \ No newline at end of file diff --git a/html/data/TG_List.csv b/html/data/TG_List.csv index e7fac7f..a1f89dc 100644 --- a/html/data/TG_List.csv +++ b/html/data/TG_List.csv @@ -6,8 +6,8 @@ YSF,0,1,Local Parrot, YSF,0,2,DEV Reflector, YSF,0,10,YSF2DMR TG26250, YSF,0,40,DL Multimode 263,https://c4fm.ysfreflector.de/Germany/ -YSF,0,41,DL-RAMSES, -YSF,0,42,DL-RAMSES-II, +YSF,0,41,DL-RAMSES,http://161.97.140.131:8000/RAMSES.html +YSF,0,42,DL-RAMSES-II,http://161.97.140.131:8000/RAMSES-II.html YSF,0,43,DL-RAMSES-III, YSF,0,44,DL-PEGASUS, YSF,0,45,DL-SAAR,https://c4fm.ysfreflector.de/DL-Saar/ diff --git a/html/index.html b/html/index.html index e336f67..ce560d3 100644 --- a/html/index.html +++ b/html/index.html @@ -29,6 +29,7 @@ + DG9VH - MMDVM-Dashboard by DG9VH @@ -87,6 +88,9 @@ + @@ -294,6 +298,15 @@ +
+
+ +
Services Monitor
+
+
    +
+
+
@@ -446,6 +459,13 @@ t_dapnet.order( [ 0, 'desc' ] ).draw(); } + if (services > 0) { + var ws3 = new WebSocket("ws://" + window.location.hostname + ":5678/SERVICES"); + ws3.onmessage = function (event) { + getServicesStatus(document, event); + }; + } + checkConfigStructure(); diff --git a/html/js/config.js b/html/js/config.js index 92acc36..311aa34 100644 --- a/html/js/config.js +++ b/html/js/config.js @@ -1,5 +1,5 @@ // config structure version, please change to value in github-file after update and adding new values -var config_struc_ver = 20210312.1; +var config_struc_ver = 20210414.1; // 1 = show link to QRZ.com, 0 = off var qrz = 1; @@ -20,6 +20,7 @@ var allheard = 1; var qso = 1; var dapnet = 1; var sysinfo = 1; +var services = 1; var about = 1; // Set displayed timezone and timestamp to timezone of browser if 1, else use UTC for displaying @@ -38,4 +39,4 @@ var qrz_blacklist = [ var dashboard_blacklist = [ "MY0CALL", -] \ No newline at end of file +] diff --git a/html/js/functions.js b/html/js/functions.js index fd1555c..9202c50 100644 --- a/html/js/functions.js +++ b/html/js/functions.js @@ -1,4 +1,4 @@ -var act_config_struc_ver = 20210312.1; +var act_config_struc_ver = 20210314.1; var messagecount = 0; var ts1TXing = null; var ts2TXing = null; @@ -21,6 +21,8 @@ dapnet = typeof(dapnet) == 'undefined' ? 1 : dapnet; sysinfo = typeof(sysinfo) == 'undefined' ? 1 : sysinfo; about = typeof(about) == 'undefined' ? 1 : about; +var array_services = []; + setInterval(getCurrentTXing, 1000); function logIt(message) { @@ -857,6 +859,61 @@ function getSysInfo(document, event) { }); } +function getServiceName(event) { + return event.data.substring(17, event.data.lastIndexOf(":")); +} + + +function getServiceState(event) { + return event.data.substr(event.data.lastIndexOf(":") + 1); +} + +function addToServices(servicename, servicestate) { + var newService = new Array(); + newService[0] = servicename; + newService[1] = servicestate; + array_services.push(newService); +} + +function insertOrUpdateServiceState(servicename, servicestate) { + updated = false; + for (i = 0; i < array_services.length; ++i){ + actual_service = array_services[i]; + if (actual_service[0] == servicename) { + var newService = new Array(); + newService[0] = servicename; + newService[1] = servicestate; + array_services[i] = newService; + updated = true; + } + } + if (updated == false) { + addToServices(servicename, servicestate); + } +} + +function getServicesStatus(document, event) { + $(document).ready(function() { + if (event.data.startsWith("SERVICESMONITOR")) { + var servicename = getServiceName(event); + var servicestate = getServiceState(event); + insertOrUpdateServiceState(servicename, servicestate); + + document.getElementById("services_monitor").innerHTML = '
    '; + //document.getElementById("services_monitor").innerHTML = '
      '; + + array_services.forEach(function(actual_service){ + if (actual_service[1] == "running") { + document.getElementById("services_monitor_list").innerHTML += '
    • ' + actual_service[0] + '
    • '; + } else { + document.getElementById("services_monitor_list").innerHTML += '
    • ' + actual_service[0] + '
    • '; + } + }); + document.getElementById("services_monitor").innerHTML += "
    "; + } + }); +} + function activateDefaultTab(name) { var element = document.getElementById(name + "-tab"); element.classList.add("active"); diff --git a/html/js/version.js b/html/js/version.js index 20afeb6..3395fe9 100644 --- a/html/js/version.js +++ b/html/js/version.js @@ -1 +1 @@ -var dashboard_version = "2021-04-10 19:54:10"; +var dashboard_version = "2021-04-14 22:04:34"; diff --git a/html/open-iconic b/html/open-iconic new file mode 160000 index 0000000..1d1e888 --- /dev/null +++ b/html/open-iconic @@ -0,0 +1 @@ +Subproject commit 1d1e8885c5031874b32f4e480e371ce2b1c24144 diff --git a/logtailer.ini b/logtailer.ini index 216238a..ebfbaee 100644 --- a/logtailer.ini +++ b/logtailer.ini @@ -41,3 +41,9 @@ MMDVM_bin=/usr/local/bin/MMDVMHost Logdir=/mnt/ramdisk/ Prefix=DAPNETGateway +[ServiceMonitoring] +# Here you list your Services to be monitored +BinaryName1=MMDVMHost +BinaryName2=DMRGateway +BinaryName3=DGIdGateway +BinaryName4=YSF2DMR diff --git a/logtailer.py b/logtailer.py index 42ad9cf..a3d7450 100644 --- a/logtailer.py +++ b/logtailer.py @@ -260,7 +260,8 @@ async def view_log(websocket, path): await websocket.send(line) else: await asyncio.sleep(0.2) - elif path == "/SYSINFO": + + if path == "/SYSINFO": mmdvmhost_version = str(subprocess.Popen(config['MMDVMHost']['MMDVM_bin'] + " -v", shell=True, stdout=subprocess.PIPE).stdout.read().decode("utf-8")) mmdvmhost_ctime = time.ctime(os.path.getmtime(config['MMDVMHost']['MMDVM_bin'])) mmdvmhost_buildtime = datetime.datetime.strptime(mmdvmhost_ctime, "%a %b %d %H:%M:%S %Y") @@ -304,6 +305,19 @@ async def view_log(websocket, path): await websocket.send("SYSINFO: cputemp:" + cpu_temp + " cpufrg:" + cpufrq + " cpuusage:" + cpu_usage + " cpu_load1:" + cpu_load1 + " cpu_load5:" + cpu_load5 + " cpu_load15:" + cpu_load15 + " ram_total:" + ram_total + " ram_used:" + ram_used + " ram_free:" + ram_free + " ram_percent_used:" + ram_percent_used + " disk_total:" + disk_total + " disk_used:" + disk_used + " disk_free:" + disk_free + " disk_percent_used:" + disk_percent_used) await asyncio.sleep(10) + if path == "/SERVICES": + services_items = [x for x in config.items('ServiceMonitoring') if x[0] not in config.defaults()] + while True: + for key, value in services_items: + logging.info('key: ' + key + " = " + value) + if checkIfProcessRunning(value): + logging.info('process ' + value + " is running") + await websocket.send("SERVICESMONITOR: " + value + ":running") + else: + logging.info('process ' + value + " is stopped") + await websocket.send("SERVICESMONITOR: " + value + ":stopped") + await asyncio.sleep(30) + except ValueError as e: try: await websocket.send('Logtailer-Errormessage: ValueError: {}'.format(e)) @@ -325,6 +339,21 @@ async def view_log(websocket, path): log_close(websocket, path) +def checkIfProcessRunning(processName): + ''' + Check if there is any running process that contains the given name processName. + ''' + #Iterate over the all the running process + for proc in psutil.process_iter(): + try: + # Check if process name contains the given name string. + if processName.lower() in proc.name().lower(): + return True + except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): + pass + return False; + + def log_close(websocket, path, exception=None): message = 'Closed, remote={}, path={}'.format(websocket.remote_address, path) if exception is not None: