mirror of https://github.com/k3s-io/k3s
Make summary timestamps more granular
parent
86a7a9534a
commit
7a54f94cf4
|
@ -100,10 +100,6 @@ func (sb *summaryBuilder) build() (*Summary, error) {
|
||||||
if !found {
|
if !found {
|
||||||
return nil, fmt.Errorf("Missing stats for root container")
|
return nil, fmt.Errorf("Missing stats for root container")
|
||||||
}
|
}
|
||||||
cstat, found := sb.latestContainerStats(&rootInfo)
|
|
||||||
if !found {
|
|
||||||
return nil, fmt.Errorf("Missing stats for root container")
|
|
||||||
}
|
|
||||||
|
|
||||||
rootStats := sb.containerInfoV2ToStats("", &rootInfo)
|
rootStats := sb.containerInfoV2ToStats("", &rootInfo)
|
||||||
nodeStats := NodeStats{
|
nodeStats := NodeStats{
|
||||||
|
@ -130,7 +126,6 @@ func (sb *summaryBuilder) build() (*Summary, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
summary := Summary{
|
summary := Summary{
|
||||||
Time: unversioned.NewTime(cstat.Timestamp),
|
|
||||||
Node: nodeStats,
|
Node: nodeStats,
|
||||||
Pods: sb.buildSummaryPods(),
|
Pods: sb.buildSummaryPods(),
|
||||||
}
|
}
|
||||||
|
@ -250,15 +245,17 @@ func (sb *summaryBuilder) containerInfoV2ToStats(
|
||||||
name string,
|
name string,
|
||||||
info *cadvisorapiv2.ContainerInfo) ContainerStats {
|
info *cadvisorapiv2.ContainerInfo) ContainerStats {
|
||||||
stats := ContainerStats{
|
stats := ContainerStats{
|
||||||
Name: name,
|
|
||||||
StartTime: unversioned.NewTime(info.Spec.CreationTime),
|
StartTime: unversioned.NewTime(info.Spec.CreationTime),
|
||||||
|
Name: name,
|
||||||
}
|
}
|
||||||
cstat, found := sb.latestContainerStats(info)
|
cstat, found := sb.latestContainerStats(info)
|
||||||
if !found {
|
if !found {
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
if info.Spec.HasCpu {
|
if info.Spec.HasCpu {
|
||||||
cpuStats := CPUStats{}
|
cpuStats := CPUStats{
|
||||||
|
Time: unversioned.NewTime(cstat.Timestamp),
|
||||||
|
}
|
||||||
if cstat.CpuInst != nil {
|
if cstat.CpuInst != nil {
|
||||||
cpuStats.UsageNanoCores = &cstat.CpuInst.Usage.Total
|
cpuStats.UsageNanoCores = &cstat.CpuInst.Usage.Total
|
||||||
}
|
}
|
||||||
|
@ -271,6 +268,7 @@ func (sb *summaryBuilder) containerInfoV2ToStats(
|
||||||
pageFaults := cstat.Memory.ContainerData.Pgfault
|
pageFaults := cstat.Memory.ContainerData.Pgfault
|
||||||
majorPageFaults := cstat.Memory.ContainerData.Pgmajfault
|
majorPageFaults := cstat.Memory.ContainerData.Pgmajfault
|
||||||
stats.Memory = &MemoryStats{
|
stats.Memory = &MemoryStats{
|
||||||
|
Time: unversioned.NewTime(cstat.Timestamp),
|
||||||
UsageBytes: &cstat.Memory.Usage,
|
UsageBytes: &cstat.Memory.Usage,
|
||||||
WorkingSetBytes: &cstat.Memory.WorkingSet,
|
WorkingSetBytes: &cstat.Memory.WorkingSet,
|
||||||
PageFaults: &pageFaults,
|
PageFaults: &pageFaults,
|
||||||
|
@ -304,6 +302,7 @@ func (sb *summaryBuilder) containerInfoV2ToNetworkStats(info *cadvisorapiv2.Cont
|
||||||
txErrors += inter.TxErrors
|
txErrors += inter.TxErrors
|
||||||
}
|
}
|
||||||
return &NetworkStats{
|
return &NetworkStats{
|
||||||
|
Time: unversioned.NewTime(cstat.Timestamp),
|
||||||
RxBytes: &rxBytes,
|
RxBytes: &rxBytes,
|
||||||
RxErrors: &rxErrors,
|
RxErrors: &rxErrors,
|
||||||
TxBytes: &txBytes,
|
TxBytes: &txBytes,
|
||||||
|
@ -353,6 +352,7 @@ func (sb *summaryBuilder) containerInfoV2ToUserDefinedMetrics(info *cadvisorapiv
|
||||||
for _, specVal := range udmMap {
|
for _, specVal := range udmMap {
|
||||||
udm = append(udm, UserDefinedMetric{
|
udm = append(udm, UserDefinedMetric{
|
||||||
UserDefinedMetricDescriptor: specVal.ref,
|
UserDefinedMetricDescriptor: specVal.ref,
|
||||||
|
Time: unversioned.NewTime(specVal.time),
|
||||||
Value: specVal.value,
|
Value: specVal.value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm"
|
"k8s.io/kubernetes/pkg/kubelet/cm"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/leaky"
|
"k8s.io/kubernetes/pkg/kubelet/leaky"
|
||||||
)
|
)
|
||||||
|
@ -44,6 +45,11 @@ const (
|
||||||
offsetNetTxErrors
|
offsetNetTxErrors
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
timestamp = time.Now()
|
||||||
|
creationTime = timestamp.Add(-5 * time.Minute)
|
||||||
|
)
|
||||||
|
|
||||||
func TestBuildSummary(t *testing.T) {
|
func TestBuildSummary(t *testing.T) {
|
||||||
node := api.Node{}
|
node := api.Node{}
|
||||||
node.Name = "FooNode"
|
node.Name = "FooNode"
|
||||||
|
@ -111,6 +117,7 @@ func TestBuildSummary(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
nodeStats := summary.Node
|
nodeStats := summary.Node
|
||||||
assert.Equal(t, "FooNode", nodeStats.NodeName)
|
assert.Equal(t, "FooNode", nodeStats.NodeName)
|
||||||
|
assert.EqualValues(t, testTime(creationTime, seedRoot).Unix(), nodeStats.StartTime.Time.Unix())
|
||||||
checkCPUStats(t, "Node", seedRoot, nodeStats.CPU)
|
checkCPUStats(t, "Node", seedRoot, nodeStats.CPU)
|
||||||
checkMemoryStats(t, "Node", seedRoot, nodeStats.Memory)
|
checkMemoryStats(t, "Node", seedRoot, nodeStats.Memory)
|
||||||
checkNetworkStats(t, "Node", seedRoot, nodeStats.Network)
|
checkNetworkStats(t, "Node", seedRoot, nodeStats.Network)
|
||||||
|
@ -126,6 +133,7 @@ func TestBuildSummary(t *testing.T) {
|
||||||
if !found {
|
if !found {
|
||||||
t.Errorf("Unknown SystemContainer: %q", name)
|
t.Errorf("Unknown SystemContainer: %q", name)
|
||||||
}
|
}
|
||||||
|
assert.EqualValues(t, testTime(creationTime, seed).Unix(), sys.StartTime.Time.Unix(), name+".StartTime")
|
||||||
checkCPUStats(t, name, seed, sys.CPU)
|
checkCPUStats(t, name, seed, sys.CPU)
|
||||||
checkMemoryStats(t, name, seed, sys.Memory)
|
checkMemoryStats(t, name, seed, sys.Memory)
|
||||||
}
|
}
|
||||||
|
@ -145,13 +153,16 @@ func TestBuildSummary(t *testing.T) {
|
||||||
indexCon[con.Name] = con
|
indexCon[con.Name] = con
|
||||||
}
|
}
|
||||||
con := indexCon[cName00]
|
con := indexCon[cName00]
|
||||||
|
assert.EqualValues(t, testTime(creationTime, seedPod0Container0).Unix(), con.StartTime.Time.Unix())
|
||||||
checkCPUStats(t, "container", seedPod0Container0, con.CPU)
|
checkCPUStats(t, "container", seedPod0Container0, con.CPU)
|
||||||
checkMemoryStats(t, "container", seedPod0Container0, con.Memory)
|
checkMemoryStats(t, "container", seedPod0Container0, con.Memory)
|
||||||
|
|
||||||
con = indexCon[cName01]
|
con = indexCon[cName01]
|
||||||
|
assert.EqualValues(t, testTime(creationTime, seedPod0Container1).Unix(), con.StartTime.Time.Unix())
|
||||||
checkCPUStats(t, "container", seedPod0Container1, con.CPU)
|
checkCPUStats(t, "container", seedPod0Container1, con.CPU)
|
||||||
checkMemoryStats(t, "container", seedPod0Container1, con.Memory)
|
checkMemoryStats(t, "container", seedPod0Container1, con.Memory)
|
||||||
|
|
||||||
|
assert.EqualValues(t, testTime(creationTime, seedPod0Infra).Unix(), ps.StartTime.Time.Unix())
|
||||||
checkNetworkStats(t, "Pod", seedPod0Infra, ps.Network)
|
checkNetworkStats(t, "Pod", seedPod0Infra, ps.Network)
|
||||||
|
|
||||||
// Validate Pod1 Results
|
// Validate Pod1 Results
|
||||||
|
@ -231,6 +242,7 @@ func summaryTestContainerInfo(seed int, podName string, podNamespace string, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spec := v2.ContainerSpec{
|
spec := v2.ContainerSpec{
|
||||||
|
CreationTime: testTime(creationTime, seed),
|
||||||
HasCpu: true,
|
HasCpu: true,
|
||||||
HasMemory: true,
|
HasMemory: true,
|
||||||
HasNetwork: true,
|
HasNetwork: true,
|
||||||
|
@ -239,8 +251,9 @@ func summaryTestContainerInfo(seed int, podName string, podNamespace string, con
|
||||||
}
|
}
|
||||||
|
|
||||||
stats := v2.ContainerStats{
|
stats := v2.ContainerStats{
|
||||||
Cpu: &v1.CpuStats{},
|
Timestamp: testTime(timestamp, seed),
|
||||||
CpuInst: &v2.CpuInstStats{},
|
Cpu: &v1.CpuStats{},
|
||||||
|
CpuInst: &v2.CpuInstStats{},
|
||||||
Memory: &v1.MemoryStats{
|
Memory: &v1.MemoryStats{
|
||||||
Usage: uint64(seed + offsetMemUsageBytes),
|
Usage: uint64(seed + offsetMemUsageBytes),
|
||||||
WorkingSet: uint64(seed + offsetMemWorkingSetBytes),
|
WorkingSet: uint64(seed + offsetMemWorkingSetBytes),
|
||||||
|
@ -267,7 +280,12 @@ func summaryTestContainerInfo(seed int, podName string, podNamespace string, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testTime(base time.Time, seed int) time.Time {
|
||||||
|
return base.Add(time.Duration(seed) * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
func checkNetworkStats(t *testing.T, label string, seed int, stats *NetworkStats) {
|
func checkNetworkStats(t *testing.T, label string, seed int, stats *NetworkStats) {
|
||||||
|
assert.EqualValues(t, testTime(timestamp, seed).Unix(), stats.Time.Time.Unix(), label+".Net.Time")
|
||||||
assert.EqualValues(t, seed+offsetNetRxBytes, *stats.RxBytes, label+".Net.RxBytes")
|
assert.EqualValues(t, seed+offsetNetRxBytes, *stats.RxBytes, label+".Net.RxBytes")
|
||||||
assert.EqualValues(t, seed+offsetNetRxErrors, *stats.RxErrors, label+".Net.RxErrors")
|
assert.EqualValues(t, seed+offsetNetRxErrors, *stats.RxErrors, label+".Net.RxErrors")
|
||||||
assert.EqualValues(t, seed+offsetNetTxBytes, *stats.TxBytes, label+".Net.TxBytes")
|
assert.EqualValues(t, seed+offsetNetTxBytes, *stats.TxBytes, label+".Net.TxBytes")
|
||||||
|
@ -275,11 +293,13 @@ func checkNetworkStats(t *testing.T, label string, seed int, stats *NetworkStats
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkCPUStats(t *testing.T, label string, seed int, stats *CPUStats) {
|
func checkCPUStats(t *testing.T, label string, seed int, stats *CPUStats) {
|
||||||
|
assert.EqualValues(t, testTime(timestamp, seed).Unix(), stats.Time.Time.Unix(), label+".CPU.Time")
|
||||||
assert.EqualValues(t, seed+offsetCPUUsageCores, *stats.UsageNanoCores, label+".CPU.UsageCores")
|
assert.EqualValues(t, seed+offsetCPUUsageCores, *stats.UsageNanoCores, label+".CPU.UsageCores")
|
||||||
assert.EqualValues(t, seed+offsetCPUUsageCoreSeconds, *stats.UsageCoreNanoSeconds, label+".CPU.UsageCoreSeconds")
|
assert.EqualValues(t, seed+offsetCPUUsageCoreSeconds, *stats.UsageCoreNanoSeconds, label+".CPU.UsageCoreSeconds")
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkMemoryStats(t *testing.T, label string, seed int, stats *MemoryStats) {
|
func checkMemoryStats(t *testing.T, label string, seed int, stats *MemoryStats) {
|
||||||
|
assert.EqualValues(t, testTime(timestamp, seed).Unix(), stats.Time.Time.Unix(), label+".Mem.Time")
|
||||||
assert.EqualValues(t, seed+offsetMemUsageBytes, *stats.UsageBytes, label+".Mem.UsageBytes")
|
assert.EqualValues(t, seed+offsetMemUsageBytes, *stats.UsageBytes, label+".Mem.UsageBytes")
|
||||||
assert.EqualValues(t, seed+offsetMemWorkingSetBytes, *stats.WorkingSetBytes, label+".Mem.WorkingSetBytes")
|
assert.EqualValues(t, seed+offsetMemWorkingSetBytes, *stats.WorkingSetBytes, label+".Mem.WorkingSetBytes")
|
||||||
assert.EqualValues(t, seed+offsetMemPageFaults, *stats.PageFaults, label+".Mem.PageFaults")
|
assert.EqualValues(t, seed+offsetMemPageFaults, *stats.PageFaults, label+".Mem.PageFaults")
|
||||||
|
@ -301,24 +321,26 @@ func TestCustomMetrics(t *testing.T) {
|
||||||
Units: "count",
|
Units: "count",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
timestamp1 := time.Now()
|
||||||
|
timestamp2 := time.Now().Add(time.Minute)
|
||||||
metrics := map[string][]v1.MetricVal{
|
metrics := map[string][]v1.MetricVal{
|
||||||
"qos": {
|
"qos": {
|
||||||
{
|
{
|
||||||
Timestamp: time.Now(),
|
Timestamp: timestamp1,
|
||||||
IntValue: 10,
|
IntValue: 10,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Timestamp: time.Now().Add(time.Minute),
|
Timestamp: timestamp2,
|
||||||
IntValue: 100,
|
IntValue: 100,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"cpuLoad": {
|
"cpuLoad": {
|
||||||
{
|
{
|
||||||
Timestamp: time.Now(),
|
Timestamp: timestamp1,
|
||||||
FloatValue: 1.2,
|
FloatValue: 1.2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Timestamp: time.Now().Add(time.Minute),
|
Timestamp: timestamp2,
|
||||||
FloatValue: 2.1,
|
FloatValue: 2.1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -341,6 +363,7 @@ func TestCustomMetrics(t *testing.T) {
|
||||||
Type: MetricGauge,
|
Type: MetricGauge,
|
||||||
Units: "per second",
|
Units: "per second",
|
||||||
},
|
},
|
||||||
|
Time: unversioned.NewTime(timestamp2),
|
||||||
Value: 100,
|
Value: 100,
|
||||||
},
|
},
|
||||||
UserDefinedMetric{
|
UserDefinedMetric{
|
||||||
|
@ -349,6 +372,7 @@ func TestCustomMetrics(t *testing.T) {
|
||||||
Type: MetricCumulative,
|
Type: MetricCumulative,
|
||||||
Units: "count",
|
Units: "count",
|
||||||
},
|
},
|
||||||
|
Time: unversioned.NewTime(timestamp2),
|
||||||
Value: 2.1,
|
Value: 2.1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,6 @@ import (
|
||||||
|
|
||||||
// Summary is a top-level container for holding NodeStats and PodStats.
|
// Summary is a top-level container for holding NodeStats and PodStats.
|
||||||
type Summary struct {
|
type Summary struct {
|
||||||
// The time the most recent data included in this summary was collect at, rounded to the nearest
|
|
||||||
// second.
|
|
||||||
Time unversioned.Time `json:"time"`
|
|
||||||
// Overall node stats.
|
// Overall node stats.
|
||||||
Node NodeStats `json:"node"`
|
Node NodeStats `json:"node"`
|
||||||
// Per-pod stats.
|
// Per-pod stats.
|
||||||
|
@ -104,6 +101,8 @@ type PodReference struct {
|
||||||
|
|
||||||
// NetworkStats contains data about network resources.
|
// NetworkStats contains data about network resources.
|
||||||
type NetworkStats struct {
|
type NetworkStats struct {
|
||||||
|
// The time at which these stats were updated.
|
||||||
|
Time unversioned.Time `json:"time"`
|
||||||
// Cumulative count of bytes received.
|
// Cumulative count of bytes received.
|
||||||
RxBytes *uint64 `json:"rxBytes,omitempty"`
|
RxBytes *uint64 `json:"rxBytes,omitempty"`
|
||||||
// Cumulative count of receive errors encountered.
|
// Cumulative count of receive errors encountered.
|
||||||
|
@ -116,6 +115,8 @@ type NetworkStats struct {
|
||||||
|
|
||||||
// CPUStats contains data about CPU usage.
|
// CPUStats contains data about CPU usage.
|
||||||
type CPUStats struct {
|
type CPUStats struct {
|
||||||
|
// The time at which these stats were updated.
|
||||||
|
Time unversioned.Time `json:"time"`
|
||||||
// Total CPU usage (sum of all cores) averaged over the sample window.
|
// Total CPU usage (sum of all cores) averaged over the sample window.
|
||||||
// The "core" unit can be interpreted as CPU core-nanoseconds per second.
|
// The "core" unit can be interpreted as CPU core-nanoseconds per second.
|
||||||
UsageNanoCores *uint64 `json:"usageNanoCores,omitempty"`
|
UsageNanoCores *uint64 `json:"usageNanoCores,omitempty"`
|
||||||
|
@ -125,6 +126,8 @@ type CPUStats struct {
|
||||||
|
|
||||||
// MemoryStats contains data about memory usage.
|
// MemoryStats contains data about memory usage.
|
||||||
type MemoryStats struct {
|
type MemoryStats struct {
|
||||||
|
// The time at which these stats were updated.
|
||||||
|
Time unversioned.Time `json:"time"`
|
||||||
// Total memory in use. This includes all memory regardless of when it was accessed.
|
// Total memory in use. This includes all memory regardless of when it was accessed.
|
||||||
UsageBytes *uint64 `json:"usageBytes,omitempty"`
|
UsageBytes *uint64 `json:"usageBytes,omitempty"`
|
||||||
// The amount of working set memory. This includes recently accessed memory,
|
// The amount of working set memory. This includes recently accessed memory,
|
||||||
|
@ -188,6 +191,8 @@ type UserDefinedMetricDescriptor struct {
|
||||||
// UserDefinedMetric represents a metric defined and generate by users.
|
// UserDefinedMetric represents a metric defined and generate by users.
|
||||||
type UserDefinedMetric struct {
|
type UserDefinedMetric struct {
|
||||||
UserDefinedMetricDescriptor `json:",inline"`
|
UserDefinedMetricDescriptor `json:",inline"`
|
||||||
|
// The time at which these stats were updated.
|
||||||
|
Time unversioned.Time `json:"time"`
|
||||||
// Value of the metric. Float64s have 53 bit precision.
|
// Value of the metric. Float64s have 53 bit precision.
|
||||||
// We do not forsee any metrics exceeding that value.
|
// We do not forsee any metrics exceeding that value.
|
||||||
Value float64 `json:"value"`
|
Value float64 `json:"value"`
|
||||||
|
|
Loading…
Reference in New Issue