Implements health monitoring in the agent using ICMP ping, allowing
devices assigned to local (non-cloud) agents to be monitored.
Changes:
- Add surge-ping library for async ICMP ping operations
- Create ping.rs module with ping_device() function (5s timeout)
- Rename JobType::MONITOR to JobType::PING in protobuf
- Add monitoring_check channels for result communication
- Implement execute_ping_job() to handle PING jobs
- Update TUI to display ping result events
The agent now receives PING jobs from Phoenix, executes ICMP pings,
and sends MonitoringCheck results back for storage in the database.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Implement get_local_ip() using UDP socket trick to resolve local
interface address without sending traffic, so heartbeat reports
actual agent IP instead of "unknown"
- Remove dead poller/scheduler/executor and api_client modules that
referenced non-existent modules and were never compiled
Discovery with SNMPv3 was completing in 52 seconds, dangerously close
to the 60s timeout. Increasing to 120s provides comfortable headroom
for complete MikroTik OID tree traversal with encryption overhead.
SNMPv3 has significant encryption and authentication overhead compared to
v2c. MikroTik enterprise tree walks (1.3.6.1.4.1.14988) can take 16+
seconds with SNMPv3, causing timeouts with the previous 30s limit.
Increased timeout from 30s to 60s in both client.rs and device_poller.rs
to accommodate SNMPv3's additional latency.
- Add trap.rs with BER/ASN.1 parser for SNMP trap PDUs
- Support both SNMPv1 and SNMPv2c trap formats
- Listen on configurable UDP port (default 162)
- Log received traps at INFO level
- Add LOG_LEVEL env var for log verbosity control
- Add TRAP_PORT env var and CLI flag
- Update docker-compose with trap port mapping
- Replace raw ICMP socket implementation with system ping command
- Add regex-lite dependency for parsing ping output
- Add tokio process feature for async command execution
- Support macOS and Linux ping output formats
- Add iputils to Dockerfile for setuid-root ping
- Remove socket2 dependency (no longer needed)
This eliminates the need for CAP_NET_RAW capability in containers.
- Added custom logging macros (log_error!, log_warn!, log_info!, log_debug!)
- Implemented LogLevel enum and LOG_LEVEL static for runtime level control
- Exported macros with #[macro_export] for use across all modules
- Replaced all log:: calls in websocket_client.rs, health.rs, and version.rs
- Removed obsolete test code referencing old log crate
- Removed log dependency from Cargo.toml
- Fixed useless comparison warning in test
- Binary size: still 1.5M (no change - log was lightweight)
- Tests: 65 passing, 0 warnings
This completes the removal of 9 dependencies (thiserror, hostname, chrono,
base64, rand, ureq, tiny_http, anyhow, log). Dependency count: 19 → 10.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added custom logging macros to main.rs to prepare for removing the
log crate dependency:
- Added LogLevel enum and LOG_LEVEL static
- Created log_error!, log_warn!, log_info!, log_debug! macros
- Replaced log calls in main.rs with custom macros
- Made format_timestamp() public for use in macros
Still TODO:
- Update websocket_client.rs, health.rs, version.rs
- Remove log from Cargo.toml
This is work in progress toward removing more dependencies.
Problem:
- Rust agent was experiencing frequent SNMP timeouts
- 5-second timeout is too aggressive for slow devices or congested networks
- Phoenix app uses 30-second timeout with better reliability
Solution:
- Increased SNMP_TIMEOUT_SECS constant from 5 to 30 seconds
- Applied to both get() and walk() operations
- Now matches Phoenix application timeout configuration
Benefits:
- Reduces false positive timeout errors
- Better handling of slow network devices
- Consistent timeout behavior across Elixir and Rust pollers
- Maintains reliability during network congestion
Note: SNMP timeout is per-request. Total polling time may still be
limited by Task::spawn_blocking timeout in poller executor (40s).
🤖 Generated with Claude Code
Removed dependencies and replaced with custom code:
- thiserror: Not used (only pulled by tokio-tungstenite)
- hostname: Replaced with /proc/sys/kernel/hostname reader
- chrono: Replaced with std::time::SystemTime + custom formatting
- base64: Replaced with custom base64 encoder/decoder
Benefits:
- Binary size: 2.4M → 2.3M (100KB reduction)
- Reduced dependency count: 19 → 15 direct dependencies
- Added 7 new tests (73 → 80 total tests)
- All tests pass
Custom implementations:
- format_timestamp(): YYYY-MM-DD HH:MM:SS.mmm format
- get_hostname(): Read from /proc/sys/kernel/hostname
- get_uptime_seconds(): Read from /proc/uptime
- base64_encode/decode(): Standard base64 encoding
No functionality changes, all existing features work identically.
When using SOCK_DGRAM for ICMP on Linux, the kernel manages the
identifier field and may overwrite the value we set. This causes
validation failures when we receive replies with kernel-assigned
identifiers.
The fix is to only validate:
- Type (0 = ECHO REPLY)
- Code (0)
- Sequence number (matches our random value)
The sequence number is sufficient for uniqueness given our polling
intervals (300+ seconds per device). This is the standard approach
for DGRAM ICMP sockets.