Sentinel Agent
The Sentinel Agent monitors the host it runs on, discovers services, collects system and process metrics, and generates threshold-based alerts.
discovery_agent.json), REST API, and internal KV bucket names are unchanged and still read discovery_agent / Discovery Agent — the rename is UI-facing only.
Overview
| Property | Value |
|---|---|
| Service name | MugnsoftDiscoveryAgent |
| Default port | 8070 |
| Configuration file | discovery_agent.json |
| Version | v4.0.0 |
| Storage | embedded key-value store (discovery.db, metrics.db, process.db, system.db) |
Service Management
CLI Commands
# Install as service and register with the Webserver
discovery_agent install <webserver_ip>:<port>
# Re-register with the Webserver
discovery_agent register <webserver_ip>:<port>
# Migrate to a new Webserver
discovery_agent migrate <webserver_ip>:<port> <jwt_token>
# Start / Stop / Restart
discovery_agent start
discovery_agent stop
discovery_agent restart
# Run in foreground
discovery_agent run
# Remove the service
discovery_agent uninstall
Configuration
Core Settings
{
"name": "agent1",
"port": "8070",
"webserver": "192.168.1.100:8050",
"integratorEndPoint": "192.168.1.100:8052",
"location": "Datacenter-1",
"sched": "5MIN",
"processes": "nginx,mysql,java",
"ports": "80,443,3306",
"logLevel": "info"
}
| Field | Description | Default |
|---|---|---|
name |
Unique agent identifier | required |
port |
API listening port | "8070" |
webserver |
Webserver IP:port for registration | required |
integratorEndPoint |
Integrator IP:port for data forwarding | (empty) |
probeEndPoint |
Probe name(s) that run delegated URL/API/port checks (required when urls, apis, or ports are set) |
(empty) |
appName |
Application name this agent’s data is grouped under | (empty) |
location |
Geographic/logical location label | (empty) |
tags |
Comma-separated tags for categorization | (empty) |
sched |
Discovery interval | "5MIN" |
schedMonitors |
Interval for delegated monitor checks | same as sched |
processes |
Comma-separated process names to monitor | (empty) |
ports |
Comma-separated ports to monitor | (empty) |
Scheduling Options
| Label | Interval |
|---|---|
1MIN |
Every minute |
2MIN |
Every 2 minutes |
5MIN |
Every 5 minutes |
10MIN |
Every 10 minutes |
30MIN |
Every 30 minutes |
1H |
Every hour |
4H |
Every 4 hours |
8H |
Every 8 hours |
1D |
Daily |
Directory Structure
<install_dir>/
├── discovery_agent(.exe) # Executable
├── discovery_agent.json # Service configuration
├── config/
│ ├── sec/ # RSA keys
│ └── ssl/ # TLS certificates
├── data/
│ ├── process_list.txt # Monitored process names
│ ├── port_list.txt # Monitored network ports
│ ├── process_thresholds.json # Per-process threshold config
│ ├── system_thresholds.json # System threshold config
│ ├── discover_metrics.json # Latest collected metrics
│ └── alerts.json # Generated alerts
├── dbs/ # embedded key-value databases
│ ├── discovery.db # Main discovery data
│ ├── metrics.db # Historical metrics
│ ├── process.db # Process data
│ ├── system.db # System data
│ └── backup/ # Automated backups
└── log/ # Rotated log files
Discovery Mechanisms
Process Discovery
The Sentinel Agent monitors processes by name. Configure which processes to watch:
Method 1: Configuration file
{
"processes": "nginx,mysqld,java,python3"
}
Method 2: Process list file (data/process_list.txt)
nginx:web,production
mysqld:database,production
java:application
python3.12:scripts
Format: processname[.exe]:tag1,tag2 (colon-separated, with optional tags)
Port Discovery
Monitor which processes are listening on specific ports:
Configuration file:
{
"ports": "80,443,3306,5432,8080"
}
Port list file (data/port_list.txt):
80
443
3306
5432
The agent maps port listeners to process names via TCP connection enumeration.
Network Traffic Discovery
Uses packet capture (pcap) via the gopacket library for live traffic analysis:
- Captures packets on all network interfaces
- Duration configurable via
discoCapInterval - Aggregates traffic by process ID (PID)
- Calculates bandwidth in kbits/s (in/out)
- Generates network topology graph in Cytoscape format for visualization
Delegated Monitors (URL / API / Port checks)
Beyond host metrics, a Sentinel Agent can define synthetic checks — urls, apis, pings, nslookups, tcps, dbs, and syss — directly in its configuration. The agent does not run these checks itself; it delegates them to one or more Monitor probes named in probeEndPoint.
{
"appName": "Shop",
"probeEndPoint": "probe1,probe-win2",
"ports": "80,443,3306",
"urls": [{ "name": "shop-home", "url": "https://shop.example.com/" }],
"apis": [
{
"name": "checkout-api",
"url": "https://api.example.com/health",
"typeApi": "GET"
}
]
}
probeEndPoint is required whenever urls, apis, or ports are defined. Without it the agent logs an error and the checks are not registered. The interval for these delegated checks is controlled by schedMonitors.
This lets you describe a host’s full service surface (system health and its endpoints) in one place, while the actual URL/API execution runs on a probe that has network reach to the targets.
Collected Metrics
System Metrics
| Metric | Description | Threshold Config |
|---|---|---|
| CPU % | Overall CPU usage percentage | discoCPUGFixedThreshCri/Maj/Min |
| Memory % | Memory usage percentage | discoMEMGFixedThreshCri/Maj/Min |
| Load Average (Linux) | 5-minute load average | discoLoadAvg5minGFixedThreshCri/Maj/Min |
| Filesystem % | Disk usage per mount point | discoFSGFixedThreshCri/Maj/Min |
| TCP Sockets | Open TCP socket count | discoTCPSocketsGFixedThreshCri/Maj/Min |
| CPU I/O Wait (Linux) | CPU time waiting for I/O | discoCpuIOWaitGFixedThreshCri/Maj/Min |
| Uptime | System uptime | (informational) |
| Boot time | Last boot timestamp | (informational) |
Per-Process Metrics
| Metric | Description | Threshold Config |
|---|---|---|
| CPU % | Process CPU usage | discoCPUPFixedThresh* or discoCPUPAutoThreshold |
| Memory | RSS memory usage | discoMEMPFixedThresh* or discoMEMPAutoThreshold |
| Swap | Swap usage | discoSWAPPFixedThresh* or discoSWAPPAutoThreshold |
| I/O Read | Disk read bytes/s | discoIostatReadPFixedThresh* or auto |
| I/O Write | Disk write bytes/s | discoIostatWritePFixedThresh* or auto |
| CPU User % | User-mode CPU time | discoCPUUserPFixedThresh* |
| Threads | Thread count | discoNumThreadsPFixedThresh* |
| File Descriptors (Linux) | Open FD count | discoNumFDsPFixedThresh* |
| Network Traffic In | Inbound bandwidth (kbits/s) | via trafficThresholds |
| Network Traffic Out | Outbound bandwidth (kbits/s) | via trafficThresholds |
Metric Enable/Disable
Each metric can be individually enabled or disabled:
{
"discoCPUGMonEnabled": "true",
"discoMEMGMonEnabled": "true",
"discoLoadAvg5minGMonEnabled": "true",
"discoCPUPMonEnabled": "true",
"discoMEMPMonEnabled": "true",
"discoSWAPPMonEnabled": "false"
}
Threshold Configuration
Fixed Thresholds
Set explicit threshold values per metric:
{
"discoCPUGFixedThreshCri": "95",
"discoCPUGFixedThreshMaj": "85",
"discoCPUGFixedThreshMin": "75"
}
Auto Thresholds
Let the agent calculate thresholds based on historical data:
{
"discoCPUPAutoThreshold": "true",
"discoMEMPAutoThreshold": "true"
}
Auto-thresholds use statistical analysis (standard deviation) of historical metrics to dynamically set threshold values.
When auto-threshold is enabled for a metric, leave the corresponding *FixedThresh* fields empty (""). The web UI displays these fields as ∞: while the baseline is being computed (warm-up period), no alert fires for that metric.
999999999999999.00 for this purpose — the agent now automatically normalizes that legacy value back to "" when loading and saving its configuration.
Traffic Thresholds
Per-process network traffic thresholds with directional operators:
{
"trafficThresholds": {
"nginx": {
"operator": ">",
"critical": 10000,
"major": 5000,
"minor": 1000
}
}
}
Operators: > (alert when above) or < (alert when below).
Alerting
Alert Status Levels
| Level | Integer | Description |
|---|---|---|
| OK | 0 | Within normal range |
| MINOR | 1 | Minor threshold breached |
| MAJOR | 2 | Major threshold breached |
| CRITICAL | 3 | Critical threshold breached |
Notification Channels
Identical to other components:
| Channel | Configuration |
|---|---|
smtpEnabled, smtpServerName, smtpPort, smtpUsername, smtpPwd, smtpTLS |
|
| Slack | slackChannel, slackToken |
| Teams | teamsWebhook |
| PagerDuty | pagerDutyAPIKey |
| Custom Script | scriptAction, scriptActionT |
Alert Timing
| Setting | Description |
|---|---|
notifyAfter |
Wait for N consecutive threshold breaches before first alert |
notifyFor |
Continue alerting for N cycles after breach |
notifyStatus |
Minimum status level to trigger (e.g., “CRITICAL”) |
Alert Routing
Alerts can be routed in two ways:
- Via Integrator (recommended) – Sentinel Agent pushes metrics to the Integrator, which handles alerting centrally
- Local alerting – Sentinel Agent sends alerts directly via configured channels (when no Integrator is configured)
Concurrency is controlled by semaphores: 20 concurrent goroutines for Integrator communication, 10 for local alerting.
Execution Flow
Cron trigger (every N minutes)
|
v
execDiscovery()
|
v
runDiscoveryMetrics()
├── CollectSystemMetrics() --> CPU, memory, load, FS, sockets
├── CollectProcessMetrics() --> per-process CPU, memory, I/O, traffic
├── CollectNetworkMetrics() --> pcap traffic capture, connections
└── GenerateCytoscapeData() --> network topology graph
|
v
Write data/discover_metrics.json + data/alerts.json
|
v
discoveryDataFile()
├── processMetricsKV() --> evaluate per-process thresholds
├── systemMetricsKV() --> evaluate system thresholds
└── Route alerts:
├── goDataSent2Integrator() (if Integrator configured)
└── goHandleAlerting() (local fallback)
Background Cron Jobs
| Job | Schedule | Purpose |
|---|---|---|
| Discovery | User-configured (1MIN-1D) | Main metrics collection |
| System metrics | Every 1 minute | Lightweight CPU/memory sampling |
| Auto-backup | Configurable interval | embedded key-value store backups |
| Metrics purge | Daily at 01:00 | Delete old metrics |
| Monitor purge | Daily at 03:00 | Clean up historical data |
REST API Endpoints
Authentication
| Method | Path | Description |
|---|---|---|
| POST | /api/auth |
Login (JWT) |
| POST | /loginComponent |
Component token (15min) |
| POST | /loginComponent1Year |
1-year token |
| GET | /refresh_token |
Refresh JWT |
Discovery
| Method | Path | Description |
|---|---|---|
| GET | /runDiscovery |
Trigger immediate metrics collection |
| GET | /getProcessByPort/:port |
Get process using a specific port |
| POST | /computeThreshold |
Calculate auto-baseline thresholds |
Data Access
| Method | Path | Description |
|---|---|---|
| GET | /api/db/:dbname/bucket/:bucket/key/:key |
Get specific metric |
| GET | /v1/db/:dbname/bucket/:bucket/all |
All keys/values |
| GET | /v1/db/:dbname/bucket/:bucket/allJSON |
All data as JSON |
| GET | /api/reportSysMetricsGraph/:start/:end |
System metrics graph |
| GET | /:type/reportGraph/:key/:start/:end |
Process metrics graph |
Settings
| Method | Path | Description |
|---|---|---|
| GET | /api/setting |
Get current config |
| POST | /updateSetting |
Update config |
| GET | /setting |
Get settings (encrypted) |
Health
| Method | Path | Description |
|---|---|---|
| GET | /ping |
Health check |
| GET | /uptime |
Service uptime |
| GET | /api/metrics |
Current system metrics |
| GET | /docs |
Swagger documentation |
Backup & Recovery
| Method | Path | Description |
|---|---|---|
| POST | /backupDatabase |
Manual backup |
| POST | /reinitDatabase |
Reset databases |
| GET | /api/backupKV |
Backup via API |
| GET | /api/reinitKV |
Reinitialize via API |
Certificates
| Method | Path | Description |
|---|---|---|
| GET | /reloadCertificates |
Reload TLS certificates |
| GET | /getCert |
Get TLS certificate |
| POST | /getCertFile/:filename |
Receive certificate file |
Logs
| Method | Path | Description |
|---|---|---|
| GET | /discovery/logfile/:key/:filename |
Download log file |
| GET | /partServerlogfile/:nbbytes |
Stream recent log entries |
| GET | /serverlogfiles/:filename |
Download log archive |