Fix Container Health Status Not Displayed Correctly in Dashboard #12319 (#12828)

community
dergreg 2025-08-26 22:59:33 +02:00 committed by GitHub
parent 3a727d24ce
commit daf97624b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 30 additions and 56 deletions

View File

@ -1,6 +1,11 @@
package docker
package stats
import "github.com/docker/docker/api/types"
import (
"strings"
"github.com/docker/docker/api/types"
"github.com/rs/zerolog/log"
)
type ContainerStats struct {
Running int `json:"running"`
@ -13,18 +18,20 @@ type ContainerStats struct {
func CalculateContainerStats(containers []types.Container) ContainerStats {
var running, stopped, healthy, unhealthy int
for _, container := range containers {
log.Debug().Str("containerId", container.ID).Str("state", container.State).Str("status", container.Status).Msg("Container info")
switch container.State {
case "running":
running++
case "healthy":
running++
healthy++
case "unhealthy":
running++
unhealthy++
case "exited", "stopped":
stopped++
}
if strings.Contains(container.Status, "(healthy)") {
healthy++
} else if strings.Contains(container.Status, "(unhealthy)") {
unhealthy++
}
}
return ContainerStats{

View File

@ -1,4 +1,4 @@
package docker
package stats
import (
"testing"
@ -10,11 +10,11 @@ import (
func TestCalculateContainerStats(t *testing.T) {
containers := []types.Container{
{State: "running"},
{State: "running"},
{State: "running", Status: "Up 5 minutes (healthy)"},
{State: "exited"},
{State: "stopped"},
{State: "healthy"},
{State: "unhealthy"},
{State: "running", Status: "Up 10 minutes"},
{State: "running", Status: "Up about an hour (unhealthy)"},
}
stats := CalculateContainerStats(containers)

View File

@ -11,7 +11,7 @@ import (
"github.com/docker/docker/api/types/volume"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/dataservices"
"github.com/portainer/portainer/api/docker"
"github.com/portainer/portainer/api/docker/stats"
"github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/handler/docker/utils"
"github.com/portainer/portainer/api/http/middlewares"
@ -26,12 +26,12 @@ type imagesCounters struct {
}
type dashboardResponse struct {
Containers docker.ContainerStats `json:"containers"`
Services int `json:"services"`
Images imagesCounters `json:"images"`
Volumes int `json:"volumes"`
Networks int `json:"networks"`
Stacks int `json:"stacks"`
Containers stats.ContainerStats `json:"containers"`
Services int `json:"services"`
Images imagesCounters `json:"images"`
Volumes int `json:"volumes"`
Networks int `json:"networks"`
Stacks int `json:"stacks"`
}
// @id dockerDashboard
@ -150,7 +150,7 @@ func (h *Handler) dashboard(w http.ResponseWriter, r *http.Request) *httperror.H
Size: totalSize,
},
Services: len(services),
Containers: docker.CalculateContainerStats(containers),
Containers: stats.CalculateContainerStats(containers),
Networks: len(networks),
Volumes: len(volumes),
Stacks: stackCount,

View File

@ -30,7 +30,7 @@ export function ContainerStatus({ stats }: Props) {
{stats.healthy} healthy
</div>
<div className="vertical-center space-right">
<Icon icon={Heart} mode="danger" size="sm" />
<Icon icon={Heart} mode="warning" size="sm" />
{stats.unhealthy} unhealthy
</div>
</div>

View File

@ -10,6 +10,7 @@ import (
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/docker/consts"
"github.com/portainer/portainer/api/docker/stats"
edgeutils "github.com/portainer/portainer/pkg/edge"
networkingutils "github.com/portainer/portainer/pkg/networking"
@ -207,7 +208,7 @@ func dockerSnapshotContainers(snapshot *portainer.DockerSnapshot, cli *client.Cl
snapshot.GpuUseAll = gpuUseAll
snapshot.GpuUseList = gpuUseList
stats := calculateContainerStats(containers)
stats := stats.CalculateContainerStats(containers)
snapshot.ContainerCount = stats.Total
snapshot.RunningContainerCount = stats.Running
@ -344,37 +345,3 @@ func isPodman(version types.Version) bool {
return false
}
type ContainerStats struct {
Running int
Stopped int
Healthy int
Unhealthy int
Total int
}
func calculateContainerStats(containers []types.Container) ContainerStats {
var running, stopped, healthy, unhealthy int
for _, container := range containers {
switch container.State {
case "running":
running++
case "healthy":
running++
healthy++
case "unhealthy":
running++
unhealthy++
case "exited", "stopped":
stopped++
}
}
return ContainerStats{
Running: running,
Stopped: stopped,
Healthy: healthy,
Unhealthy: unhealthy,
Total: len(containers),
}
}