fix: reduce syslog flooding by downgrading routine logs to debug level
Addresses issue #861 - syslog flooded on docker host Many routine operational messages were being logged at INFO level, causing excessive log volume when monitoring multiple VMs/containers. These messages are now logged at DEBUG level: - Guest threshold checking (every guest, every poll cycle) - Storage threshold checking (every storage, every poll cycle) - Host agent linking messages - Filesystem inclusion in disk calculation - Guest agent disk usage replacement - Polling start/completion messages - Alert cleanup and save messages Users can set LOG_LEVEL=debug to see these messages if needed for troubleshooting. The default INFO level now produces significantly less log output. Also updated documentation in CONFIGURATION.md and DOCKER.md to: - Clarify what each log level includes - Add tip about using LOG_LEVEL=warn for minimal logging
This commit is contained in:
parent
c97dffb81a
commit
f29d8b1b43
5 changed files with 36 additions and 23 deletions
|
|
@ -87,8 +87,19 @@ Environment variables take precedence over `system.json`.
|
|||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `FRONTEND_PORT` | Public listening port | `7655` |
|
||||
| `LOG_LEVEL` | Log verbosity (`debug`, `info`, `warn`, `error`) | `info` |
|
||||
| `LOG_LEVEL` | Log verbosity (see below) | `info` |
|
||||
| `LOG_FORMAT` | Log output format (`auto`, `json`, `console`) | `auto` |
|
||||
|
||||
#### Log Levels
|
||||
|
||||
| Level | Description |
|
||||
|-------|-------------|
|
||||
| `error` | Only errors and critical issues |
|
||||
| `warn` | Errors + warnings (recommended for minimal logging) |
|
||||
| `info` | Standard operational messages (startup, connections, alerts) |
|
||||
| `debug` | Verbose output including per-guest/storage polling details |
|
||||
|
||||
> **Tip**: If your syslog is being flooded with Pulse messages, set `LOG_LEVEL=warn` to significantly reduce log volume while still capturing important events.
|
||||
| `PULSE_PUBLIC_URL` | Public URL for notifications/OIDC | `""` |
|
||||
| `ALLOWED_ORIGINS` | CORS allowed domains | `""` (Same origin) |
|
||||
| `DISCOVERY_ENABLED` | Auto-discover nodes | `false` |
|
||||
|
|
|
|||
|
|
@ -57,7 +57,9 @@ Pulse is configured via environment variables.
|
|||
| `API_TOKENS` | Comma-separated API tokens | *(unset)* |
|
||||
| `DISCOVERY_SUBNET` | Custom CIDR to scan | *(auto)* |
|
||||
| `ALLOWED_ORIGINS` | CORS allowed domains | *(none)* |
|
||||
| `LOG_LEVEL` | Log verbosity | `info` |
|
||||
| `LOG_LEVEL` | Log verbosity (`debug`, `info`, `warn`, `error`) | `info` |
|
||||
|
||||
> **Tip**: Set `LOG_LEVEL=warn` to reduce log volume while still capturing important events.
|
||||
|
||||
<details>
|
||||
<summary><strong>Advanced: Resource Limits & Healthcheck</strong></summary>
|
||||
|
|
|
|||
|
|
@ -2057,7 +2057,7 @@ func (m *Manager) CheckGuest(guest interface{}, instanceName string) {
|
|||
|
||||
// Debug logging for high memory VMs
|
||||
if memUsage > 85 {
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("vm", name).
|
||||
Float64("memUsage", memUsage).
|
||||
Str("status", status).
|
||||
|
|
@ -2100,7 +2100,7 @@ func (m *Manager) CheckGuest(guest interface{}, instanceName string) {
|
|||
|
||||
monitorOnly := settings.MonitorOnly
|
||||
if monitorOnly || m.guestHasMonitorOnlyAlerts(guestID) {
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("guest", name).
|
||||
Bool("monitorOnly", monitorOnly).
|
||||
Msg("Pulse monitor-only status applied")
|
||||
|
|
@ -2185,7 +2185,7 @@ func (m *Manager) CheckGuest(guest interface{}, instanceName string) {
|
|||
}
|
||||
|
||||
// Check each metric
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("guest", name).
|
||||
Float64("cpu", cpu).
|
||||
Float64("memory", memUsage).
|
||||
|
|
@ -4341,7 +4341,7 @@ func (m *Manager) CheckStorage(storage models.Storage) {
|
|||
// Check usage if storage has valid data (even if not currently active on this node)
|
||||
// In clusters, storage may show as inactive on nodes where it's not currently mounted
|
||||
// but we still want to alert on high usage
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("storage", storage.Name).
|
||||
Str("id", storage.ID).
|
||||
Float64("usage", storage.Usage).
|
||||
|
|
@ -8140,7 +8140,7 @@ func (m *Manager) SaveActiveAlerts() error {
|
|||
return fmt.Errorf("failed to rename active alerts file: %w", err)
|
||||
}
|
||||
|
||||
log.Info().Int("count", len(alerts)).Msg("Saved active alerts to disk")
|
||||
log.Debug().Int("count", len(alerts)).Msg("Saved active alerts to disk")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -8316,7 +8316,7 @@ func (m *Manager) CleanupAlertsForNodes(existingNodes map[string]bool) {
|
|||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Int("totalAlerts", len(m.activeAlerts)).
|
||||
Int("existingNodes", len(existingNodes)).
|
||||
Interface("nodes", existingNodes).
|
||||
|
|
@ -8349,7 +8349,7 @@ func (m *Manager) CleanupAlertsForNodes(existingNodes map[string]bool) {
|
|||
}
|
||||
|
||||
if removedCount > 0 {
|
||||
log.Info().Int("removed", removedCount).Int("remaining", len(m.activeAlerts)).Msg("Cleaned up alerts for non-existent nodes")
|
||||
log.Debug().Int("removed", removedCount).Int("remaining", len(m.activeAlerts)).Msg("Cleaned up alerts for non-existent nodes")
|
||||
// Save the cleaned up state
|
||||
go func() {
|
||||
defer func() {
|
||||
|
|
|
|||
|
|
@ -2219,7 +2219,7 @@ func (m *Monitor) ApplyHostReport(report agentshost.Report, tokenRecord *config.
|
|||
linkedNodeID, linkedVMID, linkedContainerID := m.findLinkedProxmoxEntity(hostname)
|
||||
if linkedNodeID != "" {
|
||||
host.LinkedNodeID = linkedNodeID
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("hostId", identifier).
|
||||
Str("hostname", hostname).
|
||||
Str("linkedNodeId", linkedNodeID).
|
||||
|
|
@ -2227,7 +2227,7 @@ func (m *Monitor) ApplyHostReport(report agentshost.Report, tokenRecord *config.
|
|||
}
|
||||
if linkedVMID != "" {
|
||||
host.LinkedVMID = linkedVMID
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("hostId", identifier).
|
||||
Str("hostname", hostname).
|
||||
Str("linkedVmId", linkedVMID).
|
||||
|
|
@ -2235,7 +2235,7 @@ func (m *Monitor) ApplyHostReport(report agentshost.Report, tokenRecord *config.
|
|||
}
|
||||
if linkedContainerID != "" {
|
||||
host.LinkedContainerID = linkedContainerID
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("hostId", identifier).
|
||||
Str("hostname", hostname).
|
||||
Str("linkedContainerId", linkedContainerID).
|
||||
|
|
@ -5837,7 +5837,7 @@ func (m *Monitor) pollPVEInstance(ctx context.Context, instanceName string, clie
|
|||
// When the instance is part of a cluster, the cluster name is used for guest IDs to prevent duplicates
|
||||
// when multiple cluster nodes are configured as separate PVE instances.
|
||||
func (m *Monitor) pollVMsAndContainersEfficient(ctx context.Context, instanceName string, clusterName string, isCluster bool, client PVEClientInterface, nodeEffectiveStatus map[string]string) bool {
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Str("clusterName", clusterName).
|
||||
Bool("isCluster", isCluster).
|
||||
|
|
@ -6189,7 +6189,7 @@ func (m *Monitor) pollVMsAndContainersEfficient(ctx context.Context, instanceNam
|
|||
}
|
||||
|
||||
if len(includedFS) > 0 {
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Str("vm", res.Name).
|
||||
Int("vmid", res.VMID).
|
||||
|
|
@ -6223,7 +6223,7 @@ func (m *Monitor) pollVMsAndContainersEfficient(ctx context.Context, instanceNam
|
|||
diskFree = totalBytes - usedBytes
|
||||
diskUsage = safePercentage(float64(usedBytes), float64(totalBytes))
|
||||
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Str("vm", res.Name).
|
||||
Int("vmid", res.VMID).
|
||||
|
|
@ -6596,7 +6596,7 @@ func (m *Monitor) pollVMsAndContainersEfficient(ctx context.Context, instanceNam
|
|||
nodesWithResources[res.Node] = true
|
||||
}
|
||||
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Int("nodesInResources", len(nodesWithResources)).
|
||||
Int("totalVMsFromResources", len(allVMs)).
|
||||
|
|
@ -6719,7 +6719,7 @@ func (m *Monitor) pollVMsAndContainersEfficient(ctx context.Context, instanceNam
|
|||
|
||||
m.pollReplicationStatus(ctx, instanceName, client, allVMs)
|
||||
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Int("vms", len(allVMs)).
|
||||
Int("containers", len(allContainers)).
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ func (m *Monitor) pollVMsWithNodes(ctx context.Context, instanceName string, clu
|
|||
}
|
||||
}
|
||||
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Int("totalNodes", len(nodes)).
|
||||
Int("onlineNodes", onlineNodes).
|
||||
|
|
@ -864,7 +864,7 @@ func (m *Monitor) pollVMsWithNodes(ctx context.Context, instanceName string, clu
|
|||
}
|
||||
|
||||
duration := time.Since(startTime)
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Int("totalVMs", len(allVMs)).
|
||||
Int("successfulNodes", successfulNodes).
|
||||
|
|
@ -913,7 +913,7 @@ func (m *Monitor) pollContainersWithNodes(ctx context.Context, instanceName stri
|
|||
}
|
||||
}
|
||||
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Int("totalNodes", len(nodes)).
|
||||
Int("onlineNodes", onlineNodes).
|
||||
|
|
@ -1173,7 +1173,7 @@ func (m *Monitor) pollContainersWithNodes(ctx context.Context, instanceName stri
|
|||
}
|
||||
|
||||
duration := time.Since(startTime)
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Int("totalContainers", len(allContainers)).
|
||||
Int("successfulNodes", successfulNodes).
|
||||
|
|
@ -1236,7 +1236,7 @@ func (m *Monitor) pollStorageWithNodes(ctx context.Context, instanceName string,
|
|||
}
|
||||
}
|
||||
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Int("totalNodes", len(nodes)).
|
||||
Int("onlineNodes", onlineNodes).
|
||||
|
|
@ -1623,7 +1623,7 @@ func (m *Monitor) pollStorageWithNodes(ctx context.Context, instanceName string,
|
|||
Int("failedNodes", failedNodes).
|
||||
Msg("All nodes failed to retrieve storage - check Proxmox API permissions for Datastore.Audit on all storage")
|
||||
} else {
|
||||
log.Info().
|
||||
log.Debug().
|
||||
Str("instance", instanceName).
|
||||
Int("totalStorage", len(allStorage)).
|
||||
Int("successfulNodes", successfulNodes).
|
||||
|
|
|
|||
Loading…
Reference in a new issue