mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
docs + #1042
This commit is contained in:
5
.github/workflows/code_checks.yml
vendored
5
.github/workflows/code_checks.yml
vendored
@@ -25,4 +25,9 @@ jobs:
|
|||||||
else
|
else
|
||||||
echo "✅ No absolute path URLs found."
|
echo "✅ No absolute path URLs found."
|
||||||
fi
|
fi
|
||||||
|
- name: Check Python syntax
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
echo "🔍 Checking Python syntax..."
|
||||||
|
find . -name "*.py" -print0 | xargs -0 -n1 python3 -m py_compile
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## High-level overview
|
## High-level overview
|
||||||
|
|
||||||
If a Plugin supplies data to the main app it's doine either vie a SQL query or via a script that updates the `last_result.log` file in the plugin folder (`front/plugins/<plugin>`).
|
If a Plugin supplies data to the main app it's done either vie a SQL query or via a script that updates the `last_result.log` file in the plugin log folder (`app/log/plugins/`).
|
||||||
|
|
||||||
For a more in-depth overview on how plugins work check the [Plugins development docs](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS.md).
|
For a more in-depth overview on how plugins work check the [Plugins development docs](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS.md).
|
||||||
|
|
||||||
|
|||||||
26
docs/LOGGING.md
Executable file
26
docs/LOGGING.md
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
# Logging
|
||||||
|
|
||||||
|
NetAlertX comes with several logs that help to identify application issues.
|
||||||
|
|
||||||
|
For plugin-specific log debugging, please read the [Debug Plugins](./DEBUG_PLUGINS.md) guide.
|
||||||
|
|
||||||
|
When debugging any issue, increase the `LOG_LEVEL` Setting as per the [Debug tips](./DEBUG_TIPS.md) documentation.
|
||||||
|
|
||||||
|
|
||||||
|
## Main logs
|
||||||
|
|
||||||
|
You can find most of the logs exposed in the UI under _Maintenance -> Logs_.
|
||||||
|
|
||||||
|
If the UI is inaccessible, you can access them under `/app/log`.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
In the _Maintennace -> Logs_ you can **Purge logs**, download the full log file or Filter the lines with some substring to narrow down your search.
|
||||||
|
|
||||||
|
## Plugin logging
|
||||||
|
|
||||||
|
If a Plugin supplies data to the main app it's done either vie a SQL query or via a script that updates the `last_result.log` file in the plugin log folder (`app/log/plugins/`). These files are processed at the end of the scan and deleted on successful processing.
|
||||||
|
|
||||||
|
The data is in most of the cases then displayed in the application under _Integrations -> Plugins_ (or _Device -> Plugins_ if the plugin is supplying device-specific data).
|
||||||
|
|
||||||
|

|
||||||
47
docs/NAME_RESOLUTION.md
Executable file
47
docs/NAME_RESOLUTION.md
Executable file
@@ -0,0 +1,47 @@
|
|||||||
|
# NAME RESOLUTION
|
||||||
|
|
||||||
|
Name resolution in NetAlertX relies on multiple plugins to resolve device names from IP addresses. If you are seeing `(name not found)` as device names, follow these steps to diagnose and fix the issue.
|
||||||
|
|
||||||
|
## Required Plugins
|
||||||
|
|
||||||
|
For best results, ensure the following name resolution plugins are enabled:
|
||||||
|
|
||||||
|
- **AVAHISCAN** – Uses mDNS/Avahi to resolve local network names.
|
||||||
|
- **NBTSCAN** – Queries NetBIOS to find device names.
|
||||||
|
- **NSLOOKUP** – Performs standard DNS lookups.
|
||||||
|
|
||||||
|
You can check which plugins are active in your _Settings_ section and enable any that are missing.
|
||||||
|
|
||||||
|
There are other plugins that can supply device names as well, but they rely on bespoke hardware and services. See [Plugins overview](./PLUGINS.md) for details and look for plugins with name discovery (🆎) features.
|
||||||
|
|
||||||
|
## Checking Logs
|
||||||
|
|
||||||
|
If names are not resolving, check the logs for errors or timeouts.
|
||||||
|
|
||||||
|
See how to explore logs in the [Logging guide](./LOGGING.md).
|
||||||
|
|
||||||
|
Logs will show which plugins attempted resolution and any failures encountered.
|
||||||
|
|
||||||
|
## Adjusting Timeout Settings
|
||||||
|
|
||||||
|
If resolution is slow or failing due to timeouts, increase the timeout settings in your configuration, for example.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
NSLOOKUP_RUN_TIMEOUT = 30
|
||||||
|
```
|
||||||
|
|
||||||
|
Raising the timeout may help if your network has high latency or slow DNS responses.
|
||||||
|
|
||||||
|
## Checking Plugin Objects
|
||||||
|
|
||||||
|
Each plugin stores results in its respective object. You can inspect these objects to see if they contain valid name resolution data.
|
||||||
|
|
||||||
|
See [Logging guide](./LOGGING.md) and [Debug plugins](./DEBUG_PLUGINS.md) guides for details.
|
||||||
|
|
||||||
|
If the object contains no results, the issue may be with DNS settings or network access.
|
||||||
|
|
||||||
|
## Improving name resolution
|
||||||
|
|
||||||
|
For more details how to improve name resolution refer to the
|
||||||
|
[Reverse DNS Documentation](./REVERSE_DNS.md).
|
||||||
|
|
||||||
BIN
docs/img/LOGGING/logging_integrations_plugins.png
Executable file
BIN
docs/img/LOGGING/logging_integrations_plugins.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
BIN
docs/img/LOGGING/maintenance_logs.png
Executable file
BIN
docs/img/LOGGING/maintenance_logs.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
BIN
docs/img/NAME_RESOLUTION/name_res_nslookup_timeout.png
Executable file
BIN
docs/img/NAME_RESOLUTION/name_res_nslookup_timeout.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
0
front/php/templates/language/ru_ru.json
Normal file → Executable file
0
front/php/templates/language/ru_ru.json
Normal file → Executable file
@@ -285,16 +285,18 @@ def main():
|
|||||||
mylog("verbose", [f"[{pluginName}] login to omada result is: {omada_login}"])
|
mylog("verbose", [f"[{pluginName}] login to omada result is: {omada_login}"])
|
||||||
|
|
||||||
clients_list = callomada(["-t", "myomada", "clients"])
|
clients_list = callomada(["-t", "myomada", "clients"])
|
||||||
|
client_list_count = clients_list.count("\n")
|
||||||
mylog(
|
mylog(
|
||||||
"verbose",
|
"verbose",
|
||||||
[f'[{pluginName}] clients found:"{clients_list.count("\n")}"\n{clients_list}'],
|
[f'[{pluginName}] clients found:"{client_list_count}"\n{clients_list}'],
|
||||||
)
|
)
|
||||||
|
|
||||||
switches_and_aps = callomada(["-t", "myomada", "devices"])
|
switches_and_aps = callomada(["-t", "myomada", "devices"])
|
||||||
|
switches_and_aps_count = switches_and_aps.count("\n")
|
||||||
mylog(
|
mylog(
|
||||||
"verbose",
|
"verbose",
|
||||||
[
|
[
|
||||||
f'[{pluginName}] omada devices (switches, access points) found:"{switches_and_aps.count("\n")}" \n {switches_and_aps}'
|
f'[{pluginName}] omada devices (switches, access points) found:"{switches_and_aps_count}" \n {switches_and_aps}'
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ nav:
|
|||||||
- Security: SECURITY.md
|
- Security: SECURITY.md
|
||||||
- Advanced guides:
|
- Advanced guides:
|
||||||
- Remote Networks: REMOTE_NETWORKS.md
|
- Remote Networks: REMOTE_NETWORKS.md
|
||||||
- Notifications Guide: NOTIFICATIONS.md
|
- Notifications Guide: NOTIFICATIONS.md
|
||||||
|
- Name Resolution: NAME_RESOLUTION.md
|
||||||
- Authelia: AUTHELIA.md
|
- Authelia: AUTHELIA.md
|
||||||
- Performance: PERFORMANCE.md
|
- Performance: PERFORMANCE.md
|
||||||
- Reverse DNS: REVERSE_DNS.md
|
- Reverse DNS: REVERSE_DNS.md
|
||||||
@@ -57,6 +58,7 @@ nav:
|
|||||||
- Icons: ICONS.md
|
- Icons: ICONS.md
|
||||||
- Network Topology: NETWORK_TREE.md
|
- Network Topology: NETWORK_TREE.md
|
||||||
- Troubleshooting:
|
- Troubleshooting:
|
||||||
|
- Inspecting Logs: LOGGING.md
|
||||||
- Debugging Tips: DEBUG_TIPS.md
|
- Debugging Tips: DEBUG_TIPS.md
|
||||||
- Debugging Invalid JSON: DEBUG_INVALID_JSON.md
|
- Debugging Invalid JSON: DEBUG_INVALID_JSON.md
|
||||||
- Debugging Plugins: DEBUG_PLUGINS.md
|
- Debugging Plugins: DEBUG_PLUGINS.md
|
||||||
|
|||||||
@@ -50,23 +50,24 @@ class WorkflowManager:
|
|||||||
def process_event(self, event):
|
def process_event(self, event):
|
||||||
"""Process the events. Check if events match a workflow trigger"""
|
"""Process the events. Check if events match a workflow trigger"""
|
||||||
|
|
||||||
guid = event["GUID"]
|
evGuid = event["GUID"]
|
||||||
mylog('verbose', [f"[WF] Processing event with GUID {guid}"])
|
|
||||||
|
mylog('verbose', [f"[WF] Processing event with GUID {evGuid}"])
|
||||||
|
|
||||||
# Check if the trigger conditions match
|
# Check if the trigger conditions match
|
||||||
for workflow in self.workflows:
|
for workflow in self.workflows:
|
||||||
|
|
||||||
# Ensure workflow is enabled before proceeding
|
# Ensure workflow is enabled before proceeding
|
||||||
if workflow.get("enabled", "No").lower() == "yes":
|
if workflow.get("enabled", "No").lower() == "yes":
|
||||||
|
wfName = workflow["name"]
|
||||||
mylog('debug', [f"[WF] Checking if '{event["GUID"]}' triggers the workflow '{workflow["name"]}'"])
|
mylog('debug', [f"[WF] Checking if '{evGuid}' triggers the workflow '{wfName}'"])
|
||||||
|
|
||||||
# construct trigger object which also evaluates if the current event triggers it
|
# construct trigger object which also evaluates if the current event triggers it
|
||||||
trigger = Trigger(workflow["trigger"], event, self.db)
|
trigger = Trigger(workflow["trigger"], event, self.db)
|
||||||
|
|
||||||
if trigger.triggered:
|
if trigger.triggered:
|
||||||
|
|
||||||
mylog('verbose', [f"[WF] Event with GUID '{event["GUID"]}' triggered the workflow '{workflow["name"]}'"])
|
mylog('verbose', [f"[WF] Event with GUID '{evGuid}' triggered the workflow '{wfName}'"])
|
||||||
|
|
||||||
self.execute_workflow(workflow, trigger)
|
self.execute_workflow(workflow, trigger)
|
||||||
|
|
||||||
@@ -83,6 +84,8 @@ class WorkflowManager:
|
|||||||
def execute_workflow(self, workflow, trigger):
|
def execute_workflow(self, workflow, trigger):
|
||||||
"""Execute the actions in the given workflow if conditions are met."""
|
"""Execute the actions in the given workflow if conditions are met."""
|
||||||
|
|
||||||
|
wfName = workflow["name"]
|
||||||
|
|
||||||
# Ensure conditions exist
|
# Ensure conditions exist
|
||||||
if not isinstance(workflow.get("conditions"), list):
|
if not isinstance(workflow.get("conditions"), list):
|
||||||
m = f"[WF] workflow['conditions'] must be a list"
|
m = f"[WF] workflow['conditions'] must be a list"
|
||||||
@@ -96,7 +99,7 @@ class WorkflowManager:
|
|||||||
|
|
||||||
if evaluator.evaluate(trigger): # If any group evaluates to True
|
if evaluator.evaluate(trigger): # If any group evaluates to True
|
||||||
|
|
||||||
mylog('none', [f"[WF] Workflow {workflow["name"]} will be executed - conditions were evaluated as TRUE"])
|
mylog('none', [f"[WF] Workflow {wfName} will be executed - conditions were evaluated as TRUE"])
|
||||||
mylog('debug', [f"[WF] Workflow condition_group: {condition_group}"])
|
mylog('debug', [f"[WF] Workflow condition_group: {condition_group}"])
|
||||||
|
|
||||||
self.execute_actions(workflow["actions"], trigger)
|
self.execute_actions(workflow["actions"], trigger)
|
||||||
|
|||||||
Reference in New Issue
Block a user