mirror of https://github.com/portainer/portainer
parent
3a727d24ce
commit
daf97624b9
|
@ -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 {
|
type ContainerStats struct {
|
||||||
Running int `json:"running"`
|
Running int `json:"running"`
|
||||||
|
@ -13,18 +18,20 @@ type ContainerStats struct {
|
||||||
func CalculateContainerStats(containers []types.Container) ContainerStats {
|
func CalculateContainerStats(containers []types.Container) ContainerStats {
|
||||||
var running, stopped, healthy, unhealthy int
|
var running, stopped, healthy, unhealthy int
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
|
log.Debug().Str("containerId", container.ID).Str("state", container.State).Str("status", container.Status).Msg("Container info")
|
||||||
|
|
||||||
switch container.State {
|
switch container.State {
|
||||||
case "running":
|
case "running":
|
||||||
running++
|
running++
|
||||||
case "healthy":
|
|
||||||
running++
|
|
||||||
healthy++
|
|
||||||
case "unhealthy":
|
|
||||||
running++
|
|
||||||
unhealthy++
|
|
||||||
case "exited", "stopped":
|
case "exited", "stopped":
|
||||||
stopped++
|
stopped++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.Contains(container.Status, "(healthy)") {
|
||||||
|
healthy++
|
||||||
|
} else if strings.Contains(container.Status, "(unhealthy)") {
|
||||||
|
unhealthy++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ContainerStats{
|
return ContainerStats{
|
|
@ -1,4 +1,4 @@
|
||||||
package docker
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -10,11 +10,11 @@ import (
|
||||||
func TestCalculateContainerStats(t *testing.T) {
|
func TestCalculateContainerStats(t *testing.T) {
|
||||||
containers := []types.Container{
|
containers := []types.Container{
|
||||||
{State: "running"},
|
{State: "running"},
|
||||||
{State: "running"},
|
{State: "running", Status: "Up 5 minutes (healthy)"},
|
||||||
{State: "exited"},
|
{State: "exited"},
|
||||||
{State: "stopped"},
|
{State: "stopped"},
|
||||||
{State: "healthy"},
|
{State: "running", Status: "Up 10 minutes"},
|
||||||
{State: "unhealthy"},
|
{State: "running", Status: "Up about an hour (unhealthy)"},
|
||||||
}
|
}
|
||||||
|
|
||||||
stats := CalculateContainerStats(containers)
|
stats := CalculateContainerStats(containers)
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/volume"
|
"github.com/docker/docker/api/types/volume"
|
||||||
portainer "github.com/portainer/portainer/api"
|
portainer "github.com/portainer/portainer/api"
|
||||||
"github.com/portainer/portainer/api/dataservices"
|
"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/errors"
|
||||||
"github.com/portainer/portainer/api/http/handler/docker/utils"
|
"github.com/portainer/portainer/api/http/handler/docker/utils"
|
||||||
"github.com/portainer/portainer/api/http/middlewares"
|
"github.com/portainer/portainer/api/http/middlewares"
|
||||||
|
@ -26,12 +26,12 @@ type imagesCounters struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type dashboardResponse struct {
|
type dashboardResponse struct {
|
||||||
Containers docker.ContainerStats `json:"containers"`
|
Containers stats.ContainerStats `json:"containers"`
|
||||||
Services int `json:"services"`
|
Services int `json:"services"`
|
||||||
Images imagesCounters `json:"images"`
|
Images imagesCounters `json:"images"`
|
||||||
Volumes int `json:"volumes"`
|
Volumes int `json:"volumes"`
|
||||||
Networks int `json:"networks"`
|
Networks int `json:"networks"`
|
||||||
Stacks int `json:"stacks"`
|
Stacks int `json:"stacks"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// @id dockerDashboard
|
// @id dockerDashboard
|
||||||
|
@ -150,7 +150,7 @@ func (h *Handler) dashboard(w http.ResponseWriter, r *http.Request) *httperror.H
|
||||||
Size: totalSize,
|
Size: totalSize,
|
||||||
},
|
},
|
||||||
Services: len(services),
|
Services: len(services),
|
||||||
Containers: docker.CalculateContainerStats(containers),
|
Containers: stats.CalculateContainerStats(containers),
|
||||||
Networks: len(networks),
|
Networks: len(networks),
|
||||||
Volumes: len(volumes),
|
Volumes: len(volumes),
|
||||||
Stacks: stackCount,
|
Stacks: stackCount,
|
||||||
|
|
|
@ -30,7 +30,7 @@ export function ContainerStatus({ stats }: Props) {
|
||||||
{stats.healthy} healthy
|
{stats.healthy} healthy
|
||||||
</div>
|
</div>
|
||||||
<div className="vertical-center space-right">
|
<div className="vertical-center space-right">
|
||||||
<Icon icon={Heart} mode="danger" size="sm" />
|
<Icon icon={Heart} mode="warning" size="sm" />
|
||||||
{stats.unhealthy} unhealthy
|
{stats.unhealthy} unhealthy
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
portainer "github.com/portainer/portainer/api"
|
portainer "github.com/portainer/portainer/api"
|
||||||
"github.com/portainer/portainer/api/docker/consts"
|
"github.com/portainer/portainer/api/docker/consts"
|
||||||
|
"github.com/portainer/portainer/api/docker/stats"
|
||||||
edgeutils "github.com/portainer/portainer/pkg/edge"
|
edgeutils "github.com/portainer/portainer/pkg/edge"
|
||||||
networkingutils "github.com/portainer/portainer/pkg/networking"
|
networkingutils "github.com/portainer/portainer/pkg/networking"
|
||||||
|
|
||||||
|
@ -207,7 +208,7 @@ func dockerSnapshotContainers(snapshot *portainer.DockerSnapshot, cli *client.Cl
|
||||||
snapshot.GpuUseAll = gpuUseAll
|
snapshot.GpuUseAll = gpuUseAll
|
||||||
snapshot.GpuUseList = gpuUseList
|
snapshot.GpuUseList = gpuUseList
|
||||||
|
|
||||||
stats := calculateContainerStats(containers)
|
stats := stats.CalculateContainerStats(containers)
|
||||||
|
|
||||||
snapshot.ContainerCount = stats.Total
|
snapshot.ContainerCount = stats.Total
|
||||||
snapshot.RunningContainerCount = stats.Running
|
snapshot.RunningContainerCount = stats.Running
|
||||||
|
@ -344,37 +345,3 @@ func isPodman(version types.Version) bool {
|
||||||
|
|
||||||
return false
|
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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue