diff --git a/docs/DEBUG_PLUGINS.md b/docs/DEBUG_PLUGINS.md index cd134841..947eee0d 100755 --- a/docs/DEBUG_PLUGINS.md +++ b/docs/DEBUG_PLUGINS.md @@ -1,7 +1,7 @@ # Troubleshooting plugins > [!TIP] -> Before troubleshooting, please ensure you have the right [Debugging and LOG_LEVEL set](./DEBUG_TIPS.md). +> Before troubleshooting, please ensure you have the right [Debugging and LOG_LEVEL set](./DEBUG_TIPS.md) in Settings. ## High-level overview @@ -22,10 +22,25 @@ For a more in-depth overview on how plugins work check the [Plugins development #### Incorrect input data -Input data from the plugin might cause mapping issues in specific edge cases. Look for a corresponding section in the `app.log` file, for example notice the first line of the execution run of the `PIHOLE` plugin below: +Input data from the plugin might cause mapping issues in specific edge cases. Look for a corresponding section in the `app.log` file, and search for `[Scheduler] run for PLUGINNAME: YES`, so for ICMP you would look for `[Scheduler] run for ICMP: YES`. You can find examples of useful logs below. If your issue is related to a plugin, and you don't include a log section with this data, we can't help you to resolve your issue. + +##### ICMP log example ``` -17:31:05 [Scheduler] - Scheduler run for PIHOLE: YES +20:39:04 [Scheduler] run for ICMP: YES +20:39:04 [ICMP] fping skipping 192.168.1.124 : [2], timed out (NaN avg, 100% loss) +20:39:04 [ICMP] adding 192.168.1.123 from 192.168.1.123 : [2], 64 bytes, 20.1 ms (8.22 avg, 0% loss) +20:39:04 [ICMP] fping skipping 192.168.1.157 : [1], timed out (NaN avg, 100% loss) +20:39:04 [ICMP] adding 192.168.1.79 from 192.168.1.79 : [2], 64 bytes, 48.3 ms (60.9 avg, 0% loss) +20:39:04 [ICMP] fping skipping 192.168.1.128 : [2], timed out (NaN avg, 100% loss) +20:39:04 [ICMP] fping skipping 192.168.1.129 : [2], timed out (NaN avg, 100% loss) +``` + + +##### PIHOLE log example + +``` +17:31:05 [Scheduler] run for PIHOLE: YES 17:31:05 [Plugin utils] --------------------------------------------- 17:31:05 [Plugin utils] display_name: PiHole (Device sync) 17:31:05 [Plugins] CMD: SELECT n.hwaddr AS Object_PrimaryID, {s-quote}null{s-quote} AS Object_SecondaryID, datetime() AS DateTime, na.ip AS Watched_Value1, n.lastQuery AS Watched_Value2, na.name AS Watched_Value3, n.macVendor AS Watched_Value4, {s-quote}null{s-quote} AS Extra, n.hwaddr AS ForeignKey FROM EXTERNAL_PIHOLE.Network AS n LEFT JOIN EXTERNAL_PIHOLE.Network_Addresses AS na ON na.network_id = n.id WHERE n.hwaddr NOT LIKE {s-quote}ip-%{s-quote} AND n.hwaddr is not {s-quote}00:00:00:00:00:00{s-quote} AND na.ip is not null @@ -60,7 +75,7 @@ Input data from the plugin might cause mapping issues in specific edge cases. Lo 17:31:05 [API] Update API starting 17:31:06 [API] Updating table_plugins_history.json file in /api ``` - +> [!NOTE] > The debug output between the 🔻red arrows🔺 is important for debugging (arrows added only to highlight the section on this page, they are not available in the actual debug log) In the above output notice the section logging how many events are produced by the plugin: @@ -80,12 +95,11 @@ These values, if formatted correctly, will also show up in the UI: ![Plugins table](./img/DEBUG_PLUGINS/plugin_objects_pihole.png) - ### Sharing application state Sometimes specific log sections are needed to debug issues. The Devices and CurrentScan table data is sometimes needed to figure out what's wrong. -1. Please set `LOG_LEVEL` to `trace` (Disable it once you have the info as this produces big log files). +1. Please set `LOG_LEVEL` to `trace` in the Settings (Disable it once you have the info as this produces big log files). 2. Wait for the issue to occur. 3. Search for `================ DEVICES table content ================` in your logs. 4. Search for `================ CurrentScan table content ================` in your logs. diff --git a/docs/FIX_OFFLINE_DETECTION.md b/docs/FIX_OFFLINE_DETECTION.md index bbfb0d3f..9bc69dcd 100755 --- a/docs/FIX_OFFLINE_DETECTION.md +++ b/docs/FIX_OFFLINE_DETECTION.md @@ -42,7 +42,9 @@ ARPSCAN_DURATION=30 ### ✅ Add ICMP (Ping) Scanning -Enable the `ICMP` scan plugin to complement ARP detection. ICMP is often more reliable for detecting active hosts, especially when ARP fails. +Enable the `ICMP` scan plugin to complement ARP detection. ICMP is often more reliable for detecting active hosts, especially when ARP fails. + +> [!IMPORTANT] If using AdGuard/Pi-hole: If devices still show offline after enabling ICMP, temporarily disable your content blocker. If the issue disappears, whitelist the NetAlertX host IP in your blocker's settings to prevent pings from being dropped. ### ✅ Use Multiple Detection Methods @@ -52,7 +54,7 @@ A combined approach greatly improves detection robustness: * `ICMP` (ping) * `NMAPDEV` (nmap) -This hybrid strategy increases reliability, especially for down detection and alerting. See [other plugins](./PLUGINS.md) that might be compatible with your setup. See benefits and drawbacks of individual scan methods in their respective docs. +This hybrid strategy increases reliability, especially for down detection and alerting. See [other plugins](./PLUGINS.md) that might be compatible with your setup. See benefits and drawbacks of individual scan methods in their respective docs. ## Results @@ -76,4 +78,4 @@ After increasing the ARP timeout and adding ICMP scanning (on select IP ranges), Let us know in the [NetAlertX Discussions](https://github.com/jokob-sk/NetAlertX/discussions) if you have further feedback or edge cases. -See also [Remote Networks](./REMOTE_NETWORKS.md) for more advanced setups. \ No newline at end of file +See also [Remote Networks](./REMOTE_NETWORKS.md) for more advanced setups. \ No newline at end of file diff --git a/front/devices.php b/front/devices.php index a9ccce6c..f6c374b1 100755 --- a/front/devices.php +++ b/front/devices.php @@ -57,7 +57,7 @@
- + close();
-
"> - ' .lang('Maintenance_new_version').''.'' .lang('Maintenance_current_version').'';?> +
+ + + +
- +
- +
diff --git a/front/php/templates/build.php b/front/php/templates/build.php deleted file mode 100755 index ed352c38..00000000 --- a/front/php/templates/build.php +++ /dev/null @@ -1,21 +0,0 @@ - diff --git a/front/php/templates/footer.php b/front/php/templates/footer.php index 763859da..5b4058e9 100755 --- a/front/php/templates/footer.php +++ b/front/php/templates/footer.php @@ -32,8 +32,8 @@ | | | - | : - | Version: + | : + | Version: |
diff --git a/server/api_server/api_server_start.py b/server/api_server/api_server_start.py index eefdb77a..eb330dbe 100755 --- a/server/api_server/api_server_start.py +++ b/server/api_server/api_server_start.py @@ -13,7 +13,7 @@ INSTALL_PATH = os.getenv("NETALERTX_APP", "/app") sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"]) from logger import mylog # noqa: E402 [flake8 lint suppression] -from helper import get_setting_value, get_env_setting_value # noqa: E402 [flake8 lint suppression] +from helper import get_setting_value, get_env_setting_value, getBuildTimeStampAndVersion # noqa: E402 [flake8 lint suppression] from db.db_helper import get_date_from_period # noqa: E402 [flake8 lint suppression] from app_state import updateState # noqa: E402 [flake8 lint suppression] @@ -1809,6 +1809,9 @@ def start_server(graphql_port, app_state): ) thread.start() + # Pass Application "VERSION" into the app_state + buildTimestamp, newBuildVersion = getBuildTimeStampAndVersion() + # Update the state to indicate the server has started app_state = updateState("Process: Idle", None, None, None, 1) diff --git a/server/app_state.py b/server/app_state.py index 4a74ee30..1f59c219 100755 --- a/server/app_state.py +++ b/server/app_state.py @@ -42,7 +42,8 @@ class app_state_class: graphQLServerStarted=0, processScan=False, pluginsStates=None, - appVersion=None + appVersion=None, + buildTimestamp=None ): """ Initialize the application state, optionally overwriting previous values. @@ -59,6 +60,7 @@ class app_state_class: processScan (bool, optional): Initial processScan flag. pluginsStates (dict, optional): Initial plugin states to merge with previous state. appVersion (str, optional): Application version. + buildTimestamp (str, optional): ABuild timestamp. """ # json file containing the state to communicate with the frontend stateFile = apiPath + "app_state.json" @@ -86,6 +88,7 @@ class app_state_class: self.currentState = previousState.get("currentState", "Init") self.pluginsStates = previousState.get("pluginsStates", {}) self.appVersion = previousState.get("appVersion", "") + self.buildTimestamp = previousState.get("buildTimestamp", "") else: # init first time values self.settingsSaved = 0 self.settingsImported = 0 @@ -97,6 +100,7 @@ class app_state_class: self.currentState = "Init" self.pluginsStates = {} self.appVersion = "" + self.buildTimestamp = "" # Overwrite with provided parameters if supplied if settingsSaved is not None: @@ -127,6 +131,8 @@ class app_state_class: self.pluginsStates[plugin] = state if appVersion is not None: self.appVersion = appVersion + if buildTimestamp is not None: + self.buildTimestamp = buildTimestamp # check for new version every hour and if currently not running new version if self.isNewVersion is False and self.isNewVersionChecked + 3600 < int( timeNow().timestamp() @@ -154,7 +160,13 @@ class app_state_class: # Broadcast state change via SSE if available try: - broadcast_state_update(self.currentState, self.settingsImported, timestamp=self.lastUpdated) + broadcast_state_update( + self.currentState, + self.settingsImported, + timestamp=self.lastUpdated, + appVersion=self.appVersion, + buildTimestamp=self.buildTimestamp + ) except Exception as e: mylog("none", [f"[app_state] SSE broadcast: {e}"]) @@ -170,7 +182,8 @@ def updateState(newState = None, graphQLServerStarted = None, processScan = None, pluginsStates=None, - appVersion=None): + appVersion=None, + buildTimestamp=None): """ Convenience method to create or update the app state. @@ -183,6 +196,7 @@ def updateState(newState = None, processScan (bool, optional): Flag indicating if a scan is active. pluginsStates (dict, optional): Plugin state updates. appVersion (str, optional): Application version. + buildTimestamp (str, optional): Build timestamp. Returns: app_state_class: Updated state object. @@ -195,7 +209,8 @@ def updateState(newState = None, graphQLServerStarted, processScan, pluginsStates, - appVersion + appVersion, + buildTimestamp ) diff --git a/server/initialise.py b/server/initialise.py index 1c6f52aa..f111ced0 100755 --- a/server/initialise.py +++ b/server/initialise.py @@ -715,7 +715,7 @@ def importConfigs(pm, db, all_plugins): # settingsImported = None (timestamp), # showSpinner = False (1/0), # graphQLServerStarted = 1 (1/0)) - updateState("Config imported", conf.lastImportedConfFile, conf.lastImportedConfFile, False, 1, None, None, new_version) + updateState("Config imported", conf.lastImportedConfFile, conf.lastImportedConfFile, False, 1, None, None, new_version, buildTimestamp) msg = '[Config] Imported new settings config' mylog('minimal', msg)