diff --git a/api/nodes.go b/api/nodes.go index 44e158283..d6a1d6b59 100644 --- a/api/nodes.go +++ b/api/nodes.go @@ -409,6 +409,7 @@ func (n *Nodes) Stats(nodeID string, q *QueryOptions) (*HostStats, error) { if _, err := n.client.query(path, &resp, q); err != nil { return nil, err } + return &resp, nil } @@ -573,6 +574,7 @@ type HostStats struct { Memory *HostMemoryStats CPU []*HostCPUStats DiskStats []*HostDiskStats + DeviceStats []*DeviceGroupStats Uptime uint64 CPUTicksConsumed float64 } @@ -601,6 +603,67 @@ type HostDiskStats struct { InodesUsedPercent float64 } +// DeviceGroupStats contains statistics for each device of a particular +// device group, identified by the vendor, type and name of the device. +type DeviceGroupStats struct { + Vendor string + Type string + Name string + + // InstanceStats is a mapping of each device ID to its statistics. + InstanceStats map[string]*DeviceStats +} + +// DeviceStats is the statistics for an individual device +type DeviceStats struct { + // Summary exposes a single summary metric that should be the most + // informative to users. + Summary *StatValue + + // Stats contains the verbose statistics for the device. + Stats *StatObject + + // Timestamp is the time the statistics were collected. + Timestamp time.Time +} + +// StatObject is a collection of statistics either exposed at the top +// level or via nested StatObjects. +type StatObject struct { + // Nested is a mapping of object name to a nested stats object. + Nested map[string]*StatObject + + // Attributes is a mapping of statistic name to its value. + Attributes map[string]*StatValue +} + +// StatValue exposes the values of a particular statistic. The value may be of +// type float, integer, string or boolean. Numeric types can be exposed as a +// single value or as a fraction. +type StatValue struct { + // FloatNumeratorVal exposes a floating point value. If denominator is set + // it is assumed to be a fractional value, otherwise it is a scalar. + FloatNumeratorVal *float64 `json:",omitempty"` + FloatDenominatorVal *float64 `json:",omitempty"` + + // IntNumeratorVal exposes a int value. If denominator is set it is assumed + // to be a fractional value, otherwise it is a scalar. + IntNumeratorVal *int64 `json:",omitempty"` + IntDenominatorVal *int64 `json:",omitempty"` + + // StringVal exposes a string value. These are likely annotations. + StringVal *string `json:",omitempty"` + + // BoolVal exposes a boolean statistic. + BoolVal *bool `json:",omitempty"` + + // Unit gives the unit type: °F, %, MHz, MB, etc. + Unit string `json:",omitempty"` + + // Desc provides a human readable description of the statistic. + Desc string `json:",omitempty"` +} + // NodeListStub is a subset of information returned during // node list operations. type NodeListStub struct { diff --git a/client/stats/cpu_test.go b/client/stats/cpu_test.go index eedd66e47..024fba93a 100644 --- a/client/stats/cpu_test.go +++ b/client/stats/cpu_test.go @@ -29,7 +29,7 @@ func TestHostStats_CPU(t *testing.T) { logger := testlog.HCLogger(t) cwd, err := os.Getwd() assert.Nil(err) - hs := NewHostStatsCollector(logger, cwd) + hs := NewHostStatsCollector(logger, cwd, nil) // Collect twice so we can calculate percents we need to generate some work // so that the cpu values change diff --git a/client/stats/host.go b/client/stats/host.go index 7a5be3322..28d61906d 100644 --- a/client/stats/host.go +++ b/client/stats/host.go @@ -204,6 +204,10 @@ func (h *HostStatsCollector) collectDiskStats() ([]*DiskStats, error) { } func (h *HostStatsCollector) collectDeviceGroupStats() []*DeviceGroupStats { + if h.deviceStatsCollector == nil { + return []*DeviceGroupStats{} + } + return h.deviceStatsCollector() }