From 874266e00029174d6ad512eeac678b0c99512cd7 Mon Sep 17 00:00:00 2001 From: Vladimir Lavor Date: Thu, 5 May 2022 10:56:23 +0200 Subject: [PATCH] support error counters also as normal counters https://gerrit.fd.io/r/c/vpp/+/35640 Signed-off-by: Vladimir Lavor Change-Id: I91820bb15655e7b309af814c659eb9f5e7cd08a4 --- adapter/stats_api.go | 39 +++++++--------------------- adapter/statsclient/stat_segment_api.go | 45 +++++++++++++++++++++++---------- adapter/statsclient/statseg_v1.go | 20 +++++++-------- adapter/statsclient/statseg_v2.go | 18 ++++++------- core/stats.go | 23 ++++++++++------- 5 files changed, 73 insertions(+), 72 deletions(-) diff --git a/adapter/stats_api.go b/adapter/stats_api.go index 1319d71..7dc7dc3 100644 --- a/adapter/stats_api.go +++ b/adapter/stats_api.go @@ -16,7 +16,6 @@ package adapter import ( "errors" - "fmt" ) const ( @@ -53,39 +52,19 @@ type StatsAPI interface { // StatType represents type of stat directory and simply // defines what type of stat data is stored in the stat entry. -type StatType int +type StatType string const ( - _ StatType = 0 - ScalarIndex StatType = 1 - SimpleCounterVector StatType = 2 - CombinedCounterVector StatType = 3 - ErrorIndex StatType = 4 - NameVector StatType = 5 - Empty StatType = 6 - Symlink StatType = 7 + Unknown StatType = "UnknownStatType" + ScalarIndex StatType = "ScalarIndex" + SimpleCounterVector StatType = "SimpleCounterVector" + CombinedCounterVector StatType = "CombinedCounterVector" + ErrorIndex StatType = "ErrorIndex" + NameVector StatType = "NameVector" + Empty StatType = "Empty" + Symlink StatType = "Symlink" ) -func (d StatType) String() string { - switch d { - case ScalarIndex: - return "ScalarIndex" - case SimpleCounterVector: - return "SimpleCounterVector" - case CombinedCounterVector: - return "CombinedCounterVector" - case ErrorIndex: - return "ErrorIndex" - case NameVector: - return "NameVector" - case Empty: - return "Empty" - case Symlink: - return "Symlink" - } - return fmt.Sprintf("UnknownStatType(%d)", d) -} - // StatDir defines directory of stats entries created by PrepareDir. type StatDir struct { Epoch int64 diff --git a/adapter/statsclient/stat_segment_api.go b/adapter/statsclient/stat_segment_api.go index 2161e6e..fd7ef36 100644 --- a/adapter/statsclient/stat_segment_api.go +++ b/adapter/statsclient/stat_segment_api.go @@ -38,16 +38,24 @@ const ( maxVersion = 2 ) -const ( - statDirIllegal = 0 - statDirScalarIndex = 1 - statDirCounterVectorSimple = 2 - statDirCounterVectorCombined = 3 - statDirErrorIndex = 4 - statDirNameVector = 5 - statDirEmpty = 6 - statDirSymlink = 7 -) +var dirTypeMapping = map[dirType]adapter.StatType{ + 1: adapter.ScalarIndex, + 2: adapter.SimpleCounterVector, + 3: adapter.CombinedCounterVector, + 4: adapter.NameVector, + 5: adapter.Empty, + 6: adapter.Symlink, +} + +var dirTypeMappingLegacy = map[dirType]adapter.StatType{ + 1: adapter.ScalarIndex, + 2: adapter.SimpleCounterVector, + 3: adapter.CombinedCounterVector, + 4: adapter.ErrorIndex, + 5: adapter.NameVector, + 6: adapter.Empty, + 7: adapter.Symlink, +} type ( dirVector unsafe.Pointer @@ -92,10 +100,6 @@ type vecHeader struct { vectorData [0]uint8 } -func (t dirType) String() string { - return adapter.StatType(t).String() -} - func getVersion(data []byte) uint64 { type apiVersion struct { value uint64 @@ -113,6 +117,19 @@ func vectorLen(v dirVector) dirVector { return dirVector(&vec.length) } +func getStatType(dirTypeNum dirType, useLegacyMapping bool) (dirTyp adapter.StatType) { + var exists bool + if useLegacyMapping { + dirTyp, exists = dirTypeMappingLegacy[dirTypeNum] + } else { + dirTyp, exists = dirTypeMapping[dirTypeNum] + } + if exists { + return dirTyp + } + return adapter.Unknown +} + //go:nosplit func statSegPointer(v dirVector, offset uintptr) dirVector { return dirVector(uintptr(v) + offset) diff --git a/adapter/statsclient/statseg_v1.go b/adapter/statsclient/statseg_v1.go index efd487e..22052f5 100644 --- a/adapter/statsclient/statseg_v1.go +++ b/adapter/statsclient/statseg_v1.go @@ -85,7 +85,7 @@ func (ss *statSegmentV1) GetStatDirOnIndex(v dirVector, index uint32) (dirSegmen break } } - return statSegDir, dirName(name), dir.directoryType + return statSegDir, name, dir.directoryType } func (ss *statSegmentV1) GetEpoch() (int64, bool) { @@ -95,13 +95,13 @@ func (ss *statSegmentV1) GetEpoch() (int64, bool) { func (ss *statSegmentV1) CopyEntryData(segment dirSegment, _ uint32) adapter.Stat { dirEntry := (*statSegDirectoryEntryV1)(segment) - dirType := adapter.StatType(dirEntry.directoryType) + typ := getStatType(dirEntry.directoryType, true) - switch dirType { - case statDirScalarIndex: + switch typ { + case adapter.ScalarIndex: return adapter.ScalarStat(dirEntry.unionData) - case statDirErrorIndex: + case adapter.ErrorIndex: if dirEntry.unionData == 0 { debugf("offset invalid for %s", dirEntry.name) break @@ -125,7 +125,7 @@ func (ss *statSegmentV1) CopyEntryData(segment dirSegment, _ uint32) adapter.Sta } return adapter.ErrorStat(errData) - case statDirCounterVectorSimple: + case adapter.SimpleCounterVector: if dirEntry.unionData == 0 { debugf("offset invalid for %s", dirEntry.name) break @@ -151,7 +151,7 @@ func (ss *statSegmentV1) CopyEntryData(segment dirSegment, _ uint32) adapter.Sta } return adapter.SimpleCounterStat(data) - case statDirCounterVectorCombined: + case adapter.CombinedCounterVector: if dirEntry.unionData == 0 { debugf("offset invalid for %s", dirEntry.name) break @@ -177,7 +177,7 @@ func (ss *statSegmentV1) CopyEntryData(segment dirSegment, _ uint32) adapter.Sta } return adapter.CombinedCounterStat(data) - case statDirNameVector: + case adapter.NameVector: if dirEntry.unionData == 0 { debugf("offset invalid for %s", dirEntry.name) break @@ -211,10 +211,10 @@ func (ss *statSegmentV1) CopyEntryData(segment dirSegment, _ uint32) adapter.Sta } return adapter.NameStat(data) - case statDirEmpty: + case adapter.Empty: // no-op - case statDirSymlink: + case adapter.Symlink: debugf("Symlinks are not supported for stats v1") default: diff --git a/adapter/statsclient/statseg_v2.go b/adapter/statsclient/statseg_v2.go index 0780248..1f8aaeb 100644 --- a/adapter/statsclient/statseg_v2.go +++ b/adapter/statsclient/statseg_v2.go @@ -92,18 +92,18 @@ func (ss *statSegmentV2) GetEpoch() (int64, bool) { func (ss *statSegmentV2) CopyEntryData(segment dirSegment, index uint32) adapter.Stat { dirEntry := (*statSegDirectoryEntryV2)(segment) - typ := adapter.StatType(dirEntry.directoryType) + typ := getStatType(dirEntry.directoryType, ss.getErrorVector() != nil) // skip zero pointer value - if typ != statDirScalarIndex && typ != statDirEmpty && dirEntry.unionData == 0 { + if typ != adapter.ScalarIndex && typ != adapter.Empty && dirEntry.unionData == 0 { debugf("data pointer not defined for %s", dirEntry.name) return nil } switch typ { - case statDirScalarIndex: + case adapter.ScalarIndex: return adapter.ScalarStat(dirEntry.unionData) - case statDirErrorIndex: + case adapter.ErrorIndex: dirVector := ss.getErrorVector() if dirVector == nil { debugf("error vector pointer is out of range for %s", dirEntry.name) @@ -124,7 +124,7 @@ func (ss *statSegmentV2) CopyEntryData(segment dirSegment, index uint32) adapter } return adapter.ErrorStat(errData) - case statDirCounterVectorSimple: + case adapter.SimpleCounterVector: dirVector := ss.adjust(dirVector(&dirEntry.unionData)) if dirVector == nil { debugf("data vector pointer is out of range for %s", dirEntry.name) @@ -159,7 +159,7 @@ func (ss *statSegmentV2) CopyEntryData(segment dirSegment, index uint32) adapter } return adapter.SimpleCounterStat(data) - case statDirCounterVectorCombined: + case adapter.CombinedCounterVector: dirVector := ss.adjust(dirVector(&dirEntry.unionData)) if dirVector == nil { debugf("data vector pointer is out of range for %s", dirEntry.name) @@ -194,7 +194,7 @@ func (ss *statSegmentV2) CopyEntryData(segment dirSegment, index uint32) adapter } return adapter.CombinedCounterStat(data) - case statDirNameVector: + case adapter.NameVector: dirVector := ss.adjust(dirVector(&dirEntry.unionData)) if dirVector == nil { debugf("data vector pointer is out of range for %s", dirEntry.name) @@ -226,11 +226,11 @@ func (ss *statSegmentV2) CopyEntryData(segment dirSegment, index uint32) adapter } return adapter.NameStat(data) - case statDirEmpty: + case adapter.Empty: return adapter.EmptyStat("") // no-op - case statDirSymlink: + case adapter.Symlink: // prevent recursion loops if index != ^uint32(0) { debugf("received symlink with defined item index") diff --git a/core/stats.go b/core/stats.go index 4033981..f05383d 100644 --- a/core/stats.go +++ b/core/stats.go @@ -40,8 +40,8 @@ const ( CounterStatsPrefix = "/err/" MemoryStatSegPrefix = "/mem/statseg" - MemoryStatPrefix = "/mem/stat" - MemoryMainPrefix = "/mem/main" + MemoryStatSegment = "/mem/stat segment" + MemoryMainHeap = "/mem/main heap" MemoryStats_Total = "total" MemoryStats_Used = "used" @@ -303,9 +303,6 @@ func (c *StatsConnection) GetErrorStats(errorStats *api.ErrorStats) (err error) } for i, stat := range c.errorStatsData.Entries { - if stat.Type != adapter.ErrorIndex { - continue - } if errStat, ok := stat.Data.(adapter.ErrorStat); ok { values := make([]uint64, len(errStat)) for j, errStatW := range errStat { @@ -313,8 +310,16 @@ func (c *StatsConnection) GetErrorStats(errorStats *api.ErrorStats) (err error) } errorStats.Errors[i].Values = values } + if errStat, ok := stat.Data.(adapter.SimpleCounterStat); ok { + values := make([]uint64, len(errStat)) + for j, errStatW := range errStat { + for _, val := range errStatW { + values[j] += uint64(val) + } + } + errorStats.Errors[i].Values = values + } } - return nil } @@ -547,7 +552,7 @@ func (c *StatsConnection) GetBufferStats(bufStats *api.BufferStats) (err error) } func (c *StatsConnection) GetMemoryStats(memStats *api.MemoryStats) (err error) { - if err := c.updateStats(&c.memStatsData, MemoryStatSegPrefix, MemoryStatPrefix, MemoryMainPrefix); err != nil { + if err := c.updateStats(&c.memStatsData, MemoryStatSegPrefix, MemoryStatSegment, MemoryMainHeap); err != nil { return err } convertStats := func(stats []adapter.Counter) api.MemoryCounters { @@ -573,7 +578,7 @@ func (c *StatsConnection) GetMemoryStats(memStats *api.MemoryStats) (err error) case MemoryStats_Used: memStats.Used = val } - } else if strings.Contains(string(stat.Name), MemoryStatPrefix) { + } else if string(stat.Name) == MemoryStatSegment { if perHeapStats, ok := stat.Data.(adapter.SimpleCounterStat); ok { if memStats.Stat == nil { memStats.Stat = make(map[int]api.MemoryCounters) @@ -582,7 +587,7 @@ func (c *StatsConnection) GetMemoryStats(memStats *api.MemoryStats) (err error) memStats.Stat[heap] = convertStats(stats) } } - } else if strings.Contains(string(stat.Name), MemoryMainPrefix) { + } else if string(stat.Name) == MemoryMainHeap { if perHeapStats, ok := stat.Data.(adapter.SimpleCounterStat); ok { if memStats.Main == nil { memStats.Main = make(map[int]api.MemoryCounters) -- 2.16.6