diff --git a/command/alloc_status.go b/command/alloc_status.go index 773791c59..181f8ad24 100644 --- a/command/alloc_status.go +++ b/command/alloc_status.go @@ -488,6 +488,7 @@ func (c *AllocStatusCommand) outputTaskResources(alloc *api.Allocation, task str addr = append(addr, fmt.Sprintf("%v: %v:%v\n", port.Label, nw.IP, port.Value)) } } + var resourcesOutput []string resourcesOutput = append(resourcesOutput, "CPU|Memory|Disk|IOPS|Addresses") firstAddr := "" @@ -498,6 +499,8 @@ func (c *AllocStatusCommand) outputTaskResources(alloc *api.Allocation, task str // Display the rolled up stats. If possible prefer the live statistics cpuUsage := strconv.Itoa(*resource.CPU) memUsage := humanize.IBytes(uint64(*resource.MemoryMB * bytesPerMegabyte)) + var deviceStats []*api.DeviceGroupStats + if stats != nil { if ru, ok := stats.Tasks[task]; ok && ru != nil && ru.ResourceUsage != nil { if cs := ru.ResourceUsage.CpuStats; cs != nil { @@ -506,6 +509,7 @@ func (c *AllocStatusCommand) outputTaskResources(alloc *api.Allocation, task str if ms := ru.ResourceUsage.MemoryStats; ms != nil { memUsage = fmt.Sprintf("%v/%v", humanize.IBytes(ms.RSS), memUsage) } + deviceStats = ru.ResourceUsage.DeviceStats } } resourcesOutput = append(resourcesOutput, fmt.Sprintf("%v MHz|%v|%v|%v|%v", @@ -519,6 +523,11 @@ func (c *AllocStatusCommand) outputTaskResources(alloc *api.Allocation, task str } c.Ui.Output(formatListWithSpaces(resourcesOutput)) + if len(deviceStats) > 0 { + c.Ui.Output("") + c.Ui.Output(formatList(getDeviceResources(deviceStats))) + } + if stats != nil { if ru, ok := stats.Tasks[task]; ok && ru != nil && displayStats && ru.ResourceUsage != nil { c.Ui.Output("") @@ -532,6 +541,8 @@ func (c *AllocStatusCommand) outputTaskResources(alloc *api.Allocation, task str func (c *AllocStatusCommand) outputVerboseResourceUsage(task string, resourceUsage *api.ResourceUsage) { memoryStats := resourceUsage.MemoryStats cpuStats := resourceUsage.CpuStats + deviceStats := resourceUsage.DeviceStats + if memoryStats != nil && len(memoryStats.Measured) > 0 { c.Ui.Output("Memory Stats") @@ -593,6 +604,12 @@ func (c *AllocStatusCommand) outputVerboseResourceUsage(task string, resourceUsa out[1] = strings.Join(measuredStats, "|") c.Ui.Output(formatList(out)) } + + if len(deviceStats) > 0 { + c.Ui.Output("Device Stats") + + printDeviceStats(c.Ui, deviceStats) + } } // shortTaskStatus prints out the current state of each task. diff --git a/command/helper_stats.go b/command/helper_stats.go index cce511283..4ffac8ddd 100644 --- a/command/helper_stats.go +++ b/command/helper_stats.go @@ -46,7 +46,8 @@ func formatDeviceStats(stat *api.StatObject, keyPrefix string, result *[]string) } } -// getDeviceResources returns a list of devices and their statistics summary +// getDeviceResourcesForNode returns a list of devices and their statistics summary +// and tracks devices without statistics func getDeviceResourcesForNode(deviceGroupStats []*api.DeviceGroupStats, node *api.Node) []string { statsSummaryMap := buildDeviceStatsSummaryMap(deviceGroupStats) @@ -66,6 +67,18 @@ func getDeviceResourcesForNode(deviceGroupStats []*api.DeviceGroupStats, node *a return devices } +// getDeviceResources returns alist of devices and their statistics summary +func getDeviceResources(deviceGroupStats []*api.DeviceGroupStats) []string { + statsSummaryMap := buildDeviceStatsSummaryMap(deviceGroupStats) + + result := make([]string, 0, len(statsSummaryMap)) + for id, stats := range statsSummaryMap { + result = append(result, id+"|"+stats.String()) + } + + return result +} + func printDeviceStats(ui cli.Ui, deviceGroupStats []*api.DeviceGroupStats) { isFirst := true for _, dg := range deviceGroupStats { diff --git a/command/helper_stats_test.go b/command/helper_stats_test.go index d37e6261b..e1516c92f 100644 --- a/command/helper_stats_test.go +++ b/command/helper_stats_test.go @@ -201,3 +201,52 @@ func TestNodeStatusCommand_GetDeviceResourcesForNode(t *testing.T) { assert.Equal(t, expected, formattedDevices) } + +func TestNodeStatusCommand_GetDeviceResources(t *testing.T) { + hostDeviceStats := []*api.DeviceGroupStats{ + { + Vendor: "vendor1", + Type: "type1", + Name: "name1", + InstanceStats: map[string]*api.DeviceStats{ + "id1": { + Summary: &api.StatValue{ + StringVal: helper.StringToPtr("stat1"), + }, + }, + "id2": { + Summary: &api.StatValue{ + IntNumeratorVal: helper.Int64ToPtr(2), + }, + }, + }, + }, + { + Vendor: "vendor2", + Type: "type2", + InstanceStats: map[string]*api.DeviceStats{ + "id1": { + Summary: &api.StatValue{ + StringVal: helper.StringToPtr("stat3"), + }, + }, + "id2": { + Summary: &api.StatValue{ + IntNumeratorVal: helper.Int64ToPtr(4), + }, + }, + }, + }, + } + + formattedDevices := getDeviceResources(hostDeviceStats) + sort.Strings(formattedDevices) + expected := []string{ + "vendor1/type1/name1[id1]|stat1", + "vendor1/type1/name1[id2]|2", + "vendor2/type2[id1]|stat3", + "vendor2/type2[id2]|4", + } + + assert.Equal(t, expected, formattedDevices) +}