mirror of https://github.com/portainer/portainer
				
				
				
			feat(dashboard): add health status to home page and dashboard (#3489)
* feat(dashboard): add health status to home page and dashboard * fix(dashboard): code review updates, using builtin for substring searchpull/3549/head
							parent
							
								
									cc8d3c8639
								
							
						
					
					
						commit
						6f59f130a1
					
				| 
						 | 
				
			
			@ -3,6 +3,7 @@ package docker
 | 
			
		|||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"log"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
| 
						 | 
				
			
			@ -126,6 +127,8 @@ func snapshotContainers(snapshot *portainer.Snapshot, cli *client.Client) error
 | 
			
		|||
 | 
			
		||||
	runningContainers := 0
 | 
			
		||||
	stoppedContainers := 0
 | 
			
		||||
	healthyContainers := 0
 | 
			
		||||
	unhealthyContainers := 0
 | 
			
		||||
	stacks := make(map[string]struct{})
 | 
			
		||||
	for _, container := range containers {
 | 
			
		||||
		if container.State == "exited" {
 | 
			
		||||
| 
						 | 
				
			
			@ -134,6 +137,12 @@ func snapshotContainers(snapshot *portainer.Snapshot, cli *client.Client) error
 | 
			
		|||
			runningContainers++
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if strings.Contains(container.Status, "(healthy)") {
 | 
			
		||||
			healthyContainers++
 | 
			
		||||
		} else if strings.Contains(container.Status, "(unhealthy)") {
 | 
			
		||||
			unhealthyContainers++
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for k, v := range container.Labels {
 | 
			
		||||
			if k == "com.docker.compose.project" {
 | 
			
		||||
				stacks[v] = struct{}{}
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +152,8 @@ func snapshotContainers(snapshot *portainer.Snapshot, cli *client.Client) error
 | 
			
		|||
 | 
			
		||||
	snapshot.RunningContainerCount = runningContainers
 | 
			
		||||
	snapshot.StoppedContainerCount = stoppedContainers
 | 
			
		||||
	snapshot.HealthyContainerCount = healthyContainers
 | 
			
		||||
	snapshot.UnhealthyContainerCount = unhealthyContainers
 | 
			
		||||
	snapshot.StackCount += len(stacks)
 | 
			
		||||
	snapshot.SnapshotRaw.Containers = containers
 | 
			
		||||
	return nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -397,6 +397,8 @@ type (
 | 
			
		|||
		TotalMemory             int64       `json:"TotalMemory"`
 | 
			
		||||
		RunningContainerCount   int         `json:"RunningContainerCount"`
 | 
			
		||||
		StoppedContainerCount   int         `json:"StoppedContainerCount"`
 | 
			
		||||
		HealthyContainerCount   int         `json:"HealthyContainerCount"`
 | 
			
		||||
		UnhealthyContainerCount int         `json:"UnhealthyContainerCount"`
 | 
			
		||||
		VolumeCount             int         `json:"VolumeCount"`
 | 
			
		||||
		ImageCount              int         `json:"ImageCount"`
 | 
			
		||||
		ServiceCount            int         `json:"ServiceCount"`
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -248,6 +248,22 @@ angular.module('portainer.docker')
 | 
			
		|||
    }).length;
 | 
			
		||||
  };
 | 
			
		||||
})
 | 
			
		||||
.filter('healthycontainers', function () {
 | 
			
		||||
  'use strict';
 | 
			
		||||
  return function healthyContainersFilter(containers) {
 | 
			
		||||
    return containers.filter(function (container) {
 | 
			
		||||
      return container.Status === 'healthy';
 | 
			
		||||
    }).length;
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
.filter('unhealthycontainers', function () {
 | 
			
		||||
  'use strict';
 | 
			
		||||
  return function unhealthyContainersFilter(containers) {
 | 
			
		||||
    return containers.filter(function (container) {
 | 
			
		||||
      return container.Status === 'unhealthy';
 | 
			
		||||
    }).length;
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
.filter('imagestotalsize', function () {
 | 
			
		||||
  'use strict';
 | 
			
		||||
  return function (images) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -109,9 +109,13 @@
 | 
			
		|||
          <div class="widget-icon blue pull-left">
 | 
			
		||||
            <i class="fa fa-server"></i>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="pull-right">
 | 
			
		||||
            <div><i class="fa fa-heartbeat space-right green-icon"></i>{{ containers | runningcontainers }} running</div>
 | 
			
		||||
            <div><i class="fa fa-heartbeat space-right red-icon"></i>{{ containers | stoppedcontainers }} stopped</div>
 | 
			
		||||
          <div class="pull-right"style="padding-left: 5px;">
 | 
			
		||||
            <div><i class="fa fa-power-off space-right green-icon"></i>{{ containers | runningcontainers }} running</div>
 | 
			
		||||
            <div><i class="fa fa-power-off space-right red-icon"></i>{{ containers | stoppedcontainers }} stopped</div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="pull-right" style="padding-right: 5px;">
 | 
			
		||||
            <div><i class="fa fa-heartbeat space-right green-icon"></i>{{ containers | healthycontainers }} healthy</div>
 | 
			
		||||
            <div><i class="fa fa-heartbeat space-right orange-icon"></i>{{ containers | unhealthycontainers }} unhealthy</div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="title">{{ containers.length }}</div>
 | 
			
		||||
          <div class="comment">{{ containers.length === 1 ? 'Container' : 'Containers' }}</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,8 +51,11 @@
 | 
			
		|||
              <i class="fa fa-server space-right" aria-hidden="true"></i>{{ $ctrl.model.Snapshots[0].RunningContainerCount + $ctrl.model.Snapshots[0].StoppedContainerCount }} {{ $ctrl.model.Snapshots[0].RunningContainerCount + $ctrl.model.Snapshots[0].StoppedContainerCount === 1 ? 'container' : 'containers' }}
 | 
			
		||||
              <span ng-if="$ctrl.model.Snapshots[0].RunningContainerCount > 0 || $ctrl.model.Snapshots[0].StoppedContainerCount > 0">
 | 
			
		||||
                -
 | 
			
		||||
                <i class="fa fa-heartbeat green-icon" aria-hidden="true"></i> {{ $ctrl.model.Snapshots[0].RunningContainerCount }}
 | 
			
		||||
                <i class="fa fa-heartbeat red-icon" aria-hidden="true"></i> {{ $ctrl.model.Snapshots[0].StoppedContainerCount }}
 | 
			
		||||
                <i class="fa fa-power-off green-icon" aria-hidden="true"></i> {{ $ctrl.model.Snapshots[0].RunningContainerCount }}
 | 
			
		||||
                <i class="fa fa-power-off red-icon" aria-hidden="true"></i> {{ $ctrl.model.Snapshots[0].StoppedContainerCount }}
 | 
			
		||||
                /
 | 
			
		||||
                <i class="fa fa-heartbeat green-icon" aria-hidden="true"></i> {{ $ctrl.model.Snapshots[0].HealthyContainerCount }}
 | 
			
		||||
                <i class="fa fa-heartbeat orange-icon" aria-hidden="true"></i> {{ $ctrl.model.Snapshots[0].UnhealthyContainerCount }}
 | 
			
		||||
              </span>
 | 
			
		||||
            </span>
 | 
			
		||||
            <span style="padding: 0 7px 0 7px;">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue