support error counters also as normal counters 85/36085/1
authorVladimir Lavor <vlavor@cisco.com>
Thu, 5 May 2022 08:56:23 +0000 (10:56 +0200)
committerVladimir Lavor <vlavor@cisco.com>
Thu, 5 May 2022 09:28:52 +0000 (11:28 +0200)
https://gerrit.fd.io/r/c/vpp/+/35640

Signed-off-by: Vladimir Lavor <vlavor@cisco.com>
Change-Id: I91820bb15655e7b309af814c659eb9f5e7cd08a4

adapter/stats_api.go
adapter/statsclient/stat_segment_api.go
adapter/statsclient/statseg_v1.go
adapter/statsclient/statseg_v2.go
core/stats.go

index 1319d71..7dc7dc3 100644 (file)
@@ -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
index 2161e6e..fd7ef36 100644 (file)
@@ -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)
index efd487e..22052f5 100644 (file)
@@ -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:
index 0780248..1f8aaeb 100644 (file)
@@ -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("<none>")
                // no-op
 
-       case statDirSymlink:
+       case adapter.Symlink:
                // prevent recursion loops
                if index != ^uint32(0) {
                        debugf("received symlink with defined item index")
index 4033981..f05383d 100644 (file)
@@ -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)