This commit implements the unified checks architecture that consolidates SNMP monitoring with HTTP/TCP/DNS checks under a single "check" abstraction, enabling consistent graphing, alerting, and management across all check types. Database Changes: - Add source_type and source_id to checks table for tracking auto-discovered vs manually created checks - Add value field to check_results for storing numeric sensor readings - Maintain backward compatibility with existing check_results data New SNMP Executors: - SnmpSensorExecutor: Poll sensor OIDs and return formatted values with status determination (OK/WARNING/CRITICAL based on limits) - SnmpInterfaceExecutor: Poll interface stats (bandwidth, packets, errors) - SnmpProcessorExecutor: Poll CPU/processor usage - SnmpStorageExecutor: Poll disk/memory usage with percentage calculations Check Execution Worker: - CheckExecutorWorker: Unified Oban worker that dispatches to appropriate executor based on check_type (snmp_sensor, snmp_interface, http, tcp, etc.) - Self-schedules next execution with distributed polling offsets - Records results in check_results TimescaleDB hypertable - Updates check state (OK/WARNING/CRITICAL/UNKNOWN) Discovery Integration: - Auto-creates checks during SNMP discovery for sensors, interfaces, processors, and storage - Links checks to source entities via source_id for data lookup - Enables/disables checks based on discovery results UI Enhancements: - Checks tab on device detail page with grouped display - FormComponent for adding manual HTTP/TCP/DNS checks - Empty state with "Run Discovery" prompt - Check status badges and last checked times Graphing: - Update GraphLive to accept check_id parameter - Query check_results table for time-series data - Support all check types (SNMP, HTTP response times, etc.) Testing: - Comprehensive test suite for SnmpSensorExecutor (5 tests) - Test suite for CheckExecutorWorker (7 tests) - Test coverage for discovery check creation (6 tests) - Remove deprecated monitoring_test.exs testing old API Bug Fixes: - Fix SNMP executors reading credentials from correct Device schema fields (device.snmp_version instead of device.snmp_device.version) - Update agent channel test to query MonitoringCheck table directly Code Quality: - Extract add_snmp_credentials helper to reduce cyclomatic complexity - Use map-based lookups for sensor formatting and check type grouping - Apply pattern matching in dispatcher to reduce complexity - All credo checks passing with no issues Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
694 lines
45 KiB
Text
694 lines
45 KiB
Text
2026-02-12
|
|
docs: add Terraform provider documentation to public API docs
|
|
- Added comprehensive Terraform provider section to /docs/api page with navigation link
|
|
- Documented what Terraform is and how it integrates with Towerops API
|
|
- Included getting started guide, installation instructions, and example usage
|
|
- Added links to Terraform Registry documentation and GitHub repository
|
|
- Covers towerops_site and towerops_device resources with full examples
|
|
- Files: lib/towerops_web/controllers/api_docs_html/index.html.heex
|
|
|
|
2026-02-12
|
|
test: comprehensive test suite for unified checks system (Phase 4)
|
|
- Added SnmpSensorExecutor tests covering standardized response format, status codes,
|
|
limit-based thresholds, error handling, and Mox-based SNMP mocking
|
|
- Added CheckExecutorWorker tests for dispatcher routing, result recording, scheduling,
|
|
error handling, and check state management
|
|
- Verified create_checks_from_discovery integration with 6 comprehensive tests
|
|
- Verified graphing function (get_check_graph_data) handles both check_results and
|
|
legacy snmp_sensor_readings tables correctly - All 141 monitoring and SNMP tests passing
|
|
- Files: test/towerops/monitoring/executors/snmp_sensor_executor_test.exs,
|
|
test/towerops/workers/check_executor_worker_test.exs, test/towerops/snmp_test.exs
|
|
|
|
2026-02-12
|
|
fix: SNMP executor build_snmp_opts reading from wrong schema fields
|
|
- Fixed SnmpSensorExecutor, SnmpInterfaceExecutor, SnmpProcessorExecutor, and
|
|
SnmpStorageExecutor to read SNMP credentials from device.snmp_version,
|
|
device.snmp_community, device.snmpv3_* instead of incorrectly accessing
|
|
device.snmp_device.version (which doesn't exist on Snmp.Device schema)
|
|
- Issue discovered via TDD while writing comprehensive executor tests
|
|
- All executors now correctly build SNMP connection options matching the
|
|
pattern used by Snmp.Poller.build_client_opts/1
|
|
- Files: lib/towerops/monitoring/executors/snmp_sensor_executor.ex,
|
|
lib/towerops/monitoring/executors/snmp_interface_executor.ex,
|
|
lib/towerops/monitoring/executors/snmp_processor_executor.ex,
|
|
lib/towerops/monitoring/executors/snmp_storage_executor.ex,
|
|
test/towerops/monitoring/executors/snmp_sensor_executor_test.exs
|
|
- Removed outdated test/towerops/monitoring/check_test.exs (was testing CheckResult
|
|
fields on Check schema)
|
|
|
|
2026-02-12
|
|
feat: unified checks system for SNMP and service monitoring
|
|
- Implemented comprehensive unified checks architecture combining SNMP auto-discovery
|
|
with manual HTTP/TCP/DNS service checks
|
|
- Database: Added source_type and source_id fields to checks table, created check_results
|
|
TimescaleDB hypertable for unified time-series storage
|
|
- SNMP Executors: Created SnmpSensorExecutor, SnmpInterfaceExecutor, SnmpProcessorExecutor,
|
|
SnmpStorageExecutor with standardized {:ok, %{value:, status:, output:, response_time_ms:}} format
|
|
- Workers: Implemented CheckExecutorWorker with dispatcher pattern, replacing device-specific
|
|
polling for SNMP checks
|
|
- Discovery Integration: SNMP discovery now auto-creates checks for all sensors, interfaces,
|
|
processors, and storage with source tracking
|
|
- UI: Added checks tab to device detail page with grouped display, status badges, empty state,
|
|
and manual check creation modal
|
|
- Check Form: Built CheckLive.FormComponent modal for adding HTTP/TCP/DNS checks with
|
|
dynamic fields based on check type
|
|
- Graphing: Updated GraphLive.Show to support check-based graphs, query both check_results
|
|
and legacy snmp_sensor_readings tables for seamless historical data
|
|
- Testing: Added comprehensive test suite for create_checks_from_discovery covering sensors,
|
|
interfaces, processors, storage, and Oban job scheduling
|
|
- Files: lib/towerops/monitoring.ex, lib/towerops/snmp.ex,
|
|
lib/towerops/monitoring/executors/*.ex, lib/towerops/workers/check_executor_worker.ex,
|
|
lib/towerops_web/live/device_live/show.ex, lib/towerops_web/live/check_live/form_component.ex,
|
|
lib/towerops_web/live/graph_live/show.ex, lib/towerops_web/router.ex,
|
|
priv/repo/migrations/*_add_source_fields_to_checks.exs,
|
|
priv/repo/migrations/*_add_value_to_check_results.exs,
|
|
test/towerops/snmp_test.exs
|
|
|
|
2026-02-12
|
|
fix: prevent AlreadySentError in BruteForceProtection plug
|
|
- Fixed production exception where the plug attempted to register a before_send
|
|
callback after already sending a 403 response to banned IPs
|
|
- Modified call/2 to check conn.halted before calling maybe_track_404/2
|
|
- Updated test to verify proper behavior without AlreadySentError workaround
|
|
- Files: lib/towerops_web/plugs/brute_force_protection.ex,
|
|
test/towerops_web/plugs/brute_force_protection_test.exs
|
|
|
|
CHANGELOG - towerops-web
|
|
========================
|
|
|
|
2026-02-12 - fix: reload device stream when switching back to existing devices tab
|
|
- File: lib/towerops_web/live/device_live/index.ex (apply_action/4)
|
|
Fixed 60-second delay when navigating from "discovered devices" tab back to "existing devices" tab.
|
|
The device stream existed in LiveView assigns from mount/3, but when the DOM element with
|
|
phx-update="stream" was removed (viewing discovered tab) and re-added (switching back), LiveView
|
|
didn't automatically re-render the stream data. Users had to wait for the next PubSub update
|
|
(device_status_changed) or periodic :tick event (every 15 seconds) to trigger reload_device_stream,
|
|
which could take 60+ seconds.
|
|
|
|
Fix: Explicitly reload the device stream when switching to "existing" tab by calling
|
|
list_organization_devices and stream(:device_rows, build_device_rows(devices), reset: true),
|
|
matching the pattern used when loading the discovered tab. Now the table appears instantly.
|
|
|
|
2026-02-12 - fix: suppress benign shutdown errors during K8s pod rollouts
|
|
- Files: lib/towerops/honeybadger_notice_filter.ex, lib/towerops/honeybadger_filter.ex,
|
|
lib/towerops/logger_filters.ex, config/config.exs, config/runtime.exs,
|
|
lib/towerops/application.ex, test/towerops/honeybadger_notice_filter_test.exs,
|
|
test/towerops/honeybadger_filter_test.exs, test/towerops/logger_filters_test.exs
|
|
|
|
Filter port_died and write_failed/epipe errors from Honeybadger reports, email notifications,
|
|
and logger output. These are benign artifacts of BEAM shutdown inside containers. Added
|
|
shutdown_error? guard in HoneybadgerNoticeFilter (returns nil to drop notice entirely),
|
|
port_died matching in HoneybadgerFilter's normal_shutdown?, and drop_shutdown_errors logger
|
|
filter. Reordered supervision tree so Oban starts after SnmpKit/TaskSupervisor, ensuring
|
|
it shuts down first and can drain in-flight jobs. Added 40s Oban shutdown_grace_period
|
|
in production config.
|
|
|
|
2026-02-12 - feat: email raw stacktrace on every Honeybadger exception
|
|
- Files: lib/towerops/honeybadger_notice_filter.ex, config/config.exs,
|
|
test/towerops/honeybadger_notice_filter_test.exs
|
|
|
|
Added a Honeybadger NoticeFilter that sends an email with the full error class, message,
|
|
stacktrace, and server environment info to graham@mcintire.me whenever an exception is
|
|
reported. The notice passes through unchanged so Honeybadger still receives it. Uses the
|
|
existing Swoosh mailer (Amazon SES in production, local adapter in dev).
|
|
|
|
2026-02-12 - perf: performance improvements for scale (batch inserts, indexes, selective reloading)
|
|
- Files: lib/towerops/snmp.ex, lib/towerops/devices.ex, lib/towerops_web/channels/agent_channel.ex,
|
|
lib/towerops/workers/device_poller_worker.ex, lib/towerops_web/live/dashboard_live.ex,
|
|
lib/towerops_web/live/device_live/show.ex, lib/towerops_web/live/device_live/index.ex,
|
|
lib/towerops/agents.ex, priv/repo/migrations/20260212155105_add_performance_indexes.exs
|
|
|
|
Phase 1: Batch data ingestion - replaced individual Repo.insert() calls with Repo.insert_all()
|
|
for sensor readings, interface stats, processor readings, and storage readings in both
|
|
agent_channel.ex and device_poller_worker.ex. Added create_*_batch/1 functions to snmp.ex.
|
|
|
|
Phase 2: Database indexes - added partial indexes for monitored sensors/interfaces,
|
|
composite index for devices org+status, partial index for active alerts.
|
|
|
|
Phase 3: Dashboard aggregation - replaced loading all devices into memory with
|
|
Devices.get_device_status_counts/1 GROUP BY query.
|
|
|
|
Phase 4: DeviceLive.Show selective updates - split monolithic load_equipment_data into
|
|
tab-specific loaders (base, tab_nav, overview, ports, logs, backups). PubSub handlers
|
|
now only reload data relevant to the active tab.
|
|
|
|
Phase 5: DeviceLive.Index incremental updates - separated structural changes (create/delete)
|
|
from status changes. Added debouncing for rapid status changes. Skip reload when viewing
|
|
discovered tab.
|
|
|
|
Phase 6: Agent polling memory optimization - filtered preloads in list_agent_polling_targets
|
|
to only load monitored sensors and interfaces instead of all.
|
|
|
|
2026-02-12 - feat: complete WISP vendor coverage (ePMP, Raisecom, Netonix)
|
|
- Files: priv/profiles/os_discovery/epmp.yaml (enhanced), lib/towerops/snmp/profiles/vendors/raisecom.ex (new)
|
|
Completed LibreNMS parity for major WISP equipment vendors. Three improvements:
|
|
|
|
(1) Consolidated ePMP YAML profiles - merged cambium-epmp.yaml enhancements into epmp.yaml
|
|
(added GPS satellite count sensors, proper state_name fields, better field naming), deleted
|
|
duplicate file. ePMP now discovers 11 sensors via YAML + 4 wireless sensors via vendor module.
|
|
|
|
(2) Implemented Raisecom vendor module - fills major 0% coverage gap for Asia-Pacific WISP market.
|
|
Hardware detection via RAISECOM-SYSTEM-MIB with sysDescr fallback. Sensor discovery handled by
|
|
existing YAML (raisecom.yaml, raisecom-ros.yaml) covering 15+ sensors: CPU, memory pools, fan
|
|
speed/state, voltage with thresholds, power supply state, config load state. 8 comprehensive
|
|
tests all passing.
|
|
|
|
(3) Verified Netonix coverage - YAML profile matches LibreNMS 100% (PoE status, voltage,
|
|
temperature, fan, power, current). Vendor module provides additional scalar sensors beyond
|
|
LibreNMS baseline. Netonix coverage exceeds LibreNMS.
|
|
|
|
Tarana investigated: No SNMP support in LibreNMS (newer vendor, likely cloud-managed), would
|
|
require vendor MIBs and documentation to implement.
|
|
|
|
2026-02-12 - test: fix Cambium ePMP test Mox expectations
|
|
- File: test/towerops/snmp/profiles/vendors/cambium_test.exs
|
|
Changed expect() to stub() in all discover_wireless_sensors/1 tests to handle multiple SNMP
|
|
get calls. The implementation makes several calls: static sensor fetch (CPU), ePMP mode
|
|
detection (wirelessInterfaceMode OID), and individual sensor value fetches (RSSI, SNR,
|
|
Frequency, Clients). Using stub() allows unlimited calls vs expect() which enforces exactly
|
|
one call, fixing Mox.UnexpectedCallError in all 7 ePMP-related test cases. All 13 Cambium
|
|
tests now pass correctly.
|
|
|
|
2026-02-12 - fix: sync modal state to URL for browser back/forward navigation
|
|
- Files: lib/towerops_web/live/user_settings_live.ex, lib/towerops_web/live/agent_live/index.ex
|
|
Fixed browser back/forward button navigation by syncing modal state to URL parameters.
|
|
Implemented idiomatic Phoenix LiveView pattern using push_patch/2 and handle_params/3.
|
|
|
|
**UserSettingsLive (6 modals):**
|
|
- add_token, token_created, revoke_all, add_device, device_qr, recovery_codes
|
|
- Updated handle_params/3 to read ?modal= param and set all modal states
|
|
- Added build_settings_path/2 helper to preserve tab and page params
|
|
- Updated all show/close handlers to use push_patch instead of assign
|
|
|
|
**AgentLive.Index (1 modal):**
|
|
- setup modal (displays agent token after creation)
|
|
- Updated handle_params/3 to read ?modal=setup param
|
|
- Updated show_setup and close_token_modal handlers to use push_patch
|
|
|
|
**Result:** Browser back button now closes modals without navigating away from page.
|
|
URLs are bookmarkable and restore exact modal state. Tab and pagination state preserved.
|
|
|
|
**Documentation:** Updated CLAUDE.md with comprehensive browser navigation patterns.
|
|
Created design document: docs/plans/2026-02-12-browser-navigation-fix-design.md
|
|
|
|
2026-02-12 - feat: add comprehensive MikroTik wireless sensor discovery (11 sensor types across 4 MIB tables)
|
|
- Files: lib/towerops/snmp/profiles/vendors/mikrotik.ex (enhanced)
|
|
Implemented TIER 4 LARGE priority wireless sensor discovery for MikroTik RouterOS devices.
|
|
Achieves 100% LibreNMS parity for wireless monitoring (0% → 100% coverage).
|
|
Discovers 11 sensor types across 4 MIB tables:
|
|
|
|
**AP Sensors (mtxrWlApTable .1.3.6.1.4.1.14988.1.1.1.3):**
|
|
- Clients: Station count per AP interface
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.3.1.6 (mtxrWlApClientCount)
|
|
- CCQ: Connection quality percentage (skips when clients>0 && CCQ=0 for NV2)
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.3.1.10 (mtxrWlApOverallTxCCQ)
|
|
- Frequency: Operating frequency in MHz (skips if 0)
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.3.1.7 (mtxrWlApFreq)
|
|
- Noise Floor: Background noise level in dBm
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.3.1.9 (mtxrWlApNoiseFloor)
|
|
- TX Rate: Transmit data rate in bps
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.3.1.2 (mtxrWlApTxRate)
|
|
- RX Rate: Receive data rate in bps
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.3.1.3 (mtxrWlApRxRate)
|
|
|
|
**Station Sensors (mtxrWlStatTable .1.3.6.1.4.1.14988.1.1.1.1):**
|
|
- TX CCQ: Transmit connection quality percentage
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.1.1.9 (mtxrWlStatTxCCQ)
|
|
- RX CCQ: Receive connection quality percentage
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.1.1.10 (mtxrWlStatRxCCQ)
|
|
- Frequency: Operating frequency in MHz
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.1.1.7 (mtxrWlStatFreq)
|
|
- TX Rate: Transmit data rate in bps
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.1.1.2 (mtxrWlStatTxRate)
|
|
- RX Rate: Receive data rate in bps
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.1.1.3 (mtxrWlStatRxRate)
|
|
|
|
**60GHz Sensors (mtxrWl60GTable .1.3.6.1.4.1.14988.1.1.1.8):**
|
|
- Frequency: Operating frequency in MHz
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.8.1.6 (mtxrWl60GFreq)
|
|
- RSSI: Received signal strength in dBm
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.8.1.12 (mtxrWl60GRssi)
|
|
- Quality: Signal quality percentage
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.8.1.8 (mtxrWl60GSignal)
|
|
- PHY Rate: Physical layer rate in bps (divisor: 1,000,000)
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.8.1.13 (mtxrWl60GPhyRate)
|
|
|
|
**60GHz Station Sensors (mtxrWl60GStaTable .1.3.6.1.4.1.14988.1.1.1.9):**
|
|
- Distance: Link distance in km (divisor: 100,000)
|
|
OID: .1.3.6.1.4.1.14988.1.1.1.9.1.10 (mtxrWl60GStaDistance)
|
|
|
|
**LTE Modem Sensors (mtxrLTEModemTable .1.3.6.1.4.1.14988.1.1.16.1):**
|
|
- RSRQ: Reference Signal Received Quality in dB
|
|
OID: .1.3.6.1.4.1.14988.1.1.16.1.1.3 (mtxrLTEModemSignalRSRQ)
|
|
- RSRP: Reference Signal Received Power in dBm
|
|
OID: .1.3.6.1.4.1.14988.1.1.16.1.1.4 (mtxrLTEModemSignalRSRP)
|
|
- SINR: Signal-to-Interference-plus-Noise Ratio in dB
|
|
OID: .1.3.6.1.4.1.14988.1.1.16.1.1.7 (mtxrLTEModemSignalSINR)
|
|
|
|
- Implementation Details:
|
|
- discover_wireless_sensors/1: Calls 5 table-specific discovery functions
|
|
- discover_ap_sensors/1: Walks mtxrWlApTable, builds client/CCQ/freq/noise/rate sensors
|
|
- discover_stat_sensors/1: Walks mtxrWlStatTable, builds TX/RX CCQ and rate sensors
|
|
- discover_60g_sensors/1: Walks mtxrWl60GTable, builds 60GHz sensors
|
|
- discover_60g_sta_sensors/1: Walks mtxrWl60GStaTable, builds distance sensors
|
|
- discover_lte_sensors/1: Walks mtxrLTEModemTable, builds LTE signal sensors
|
|
- group_by_index/1: Groups SNMP walk results by interface index (last OID component)
|
|
- freq_to_label/2: Extracts frequency band label (2437 → "2G", 5180 → "5G")
|
|
- to_integer/1: Safe conversion handling both string and integer SNMP values
|
|
|
|
- Smart Skip Logic (matching LibreNMS):
|
|
- CCQ skipped when clients > 0 but CCQ = 0 (NV2 mode reports clients but no CCQ)
|
|
- Frequency skipped if value is 0
|
|
- TX/RX rate skipped if both are 0
|
|
- Empty CCQ sensors skipped (both TX and RX = 0)
|
|
|
|
- Files: test/towerops/snmp/profiles/vendors/mikrotik_test.exs (enhanced)
|
|
Added comprehensive test coverage with 13 test cases:
|
|
- Tests AP sensor discovery (7 sensors: clients, CCQ, freq, noise, TX/RX rate)
|
|
- Tests station sensor discovery (6 sensors: TX/RX CCQ, freq, TX/RX rate)
|
|
- Tests 60GHz sensor discovery (4 sensors: freq, RSSI, quality, PHY rate)
|
|
- Tests 60GHz station sensor discovery (1 sensor: distance)
|
|
- Tests LTE modem sensor discovery (3 sensors: RSRQ, RSRP, SINR)
|
|
- Tests skip logic for sensors with no data
|
|
- Tests graceful handling when SNMP tables are empty
|
|
All 13 tests passing with Mox-based SNMP adapter mocking.
|
|
|
|
- Impact: Complete wireless monitoring for MikroTik RouterOS devices including
|
|
standard Wi-Fi (2.4/5GHz), 60GHz point-to-point links, and LTE modems.
|
|
Enables detection of connection quality issues, frequency changes, link
|
|
distance problems, and cellular signal degradation.
|
|
|
|
- Source: LibreNMS LibreNMS/OS/Routeros.php (11 wireless discovery methods)
|
|
Matches exact OIDs, descriptions, divisors, and skip logic from LibreNMS.
|
|
|
|
- Priority: TIER 4 LARGE (12-16 hour effort, vendor module enhancement)
|
|
- Gap Status: MikroTik wireless coverage 0% → 100% (11 sensor types)
|
|
- Result: TIER 4 COMPLETE - MikroTik wireless monitoring at 100% LibreNMS parity
|
|
|
|
2026-02-12 - feat: add UniFi channel-to-frequency dynamic conversion for accurate frequency monitoring
|
|
- Files: lib/towerops/snmp/profiles/vendors/unifi.ex (enhanced)
|
|
Added TIER 3 MEDIUM priority dynamic frequency sensor discovery for Ubiquiti UniFi APs.
|
|
Implements channel-to-frequency conversion matching LibreNMS behavior exactly.
|
|
- Channel OID: .1.3.6.1.4.1.41112.1.6.1.2.1.4 (unifiVapChannel)
|
|
- Radio Name OID: .1.3.6.1.4.1.41112.1.6.1.2.1.1 (unifiVapRadio)
|
|
- Conversion: 2.4GHz channels 1-14 → 2412-2484 MHz
|
|
- Conversion: 5GHz channels 34-165 → 5170-5825 MHz
|
|
- Unknown channels (not in lookup table) are filtered out
|
|
- Implementation:
|
|
- discover_frequency_sensors/1: Walks channel OID, converts to frequency dynamically
|
|
- channel_to_frequency/1: Lookup table with 29 Wi-Fi channel mappings
|
|
- Frequency sensors added alongside static sensors (clients, CCQ, power, utilization)
|
|
- Per-radio frequency sensors with descriptive names (e.g., "Frequency (ng)")
|
|
- Files: test/towerops/snmp/profiles/vendors/unifi_test.exs (enhanced)
|
|
Added comprehensive test coverage for frequency conversion:
|
|
- Tests 2.4GHz channel conversion (channels 1, 6, 11)
|
|
- Tests 5GHz channel conversion (channels 36, 149, 165)
|
|
- Tests unknown channel filtering (channel 999 → filtered out)
|
|
- Tests integration with static sensors (12 total sensors: 10 static + 2 frequency)
|
|
- Tests graceful handling of channel walk failures
|
|
All 16 tests passing with Mox-based SNMP adapter mocking.
|
|
- Impact: Dynamic frequency monitoring enables accurate channel tracking when APs
|
|
change channels (auto-DFS, manual changes). Static OID approach was inaccurate.
|
|
- Source: LibreNMS LibreNMS/OS/Unifi.php discoverWirelessFrequency/pollWirelessFrequency
|
|
LibreNMS LibreNMS/Modules/Wireless.php channelToFrequency lookup table
|
|
- Priority: TIER 3 MEDIUM (3-5 hour effort, vendor module enhancement)
|
|
- Gap Status: UniFi parity 80% → 90%
|
|
- Result: TIER 3 COMPLETE - All Ubiquiti platform gaps resolved
|
|
|
|
2026-02-12 - feat: add AirFiber AF-LTU optical power sensors (per-chain RX power, TX EIRP)
|
|
- Files: priv/profiles/os_discovery/airos-af-ltu.yaml (enhanced)
|
|
Added TIER 3 MEDIUM priority optical power sensors for Ubiquiti AirFiber AF-LTU:
|
|
- RX Power Chain 0: Received optical power chain 0 in dBm
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.4.1.5
|
|
- RX Power Chain 1: Received optical power chain 1 in dBm
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.4.1.6
|
|
- RX Ideal Power Chain 0: Ideal received power chain 0 in dBm
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.4.1.7
|
|
- RX Ideal Power Chain 1: Ideal received power chain 1 in dBm
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.4.1.8
|
|
- TX EIRP: Transmit effective isotropic radiated power in dBm
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.2.6
|
|
- Impact: Per-chain optical power monitoring enables detection of imbalanced
|
|
signal levels, fiber issues, and link budget problems. Ideal power comparison
|
|
helps identify suboptimal alignment or hardware degradation.
|
|
- Source: LibreNMS LibreNMS/OS/AirosAfLtu.php
|
|
- Priority: TIER 3 MEDIUM (enhanced troubleshooting and diagnostics)
|
|
- Gap Status: AF-LTU parity 80% → 90%
|
|
- Remaining: UniFi channel-to-frequency conversion (requires vendor module work)
|
|
|
|
2026-02-12 - feat: add AirFiber wireless metrics (frequency, distance, capacity, RSSI, SNR)
|
|
- Files: priv/profiles/os_discovery/airos-af60.yaml (enhanced)
|
|
Added TIER 2 HIGH priority wireless metrics for Ubiquiti AirFiber AF60:
|
|
- Frequency: Operating frequency in MHz
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.1.2
|
|
- Distance: Link distance in km (divisor 1000)
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.3.1.15
|
|
- TX Capacity: Transmit capacity in Mbps (divisor 1000)
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.3.1.7
|
|
- RX Capacity: Receive capacity in Mbps (divisor 1000)
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.3.1.8
|
|
- Local RSSI: Local received signal strength in dBm
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.3.1.3
|
|
- Remote RSSI: Remote received signal strength in dBm
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.3.1.18
|
|
- Local SNR: Local signal-to-noise ratio in dB
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.3.1.4
|
|
- Remote SNR: Remote signal-to-noise ratio in dB
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.3.1.19
|
|
- Files: priv/profiles/os_discovery/airos-af-ltu.yaml (enhanced)
|
|
Added TIER 2 HIGH priority wireless metrics for Ubiquiti AirFiber AF-LTU:
|
|
- Frequency: Operating frequency in MHz
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.2.2
|
|
- Distance: Link distance in km (divisor 1000)
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.4.1.23
|
|
- TX Capacity: Transmit capacity in Mbps (divisor 1000)
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.4.1.3
|
|
- RX Capacity: Receive capacity in Mbps (divisor 1000)
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.4.1.4
|
|
- Impact: Essential wireless metrics for capacity planning and troubleshooting.
|
|
Distance enables link budget analysis. RSSI/SNR enable interference detection.
|
|
Capacity metrics enable throughput monitoring and bandwidth planning.
|
|
- Source: LibreNMS LibreNMS/OS/AirosAf60.php, LibreNMS/OS/AirosAfLtu.php
|
|
- Priority: TIER 2 HIGH (enhanced monitoring for capacity planning)
|
|
- Gap Status: AF60 parity 50% → 80%, AF-LTU parity 60% → 80%
|
|
- Next: TIER 3 - UniFi channel-to-frequency conversion, AF-LTU optical power
|
|
|
|
2026-02-12 - feat: add critical AirFiber MCS/modulation rate state sensors
|
|
- Files: priv/profiles/os_discovery/airos-af60.yaml (enhanced)
|
|
Added CRITICAL link quality state sensors for Ubiquiti AirFiber AF60:
|
|
- TX MCS Rate: 9 states (1X-9X) showing transmit modulation level
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.3.1.5 (states: 1-2 warning, 3-4 degraded, 5-9 ok)
|
|
- RX MCS Rate: 9 states (1X-9X) showing receive modulation level
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.3.1.6 (states: 1-2 warning, 3-4 degraded, 5-9 ok)
|
|
- Active Link: 2 states (Main/Backup) showing active link selection
|
|
OID: .1.3.6.1.4.1.41112.1.11.1.3.1.2 (states: 1=Main ok, 2=Backup degraded)
|
|
- Files: priv/profiles/os_discovery/airos-af-ltu.yaml (enhanced)
|
|
Added CRITICAL link quality state sensors for Ubiquiti AirFiber AF-LTU:
|
|
- TX Modulation Rate: 7 QAM states (1X QPSK+SFBC through 12X 4096QAM)
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.4.1.1 (states: 1-2 warning, 4-6 degraded, 8-12 ok)
|
|
- RX Modulation Rate: 7 QAM states (1X QPSK+SFBC through 12X 4096QAM)
|
|
OID: .1.3.6.1.4.1.41112.1.10.1.4.1.2 (states: 1-2 warning, 4-6 degraded, 8-12 ok)
|
|
- Impact: MCS/modulation rate is THE key indicator of point-to-point link health.
|
|
Without these sensors, operators cannot diagnose why throughput changed or when
|
|
links drop from high QAM to low QAM due to interference or alignment issues.
|
|
- Pattern: State sensors with discrete value mappings match LibreNMS exactly.
|
|
Uses generic values for alerting: 0=ok, 1=degraded/warning, 2=critical.
|
|
- Source: LibreNMS includes/discovery/sensors/state/airos-af*.inc.php
|
|
- Priority: TIER 1 CRITICAL (production monitoring gaps for PtP wireless)
|
|
- Gap Status: AF60 parity 35% → 50%, AF-LTU parity 40% → 60%
|
|
- Next: TIER 2 - Add RSSI, SNR, frequency, distance, capacity sensors
|
|
|
|
2026-02-12 - feat: add Dell PowerVault storage array text-based sensor parsing
|
|
- Files: lib/towerops/snmp/profiles/vendors/powervault.ex (created)
|
|
Created vendor post-processing module for Dell PowerVault storage arrays.
|
|
PowerVault devices report sensors as text messages in FCMGMT-MIB::connUnitSensorMessage
|
|
instead of structured SNMP tables, requiring regex-based parsing.
|
|
- Message format: "Sensor Name: Value Unit" (e.g., "Enclosure Temp: 25 C 77.0F")
|
|
- Temperature: Parses Celsius from "N C M.MF" format (e.g., "25 C 77.0F" → 25°C)
|
|
- Voltage: Parses "N.NV" format (e.g., "12.1V" → 12.1V)
|
|
- Current: Parses "N.NA" format (e.g., "0.5A" → 0.5A)
|
|
- Charge: Parses "N%" format (e.g., "95%" → 95% with battery thresholds)
|
|
Sensor index format: powervault_{type}.{oid_index} for unique identification.
|
|
- Files: lib/towerops/snmp/profiles/dynamic.ex (enhanced)
|
|
Integrated PowerVault vendor module into post-processing pipeline.
|
|
Added "dell-powervault" case to apply_vendor_post_processing/3 function.
|
|
- Files: test/towerops/snmp/profiles/vendors/powervault_test.exs (created)
|
|
Comprehensive test suite with 21 tests covering:
|
|
- All sensor types (temperature, voltage, current, charge/percent)
|
|
- Multi-sensor parsing (mixed message types in single walk)
|
|
- Error handling (invalid formats, non-string values, missing colons)
|
|
- Edge cases (empty results, SNMP timeouts, existing sensor preservation)
|
|
All tests passing with Mox-based SNMP adapter mocking.
|
|
- Pattern: Follows Arista vendor module architecture with post_process_sensors/2
|
|
callback. Client.walk returns map format, converted to list for message parsing.
|
|
- Result: Dell PowerVault storage arrays now support temperature/voltage/current/
|
|
battery monitoring via text message parsing. Gap: CRITICAL → RESOLVED.
|
|
Parity: 0% → 85% (limited by FCMGMT-MIB available sensors).
|
|
|
|
2026-02-11 - feat: add Dell UPS power sensor and HP BladeSystem/Moonshot complete monitoring
|
|
- Files: priv/profiles/os_discovery/dell-ups.yaml (enhanced)
|
|
Added Dell UPS power consumption sensor via DELL-SNMP-UPS-MIB:
|
|
- Power: physicalOutputPresentConsumption (OID .1.3.6.1.4.1.674.10902.2.120.2.6.0)
|
|
Enables capacity planning and load tracking for Dell UPS units.
|
|
Gap: MEDIUM (missing power sensor) → RESOLVED. Parity: 80% → 100%.
|
|
- Files: priv/profiles/os_discovery/hpblmos.yaml (enhanced)
|
|
Created comprehensive HP BladeSystem/Moonshot sensor profile:
|
|
- Temperature: Blade chassis component temperatures (OID .1.3.6.1.4.1.232.22.2.3.1.2.1.6)
|
|
- Power: PSU output wattage with max limit (OID .1.3.6.1.4.1.232.22.2.5.1.1.1.10)
|
|
- State: Fan operational status (OID .1.3.6.1.4.1.232.22.2.3.1.3.1.11)
|
|
- State: PSU condition status (OID .1.3.6.1.4.1.232.22.2.5.1.1.1.17)
|
|
Skip logic: Only monitors present fans/PSUs (presence check to avoid non-existent sensors)
|
|
Gap: CRITICAL (no sensor profile) → RESOLVED. Parity: 0% → 80%.
|
|
- Analysis Discovery: Dell Enterprise Servers (iDRAC) already have excellent coverage
|
|
The existing drac.yaml profile includes comprehensive sensor monitoring:
|
|
- Temperature: Multiple probes with thresholds (4 types)
|
|
- Voltage: PSU voltage monitoring (2 types)
|
|
- Current: Amperage probes (3 types, filtered for wattage type)
|
|
- Power: Chassis power (current, peak, potential, idle, max - 5 types)
|
|
- Fanspeed: Cooling device monitoring with thresholds
|
|
- State: Extensive state sensors (global system, IDSDM card, intrusion, IOM, etc.)
|
|
Previous gap analysis incorrectly reported 0% parity - actual parity is 95%+.
|
|
- Result: Tier 4 complete. Dell UPS now has full monitoring capability, HP BladeSystem
|
|
blade chassis fully supported with temperature/power/fan/PSU monitoring. Dell servers
|
|
confirmed to have excellent existing coverage via iDRAC/OpenManage MIBs.
|
|
|
|
2026-02-11 - feat: add Force10 FTOS and optical transceiver monitoring (ProCurve, Comware)
|
|
- Files: priv/profiles/os_discovery/ftos.yaml (enhanced)
|
|
Added Dell Force10 FTOS temperature monitoring for all 3 series:
|
|
- S-Series: chStackUnitTemp (OID .1.3.6.1.4.1.6027.3.10.1.2.2.1.14)
|
|
- C-Series: chSysCardTemp (OID .1.3.6.1.4.1.6027.3.8.1.2.1.1.5)
|
|
- E-Series: chSysCardUpperTemp + chSysCardLowerTemp (OIDs .1.3.6.1.4.1.6027.3.1.1.2.3.1.8-9)
|
|
Completes Tier 1 critical network switch monitoring. Parity: 0% → 90%.
|
|
- Files: priv/profiles/os_discovery/procurve.yaml (enhanced)
|
|
Added HP ProCurve transceiver optical monitoring via HP-ICF-TRANSCEIVER-MIB::hpicfXcvrInfoTable:
|
|
- Temperature: hpicfXcvrTemp (OID .1.3.6.1.4.1.11.2.14.11.5.1.82.1.1.1.1.11)
|
|
- Bias Current: hpicfXcvrBias (OID .1.3.6.1.4.1.11.2.14.11.5.1.82.1.1.1.1.13)
|
|
- Supply Voltage: hpicfXcvrVoltage (OID .1.3.6.1.4.1.11.2.14.11.5.1.82.1.1.1.1.12)
|
|
- RX Power (dBm): hpicfXcvrRxPower (OID .1.3.6.1.4.1.11.2.14.11.5.1.82.1.1.1.1.14)
|
|
- TX Power (dBm): hpicfXcvrTxPower (OID .1.3.6.1.4.1.11.2.14.11.5.1.82.1.1.1.1.15)
|
|
Enables optical SFP/SFP+ monitoring for fiber uplinks. Parity: 60% → 100%.
|
|
- Files: priv/profiles/os_discovery/comware.yaml (enhanced)
|
|
Added HP Comware transceiver optical monitoring via HH3C-TRANSCEIVER-INFO-MIB::hh3cTransceiverInfoTable:
|
|
- Temperature: hh3cTransceiverTemperature (OID .1.3.6.1.4.1.25506.2.70.1.1.1.15)
|
|
- Bias Current: hh3cTransceiverBiasCurrent (OID .1.3.6.1.4.1.25506.2.70.1.1.1.17)
|
|
- Supply Voltage: hh3cTransceiverVoltage (OID .1.3.6.1.4.1.25506.2.70.1.1.1.16)
|
|
- RX Power (dBm): hh3cTransceiverCurRXPower (OID .1.3.6.1.4.1.25506.2.70.1.1.1.9)
|
|
- TX Power (dBm): hh3cTransceiverCurTXPower (OID .1.3.6.1.4.1.25506.2.70.1.1.1.12)
|
|
Completes Comware sensor coverage. Parity: 60% → 95%.
|
|
- Result: Tier 1 + Tier 2 complete. All critical network switches have temperature monitoring,
|
|
and both ProCurve/Comware have complete optical transceiver diagnostics (temp, current, voltage,
|
|
RX/TX power). Force10 FTOS data center switches fully supported. Fiber link monitoring enabled.
|
|
|
|
2026-02-11 - feat: add critical network switch sensor support (HP Comware, Dell PowerConnect, Dell SONiC)
|
|
- Files: priv/profiles/os_discovery/comware.yaml (enhanced)
|
|
Added HP Comware chassis temperature monitoring via HH3C-ENTITY-EXT-MIB::hh3cEntityExtTemperature
|
|
(OID 1.3.6.1.4.1.25506.2.6.1.1.1.1.12). This restores fundamental temperature monitoring capability
|
|
for HP Comware switches, enabling overheating alerts. Gap identified as CRITICAL in Phase 3 analysis.
|
|
- Files: priv/profiles/os_discovery/powerconnect.yaml (enhanced)
|
|
Added Dell PowerConnect/DNOS CPU temperature monitoring via FASTPATH-BOXSERVICES-PRIVATE-MIB
|
|
(OID 1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.5). Enables temperature monitoring for
|
|
common enterprise access switches.
|
|
- Files: priv/profiles/os_discovery/dell-sonic.yaml (new)
|
|
Created comprehensive sensor profile for Dell SONiC switches using NETGEAR-BOXSERVICES-PRIVATE-MIB
|
|
(Quanta-based platform). Sensors: temperature (boxServicesTempSensorState), fan speed
|
|
(boxServicesFanSpeed), PSU state (boxServicesPowSupplyItemState with 8 states). Enables hardware
|
|
monitoring for modern data center switches.
|
|
- Result: Top 3 critical network switch monitoring gaps resolved. HP Comware gains fundamental
|
|
temperature capability (40% → 60% parity), Dell PowerConnect gains first sensor support
|
|
(0% → 80% parity), Dell SONiC gains complete hardware monitoring (0% → 95% parity).
|
|
|
|
2026-02-11 - audit: Phase 3 - HP/Aruba and Dell sensor analysis complete
|
|
- Files: docs/librenms-audit/sensors/hp-aruba-comparison.md (new)
|
|
Analyzed 6 HP/Aruba platforms: ProCurve (60%), Comware (40%), hpblmos (0%), ArubaOS (100%),
|
|
ArubaOS-CX (100%), Instant On (100%). Identified critical gaps in Comware temperature and
|
|
transceiver support.
|
|
- Files: docs/librenms-audit/sensors/dell-comparison.md (new)
|
|
Analyzed 11 Dell platforms: OS10 (100%), rPDU (100%), UPS (80%), OME-M (100%), Compellent (100%),
|
|
PowerVault (20%), PowerConnect (0%), Force10 (0%), SONiC (0%), Quanta (40%), Servers (0%).
|
|
Found network switches severely underserved compared to storage/infrastructure.
|
|
- Files: docs/librenms-audit/PHASE3-VENDOR-EXPANSION.md (new)
|
|
Executive summary with implementation priorities. Tier 1 critical: Network switch sensor gaps
|
|
(8-12 hours). Tier 2 high: Optical transceiver monitoring (4-6 hours). Tier 3: Storage/compute
|
|
(7-10 hours). Total effort: 26-38 hours for full parity.
|
|
- Key Finding: Modern platforms excellent (Aruba CX, Dell OS10), but legacy network switches
|
|
missing fundamental monitoring. HP Comware temperature gap BLOCKING (breaks alerts).
|
|
Dell PowerConnect/FTOS/SONiC missing all sensors (CRITICAL for enterprise deployments).
|
|
|
|
2026-02-11 - feat: implement Arista EOS sensor enhancements (DOM power, thresholds, grouping)
|
|
- Files: lib/towerops/snmp/profiles/vendors/arista.ex (enhanced)
|
|
Implemented all critical and nice-to-have Arista sensor improvements identified in audit:
|
|
1. DOM power conversion (watts→dBm): Detects optical power sensors via regex, converts
|
|
using formula dBm = 10*log10(watts*1000), preserves original value in metadata
|
|
2. Arista threshold discovery: Walks ARISTA-ENTITY-SENSOR-MIB::aristaEntSensorThresholdTable,
|
|
applies 4 threshold types (low_critical, low_warn, high_warn, high_critical), converts
|
|
thresholds to dBm for optical sensors
|
|
3. Smart grouping: Organizes sensors by SFPs, PSUs, Platform (chipsets), Power Connectors, System
|
|
4. Description cleanup: Removes redundant "sensor" text, simplifies PSU naming, cleans whitespace
|
|
- Files: lib/towerops/snmp/profiles/dynamic.ex (integration)
|
|
Added apply_vendor_post_processing/3 to call Arista enhancements after sensor discovery.
|
|
Applies to both arista_eos and arista-mos profiles.
|
|
- Files: test/towerops/snmp/profiles/vendors/arista_test.exs (comprehensive tests)
|
|
Added 23 new tests covering DOM conversion (6 tests), threshold discovery (4 tests),
|
|
smart grouping (6 tests), description cleanup (5 tests), and end-to-end post-processing (1 test).
|
|
All tests passing (30/30 in arista_test.exs, 6367/6367 total).
|
|
- Result: Arista EOS support upgraded from 85% to 100% LibreNMS parity. All critical gaps closed:
|
|
optical power now displayed correctly in dBm, alerting enabled via thresholds, sensors
|
|
organized for better UX, descriptions cleaned up.
|
|
|
|
2026-02-11 - audit: Phase 2 - complete top vendor sensor analysis (Cisco, Juniper, Arista)
|
|
- Files: docs/librenms-audit/sensors/*.md, PHASE2-VENDOR-ANALYSIS.md (new)
|
|
Completed comprehensive sensor discovery analysis for top 3 enterprise vendors:
|
|
- cisco-ios-comparison.md: Cisco IOS/XE/XR/NX-OS analysis (95% parity, production ready)
|
|
- juniper-junos-comparison.md: JunOS analysis (100% IDENTICAL - perfect parity)
|
|
- arista-eos-comparison.md: Arista EOS analysis (85% parity, gaps identified)
|
|
- PHASE2-VENDOR-ANALYSIS.md: Comprehensive summary and recommendations
|
|
- Key findings:
|
|
- Cisco: All critical sensors covered, YAML-based discovery, minor cellular gaps (rare devices)
|
|
- Juniper: junos.yaml byte-for-byte identical (30+ sensor types, 38+ OIDs, 10 MIBs)
|
|
- Arista: Missing DOM power conversion (watts→dBm) and ARISTA-ENTITY-SENSOR-MIB thresholds
|
|
- Identified actionable fixes for Arista (2 critical, 2 minor):
|
|
1. DOM Rx/Tx power conversion (2-3 hours, enables proper optical monitoring)
|
|
2. Arista threshold discovery (4-6 hours, enables alerting)
|
|
3. Smart grouping (2-3 hours, UX improvement)
|
|
4. Description cleanup (1-2 hours, cosmetic)
|
|
- Towerops advantages: CPU/Memory/Uptime sensors (Arista), PSU/Fan state (Arista),
|
|
cleaner YAML architecture, index templates, pre-resolved MIB cache
|
|
|
|
2026-02-11 - audit: complete LibreNMS parity audit and add missing OS detection profiles
|
|
- Files: docs/librenms-audit/*.md (new)
|
|
Completed comprehensive audit comparing Towerops device detection and sensor discovery
|
|
against LibreNMS. Created detailed documentation:
|
|
- detection-algorithm.md: LibreNMS 2-pass detection system analysis
|
|
- towerops-detection.md: Towerops 4-phase detection system analysis
|
|
- vendor-detection-comparison.csv: Priority vendor comparison (MikroTik, Ubiquiti)
|
|
- librenms-sensors.md: LibreNMS sensor discovery architecture (360+ modules, 24 types)
|
|
- EXECUTIVE-SUMMARY.md: Overall findings (99.5% detection parity, 95%+ sensor parity)
|
|
- IMPLEMENTATION-STATUS.md: Phase 1 completion status
|
|
- Files: priv/profiles/os_detection/conteg-pdu.yaml, microsens-g6.yaml (new)
|
|
Added 2 missing OS detection profiles from LibreNMS to achieve 100% profile parity
|
|
(786 profiles total). Conteg PDU for power monitoring devices, MICROSENS G6 for
|
|
network switches.
|
|
- Key findings: Towerops has full detection parity with LibreNMS plus architectural
|
|
enhancements (4-phase matching, Rust NIF MIB resolution, ETS caching, index templates).
|
|
MikroTik coverage verified: all 22 sensor tables discovered identically. Ubiquiti
|
|
coverage: 8 of 9 profiles identical (airos-af has additional fallback in Towerops).
|
|
|
|
2026-02-11 - test: add 100% coverage for ExpiredBanCleanupWorker
|
|
- File: test/towerops/workers/expired_ban_cleanup_worker_test.exs (new)
|
|
Added 7 tests covering perform/1: expired ban deletion, active ban preservation,
|
|
permanent ban preservation, mixed scenarios, empty database, PubSub broadcast
|
|
on deletion, and no broadcast when nothing deleted.
|
|
|
|
2026-02-11 - fix: handle "null" string values in SNMP parsing
|
|
- File: lib/towerops/snmp/profiles/base.ex (parse_integer/1, parse_float/1)
|
|
Added explicit handling for "null" string values before attempting integer/float
|
|
conversion. Some devices (e.g., AirOS 8.7.14) return the literal string "null"
|
|
for unavailable metrics like UCD CPU stats, which caused ArgumentError when
|
|
parse_integer/parse_float tried to convert them. Now returns nil, which gets
|
|
coerced to 0 by the || 0 fallback in the calling code.
|
|
|
|
2026-02-11 - fix: deduplicate sensors with leading-dot OID differences
|
|
- File: lib/towerops/snmp/profiles/dynamic.ex (deduplicate_by_oid/1)
|
|
Normalized OIDs by stripping leading dots when grouping for deduplication.
|
|
gosnmp (agent) returns OIDs with leading dots (.1.3.6.1...) but vendor
|
|
modules and YAML profiles define them without. Without normalization,
|
|
the same sensor appeared twice (e.g. "DHCP Leases" and "DHCP Lease Count").
|
|
- File: lib/towerops/snmp/discovery.ex (deduplicate_sensors_by_oid/1)
|
|
Same leading-dot normalization applied to the discovery-level deduplication.
|
|
- File: lib/towerops/snmp/profiles/vendors/routeros.ex (wireless_oid_defs/0)
|
|
Removed DHCP Leases entry (mtxrDHCPLeaseCount) since the routeros.yaml
|
|
YAML profile already defines it in count_sensor_oids. Eliminates the
|
|
source of duplication for MikroTik devices.
|
|
- Tests updated in dynamic_test.exs and routeros_test.exs
|
|
|
|
2026-02-11 - fix: agent discovery and polling improvements
|
|
- File: lib/towerops_web/channels/agent_channel.ex (build_polling_queries/1, process_interface_stats/3)
|
|
Changed interface traffic OIDs from 32-bit counters (ifInOctets/ifOutOctets) to 64-bit
|
|
HC counters (ifHCInOctets/ifHCOutOctets). 32-bit counters wrap at ~4.3GB which causes
|
|
wildly inaccurate readings on gigabit+ links.
|
|
- File: lib/towerops/snmp/adapters/replay.ex (parse_value/1)
|
|
Fixed negative integer parsing regex from ^\d+$ to ^-?\d+$ so values like
|
|
entPhySensorScale=-3 are parsed as integers. Previously fell through to string,
|
|
causing sensor divisor calculation to silently return 1 instead of 1000.
|
|
- File: lib/towerops_web/channels/agent_channel.ex (build_discovery_queries/0)
|
|
Replaced walking entire Cisco enterprise tree (1.3.6.1.4.1.9) with targeted subtrees
|
|
for CPU, ENVMON, CDP, and WAP to avoid 50k+ OID responses and timeouts. Added Juniper,
|
|
HP/H3C, Fortinet, and Cambium vendor OIDs for broader device support.
|
|
- File: lib/towerops_web/channels/agent_channel.ex (build_discovery_queries/0)
|
|
Added missing discovery OIDs: ENTITY-STATE-MIB for state sensors, HOST-RESOURCES-MIB
|
|
tables for processors/storage/devices, and UCD-SNMP-MIB for Linux CPU stats fallback.
|
|
- Tests added in replay_test.exs and agent_channel_test.exs
|
|
|
|
2026-02-11 - fix: handle RouterOS version returned as list of integers
|
|
- File: lib/towerops/snmp/profiles/vendors/routeros.ex (detect_version/1)
|
|
Added pattern match to handle case where SNMP version OID returns list
|
|
of integers [7, 20, 6] instead of binary string "7.20.6". Converts list
|
|
to dotted string format using Enum.join/2.
|
|
- File: test/towerops/snmp/profiles/vendors/routeros_test.exs
|
|
Added two test cases for list-formatted versions with and without license level.
|
|
- Bug: Warning logged "Failed to detect version: {:ok, [7, 20, 6]}" even though
|
|
version was successfully retrieved, just in wrong format.
|
|
|
|
2026-02-11 - fix: normalize OIDs so agent-polled sensors match regardless of leading dot
|
|
- File: lib/towerops_web/channels/agent_channel.ex
|
|
Agent (gosnmp) returns OIDs with leading dots (e.g. ".1.3.6.1.4.1.41112...")
|
|
but sensor OIDs stored in DB may omit the dot. process_sensor_reading used
|
|
direct Map.get which silently missed wireless/vendor sensors on Ubiquiti airOS.
|
|
- Fix: Added normalize_oid_keys/1 to strip leading dots from all oid_values keys,
|
|
and normalize sensor.sensor_oid too. Both sides now match without leading dot.
|
|
- File: test/towerops/snmp/sensor_change_detector_test.exs
|
|
Fixed flaky refute_receive tests that subscribed to global "device:events" topic
|
|
and caught unrelated device_discovered events from concurrent async tests.
|
|
Changed to device-specific topic "device:#{device.id}" instead.
|
|
|
|
2026-02-11 - feat: add sensor value change events for all sensor types
|
|
- New file: lib/towerops/snmp/sensor_change_detector.ex
|
|
Extracted shared sensor change detection logic from DevicePollerWorker.
|
|
Detects threshold violations, spike/drop for % sensors, and new
|
|
sensor_value_changed events for all non-% sensors when value changes.
|
|
- File: lib/towerops/devices/event.ex
|
|
Added "sensor_value_changed" to allowed event types.
|
|
- File: lib/towerops/workers/device_poller_worker.ex
|
|
Replaced inline detect_sensor_changes with SensorChangeDetector module.
|
|
Removed ~240 lines of private functions now in shared module.
|
|
- File: lib/towerops_web/channels/agent_channel.ex
|
|
Added change detection and last_value/last_checked_at update to
|
|
process_sensor_reading/3 so agent-polled devices get same events
|
|
as Phoenix-polled devices.
|
|
- New file: test/towerops/snmp/sensor_change_detector_test.exs
|
|
11 tests covering value changes, spike/drop, thresholds, nil handling.
|
|
|
|
2026-02-11 - fix: live polling uses effective agent from site/org cascade
|
|
- File: lib/towerops_web/live/graph_live/show.ex
|
|
- Bug: Live poll mode used Agents.get_device_assignment/1 which only checks
|
|
direct device-level assignments. Devices with agent assigned at site or
|
|
org level fell through to direct Phoenix SNMP instead of routing to agent.
|
|
- Fix: Replaced with Agents.get_effective_agent_token/1 which walks the
|
|
device → site → org cascade, matching how regular polling resolves agents.
|
|
Also simplified request_agent_live_poll_and_wait to accept token_id directly.
|
|
|
|
2026-02-11 - fix: round sensor values to 1 decimal place
|
|
- Files: lib/towerops/workers/device_poller_worker.ex (poll_simple_sensor/2),
|
|
lib/towerops_web/channels/agent_channel.ex (process_sensor_reading/3)
|
|
- Bug: Division by sensor_divisor produced full float precision (e.g. 34.09999999)
|
|
- Fix: Wrap division result with Float.round(..., 1) in both Phoenix and agent paths
|
|
|
|
2026-02-11 - fix: update device status from agent monitoring checks
|
|
- File: lib/towerops_web/channels/agent_channel.ex (store_monitoring_check/2)
|
|
- Bug: Devices polled by remote agents stayed in "unknown" state because
|
|
store_monitoring_check saved the ping result but never called
|
|
Devices.update_device_status/2. The DeviceMonitorWorker (Phoenix-side)
|
|
skips agent-assigned devices entirely, so nothing ever updated status.
|
|
- Fix: Added update_device_status_from_check/2 and handle_agent_status_change/3
|
|
to derive :up/:down from check status, update device, create alerts on
|
|
transitions, and broadcast via PubSub — matching DeviceMonitorWorker behavior
|
|
- Also added alias Towerops.Alerts to the channel module
|
|
|
|
2026-02-11 - fix: update last_snmp_poll_at for agent-polled devices
|
|
- File: lib/towerops_web/channels/agent_channel.ex (process_polling_result/3)
|
|
- Bug: Devices polled by remote agents showed "Last Polled: Never" because
|
|
process_polling_result never called Devices.update_snmp_poll_time/1
|
|
- The Phoenix-side DevicePollerWorker already had this call (line 172),
|
|
but the agent channel path was missing it
|
|
- Fix: Added Devices.update_snmp_poll_time(device) at the top of
|
|
process_polling_result/3, matching the DevicePollerWorker pattern
|