diff --git a/docs/guide/alerts-and-webhooks.md b/docs/guide/alerts-and-webhooks.md index 1d7636f9..378c947c 100644 --- a/docs/guide/alerts-and-webhooks.md +++ b/docs/guide/alerts-and-webhooks.md @@ -176,11 +176,11 @@ Metric alerts fire when a container's CPU or memory usage crosses a threshold. T Available properties: -| Property | Type | Description | -| ------------- | ------ | ----------------------------------------------- | -| `cpu` | number | CPU usage percentage (0–100, per core-adjusted) | -| `memory` | number | Memory usage percentage (0–100) | -| `memoryUsage` | number | Memory usage in bytes | +| Property | Type | Description | +| ------------- | ------ | --------------------------------------------- | +| `cpu` | number | CPU usage percentage (0–100), matching the UI | +| `memory` | number | Memory usage percentage (0–100) | +| `memoryUsage` | number | Memory usage in bytes | ### Cooldown & Sample Window diff --git a/internal/notification/processing.go b/internal/notification/processing.go index d849a683..83f61d3d 100644 --- a/internal/notification/processing.go +++ b/internal/notification/processing.go @@ -114,8 +114,18 @@ func (m *Manager) processStatEvents() { // processStatEvent processes a single stat event and sends notifications for matching metric subscriptions func (m *Manager) processStatEvent(event *ContainerStatEvent) { + // Normalize CPU by core count so alerts report overall load (0-100%), + // matching the UI. Stat.CPUPercent is per-core (100% = one full core). + cores := event.Container.CPULimit + if cores <= 0 { + cores = float64(event.Host.NCPU) + } + if cores <= 0 { + cores = 1 + } + notificationStat := types.NotificationStat{ - CPUPercent: event.Stat.CPUPercent, + CPUPercent: event.Stat.CPUPercent / cores, MemoryPercent: event.Stat.MemoryPercent, MemoryUsage: event.Stat.MemoryUsage, Mounts: FromContainerMounts(event.Container), @@ -154,8 +164,8 @@ func (m *Manager) processStatEvent(event *ContainerStatEvent) { log.Debug(). Str("containerID", event.Stat.ID). - Float64("cpu", event.Stat.CPUPercent). - Float64("memory", event.Stat.MemoryPercent). + Float64("cpu", notificationStat.CPUPercent). + Float64("memory", notificationStat.MemoryPercent). Str("subscription", sub.Name). Msg("Metric alert triggered")