fix network value for stats summary

This commit is contained in:
Andy Xie 2017-11-07 23:43:00 +08:00
parent 92e1f4466e
commit 64a8edfbcf
4 changed files with 73 additions and 28 deletions

View File

@ -130,10 +130,10 @@ type PodReference struct {
UID string `json:"uid"` UID string `json:"uid"`
} }
// NetworkStats contains data about network resources. // InterfaceStats contains resource value data about interface.
type NetworkStats struct { type InterfaceStats struct {
// The time at which these stats were updated. // The name of the interface
Time metav1.Time `json:"time"` Name string `json:"name"`
// Cumulative count of bytes received. // Cumulative count of bytes received.
// +optional // +optional
RxBytes *uint64 `json:"rxBytes,omitempty"` RxBytes *uint64 `json:"rxBytes,omitempty"`
@ -148,6 +148,17 @@ type NetworkStats struct {
TxErrors *uint64 `json:"txErrors,omitempty"` TxErrors *uint64 `json:"txErrors,omitempty"`
} }
// NetworkStats contains data about network resources.
type NetworkStats struct {
// The time at which these stats were updated.
Time metav1.Time `json:"time"`
// Stats for the default interface, if found
InterfaceStats `json:",inline"`
Interfaces []InterfaceStats `json:"interfaces,omitempty"`
}
// 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. // The time at which these stats were updated.

View File

@ -127,19 +127,29 @@ func cadvisorInfoToNetworkStats(name string, info *cadvisorapiv2.ContainerInfo)
if !found { if !found {
return nil return nil
} }
for _, inter := range cstat.Network.Interfaces {
if inter.Name == network.DefaultInterfaceName { iStats := statsapi.NetworkStats{
return &statsapi.NetworkStats{
Time: metav1.NewTime(cstat.Timestamp), Time: metav1.NewTime(cstat.Timestamp),
}
for i := range cstat.Network.Interfaces {
inter := cstat.Network.Interfaces[i]
iStat := statsapi.InterfaceStats{
Name: inter.Name,
RxBytes: &inter.RxBytes, RxBytes: &inter.RxBytes,
RxErrors: &inter.RxErrors, RxErrors: &inter.RxErrors,
TxBytes: &inter.TxBytes, TxBytes: &inter.TxBytes,
TxErrors: &inter.TxErrors, TxErrors: &inter.TxErrors,
} }
if inter.Name == network.DefaultInterfaceName {
iStats.InterfaceStats = iStat
} }
iStats.Interfaces = append(iStats.Interfaces, iStat)
} }
glog.V(4).Infof("Missing default interface %q for %s", network.DefaultInterfaceName, name)
return nil return &iStats
} }
// cadvisorInfoToUserDefinedMetrics returns the statsapi.UserDefinedMetric // cadvisorInfoToUserDefinedMetrics returns the statsapi.UserDefinedMetric

View File

@ -525,10 +525,26 @@ func testTime(base time.Time, seed int) time.Time {
func checkNetworkStats(t *testing.T, label string, seed int, stats *statsapi.NetworkStats) { func checkNetworkStats(t *testing.T, label string, seed int, stats *statsapi.NetworkStats) {
assert.NotNil(t, stats) assert.NotNil(t, stats)
assert.EqualValues(t, testTime(timestamp, seed).Unix(), stats.Time.Time.Unix(), label+".Net.Time") assert.EqualValues(t, testTime(timestamp, seed).Unix(), stats.Time.Time.Unix(), label+".Net.Time")
assert.EqualValues(t, "eth0", stats.Name, "default interface name is not eth0")
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")
assert.EqualValues(t, seed+offsetNetTxErrors, *stats.TxErrors, label+".Net.TxErrors") assert.EqualValues(t, seed+offsetNetTxErrors, *stats.TxErrors, label+".Net.TxErrors")
assert.EqualValues(t, 2, len(stats.Interfaces), "network interfaces should contain 2 elements")
assert.EqualValues(t, "eth0", stats.Interfaces[0].Name, "default interface name is ont eth0")
assert.EqualValues(t, seed+offsetNetRxBytes, *stats.Interfaces[0].RxBytes, label+".Net.TxErrors")
assert.EqualValues(t, seed+offsetNetRxErrors, *stats.Interfaces[0].RxErrors, label+".Net.TxErrors")
assert.EqualValues(t, seed+offsetNetTxBytes, *stats.Interfaces[0].TxBytes, label+".Net.TxErrors")
assert.EqualValues(t, seed+offsetNetTxErrors, *stats.Interfaces[0].TxErrors, label+".Net.TxErrors")
assert.EqualValues(t, "cbr0", stats.Interfaces[1].Name, "cbr0 interface name is ont cbr0")
assert.EqualValues(t, 100, *stats.Interfaces[1].RxBytes, label+".Net.TxErrors")
assert.EqualValues(t, 100, *stats.Interfaces[1].RxErrors, label+".Net.TxErrors")
assert.EqualValues(t, 100, *stats.Interfaces[1].TxBytes, label+".Net.TxErrors")
assert.EqualValues(t, 100, *stats.Interfaces[1].TxErrors, label+".Net.TxErrors")
} }
func checkCPUStats(t *testing.T, label string, seed int, stats *statsapi.CPUStats) { func checkCPUStats(t *testing.T, label string, seed int, stats *statsapi.CPUStats) {

View File

@ -174,11 +174,15 @@ var _ = framework.KubeDescribe("Summary API", func() {
}), }),
"Network": ptrMatchAllFields(gstruct.Fields{ "Network": ptrMatchAllFields(gstruct.Fields{
"Time": recent(maxStatsAge), "Time": recent(maxStatsAge),
"InterfaceStats": gstruct.MatchAllFields(gstruct.Fields{
"Name": Equal("eth0"),
"RxBytes": bounded(10, 10*framework.Mb), "RxBytes": bounded(10, 10*framework.Mb),
"RxErrors": bounded(0, 1000), "RxErrors": bounded(0, 1000),
"TxBytes": bounded(10, 10*framework.Mb), "TxBytes": bounded(10, 10*framework.Mb),
"TxErrors": bounded(0, 1000), "TxErrors": bounded(0, 1000),
}), }),
"Interfaces": Not(BeNil()),
}),
"VolumeStats": gstruct.MatchAllElements(summaryObjectID, gstruct.Elements{ "VolumeStats": gstruct.MatchAllElements(summaryObjectID, gstruct.Elements{
"test-empty-dir": gstruct.MatchAllFields(gstruct.Fields{ "test-empty-dir": gstruct.MatchAllFields(gstruct.Fields{
"Name": Equal("test-empty-dir"), "Name": Equal("test-empty-dir"),
@ -222,13 +226,17 @@ var _ = framework.KubeDescribe("Summary API", func() {
"MajorPageFaults": bounded(0, 100000), "MajorPageFaults": bounded(0, 100000),
}), }),
// TODO(#28407): Handle non-eth0 network interface names. // TODO(#28407): Handle non-eth0 network interface names.
"Network": Or(BeNil(), ptrMatchAllFields(gstruct.Fields{ "Network": ptrMatchAllFields(gstruct.Fields{
"Time": recent(maxStatsAge), "Time": recent(maxStatsAge),
"RxBytes": bounded(1*framework.Mb, 100*framework.Gb), "InterfaceStats": gstruct.MatchAllFields(gstruct.Fields{
"RxErrors": bounded(0, 100000), "Name": Or(BeEmpty(), Equal("eth0")),
"TxBytes": bounded(10*framework.Kb, 10*framework.Gb), "RxBytes": Or(BeNil(), bounded(1*framework.Mb, 100*framework.Gb)),
"TxErrors": bounded(0, 100000), "RxErrors": Or(BeNil(), bounded(0, 100000)),
})), "TxBytes": Or(BeNil(), bounded(10*framework.Kb, 10*framework.Gb)),
"TxErrors": Or(BeNil(), bounded(0, 100000)),
}),
"Interfaces": Not(BeNil()),
}),
"Fs": ptrMatchAllFields(gstruct.Fields{ "Fs": ptrMatchAllFields(gstruct.Fields{
"Time": recent(maxStatsAge), "Time": recent(maxStatsAge),
"AvailableBytes": fsCapacityBounds, "AvailableBytes": fsCapacityBounds,