Add top stat info to mongodb plugin (#8861)

* Add top stat info

* fixes after review

* fix README.md
This commit is contained in:
Denis Pershin 2021-03-16 23:54:57 +03:00 committed by GitHub
parent c4a126073c
commit 8a47d6f104
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 268 additions and 46 deletions

View File

@ -21,6 +21,10 @@
## When true, collect per collection stats
# gather_col_stats = false
## When true, collect usage statistics for each collection
## (insert, update, queries, remove, getmore, commands etc...).
# gather_top_stat = false
## List of db where collections stats are collected
## If empty, all db are concerned
@ -263,6 +267,29 @@ by running Telegraf with the `--debug` argument.
- available (integer)
- created (integer)
- refreshing (integer)
- mongodb_top_stats
- tags:
- collection
- fields:
- total_time (integer)
- total_count (integer)
- read_lock_time (integer)
- read_lock_count (integer)
- write_lock_time (integer)
- write_lock_count (integer)
- queries_time (integer)
- queries_count (integer)
- get_more_time (integer)
- get_more_count (integer)
- insert_time (integer)
- insert_count (integer)
- update_time (integer)
- update_count (integer)
- remove_time (integer)
- remove_count (integer)
- commands_time (integer)
- commands_count (integer)
### Example Output:
```
@ -272,4 +299,5 @@ mongodb_db_stats,db_name=admin,hostname=127.0.0.1:27017 avg_obj_size=241,collect
mongodb_db_stats,db_name=local,hostname=127.0.0.1:27017 avg_obj_size=813.9705882352941,collections=6i,data_size=55350i,index_size=102400i,indexes=5i,num_extents=0i,objects=68i,ok=1i,storage_size=204800i,type="db_stat" 1547159491000000000
mongodb_col_stats,collection=foo,db_name=local,hostname=127.0.0.1:27017 size=375005928i,avg_obj_size=5494,type="col_stat",storage_size=249307136i,total_index_size=2138112i,ok=1i,count=68251i 1547159491000000000
mongodb_shard_stats,hostname=127.0.0.1:27017,in_use=3i,available=3i,created=4i,refreshing=0i 1522799074000000000
mongodb_top_stats,collection=foo,total_time=1471,total_count=158,read_lock_time=49614,read_lock_count=657,write_lock_time=49125456,write_lock_count=9841,queries_time=174,queries_count=495,get_more_time=498,get_more_count=46,insert_time=2651,insert_count=1265,update_time=0,update_count=0,remove_time=0,remove_count=0,commands_time=498611,commands_count=4615
```

View File

@ -23,6 +23,7 @@ type MongoDB struct {
GatherClusterStatus bool
GatherPerdbStats bool
GatherColStats bool
GatherTopStat bool
ColStatsDbs []string
tlsint.ClientConfig
@ -53,6 +54,10 @@ var sampleConfig = `
## When true, collect per collection stats
# gather_col_stats = false
## When true, collect usage statistics for each collection
## (insert, update, queries, remove, getmore, commands etc...).
# gather_top_stat = false
## List of db where collections stats are collected
## If empty, all db are concerned
# col_stats_dbs = ["local"]
@ -183,7 +188,7 @@ func (m *MongoDB) gatherServer(server *Server, acc telegraf.Accumulator) error {
}
server.Session = sess
}
return server.gatherData(acc, m.GatherClusterStatus, m.GatherPerdbStats, m.GatherColStats, m.ColStatsDbs)
return server.gatherData(acc, m.GatherClusterStatus, m.GatherPerdbStats, m.GatherColStats, m.GatherTopStat, m.ColStatsDbs)
}
func init() {
@ -193,6 +198,7 @@ func init() {
GatherClusterStatus: true,
GatherPerdbStats: false,
GatherColStats: false,
GatherTopStat: false,
ColStatsDbs: []string{"local"},
}
})

View File

@ -15,6 +15,7 @@ type MongodbData struct {
DbData []DbData
ColData []ColData
ShardHostData []DbData
TopStatsData []DbData
}
type DbData struct {
@ -37,7 +38,7 @@ func NewMongodbData(statLine *StatLine, tags map[string]string) *MongodbData {
}
}
var DefaultStats = map[string]string{
var defaultStats = map[string]string{
"uptime_ns": "UptimeNanos",
"inserts": "InsertCnt",
"inserts_per_sec": "Insert",
@ -94,7 +95,7 @@ var DefaultStats = map[string]string{
"total_docs_scanned": "TotalObjectsScanned",
}
var DefaultAssertsStats = map[string]string{
var defaultAssertsStats = map[string]string{
"assert_regular": "Regular",
"assert_warning": "Warning",
"assert_msg": "Msg",
@ -102,7 +103,7 @@ var DefaultAssertsStats = map[string]string{
"assert_rollovers": "Rollovers",
}
var DefaultCommandsStats = map[string]string{
var defaultCommandsStats = map[string]string{
"aggregate_command_total": "AggregateCommandTotal",
"aggregate_command_failed": "AggregateCommandFailed",
"count_command_total": "CountCommandTotal",
@ -123,7 +124,7 @@ var DefaultCommandsStats = map[string]string{
"update_command_failed": "UpdateCommandFailed",
}
var DefaultLatencyStats = map[string]string{
var defaultLatencyStats = map[string]string{
"latency_writes_count": "WriteOpsCnt",
"latency_writes": "WriteLatency",
"latency_reads_count": "ReadOpsCnt",
@ -132,7 +133,7 @@ var DefaultLatencyStats = map[string]string{
"latency_commands": "CommandLatency",
}
var DefaultReplStats = map[string]string{
var defaultReplStats = map[string]string{
"repl_inserts": "InsertRCnt",
"repl_inserts_per_sec": "InsertR",
"repl_queries": "QueryRCnt",
@ -164,37 +165,37 @@ var DefaultReplStats = map[string]string{
"repl_executor_unsignaled_events": "ReplExecutorUnsignaledEvents",
}
var DefaultClusterStats = map[string]string{
var defaultClusterStats = map[string]string{
"jumbo_chunks": "JumboChunksCount",
}
var DefaultShardStats = map[string]string{
var defaultShardStats = map[string]string{
"total_in_use": "TotalInUse",
"total_available": "TotalAvailable",
"total_created": "TotalCreated",
"total_refreshing": "TotalRefreshing",
}
var ShardHostStats = map[string]string{
var shardHostStats = map[string]string{
"in_use": "InUse",
"available": "Available",
"created": "Created",
"refreshing": "Refreshing",
}
var MmapStats = map[string]string{
var mmapStats = map[string]string{
"mapped_megabytes": "Mapped",
"non-mapped_megabytes": "NonMapped",
"page_faults": "FaultsCnt",
"page_faults_per_sec": "Faults",
}
var WiredTigerStats = map[string]string{
var wiredTigerStats = map[string]string{
"percent_cache_dirty": "CacheDirtyPercent",
"percent_cache_used": "CacheUsedPercent",
}
var WiredTigerExtStats = map[string]string{
var wiredTigerExtStats = map[string]string{
"wtcache_tracked_dirty_bytes": "TrackedDirtyBytes",
"wtcache_current_bytes": "CurrentCachedBytes",
"wtcache_max_bytes_configured": "MaxBytesConfigured",
@ -215,7 +216,7 @@ var WiredTigerExtStats = map[string]string{
"wtcache_unmodified_pages_evicted": "UnmodifiedPagesEvicted",
}
var DefaultTCMallocStats = map[string]string{
var defaultTCMallocStats = map[string]string{
"tcmalloc_current_allocated_bytes": "TCMallocCurrentAllocatedBytes",
"tcmalloc_heap_size": "TCMallocHeapSize",
"tcmalloc_central_cache_free_bytes": "TCMallocCentralCacheFreeBytes",
@ -237,13 +238,13 @@ var DefaultTCMallocStats = map[string]string{
"tcmalloc_pageheap_total_reserve_bytes": "TCMallocPageheapTotalReserveBytes",
}
var DefaultStorageStats = map[string]string{
var defaultStorageStats = map[string]string{
"storage_freelist_search_bucket_exhausted": "StorageFreelistSearchBucketExhausted",
"storage_freelist_search_requests": "StorageFreelistSearchRequests",
"storage_freelist_search_scanned": "StorageFreelistSearchScanned",
}
var DbDataStats = map[string]string{
var dbDataStats = map[string]string{
"collections": "Collections",
"objects": "Objects",
"avg_obj_size": "AvgObjSize",
@ -255,7 +256,7 @@ var DbDataStats = map[string]string{
"ok": "Ok",
}
var ColDataStats = map[string]string{
var colDataStats = map[string]string{
"count": "Count",
"size": "Size",
"avg_obj_size": "AvgObjSize",
@ -264,6 +265,27 @@ var ColDataStats = map[string]string{
"ok": "Ok",
}
var topDataStats = map[string]string{
"total_time": "TotalTime",
"total_count": "TotalCount",
"read_lock_time": "ReadLockTime",
"read_lock_count": "ReadLockCount",
"write_lock_time": "WriteLockTime",
"write_lock_count": "WriteLockCount",
"queries_time": "QueriesTime",
"queries_count": "QueriesCount",
"get_more_time": "GetMoreTime",
"get_more_count": "GetMoreCount",
"insert_time": "InsertTime",
"insert_count": "InsertCount",
"update_time": "UpdateTime",
"update_count": "UpdateCount",
"remove_time": "RemoveTime",
"remove_count": "RemoveCount",
"commands_time": "CommandsTime",
"commands_count": "CommandsCount",
}
func (d *MongodbData) AddDbStats() {
for _, dbstat := range d.StatLine.DbStatsLines {
dbStatLine := reflect.ValueOf(&dbstat).Elem()
@ -272,7 +294,7 @@ func (d *MongodbData) AddDbStats() {
Fields: make(map[string]interface{}),
}
newDbData.Fields["type"] = "db_stat"
for key, value := range DbDataStats {
for key, value := range dbDataStats {
val := dbStatLine.FieldByName(value).Interface()
newDbData.Fields[key] = val
}
@ -289,7 +311,7 @@ func (d *MongodbData) AddColStats() {
Fields: make(map[string]interface{}),
}
newColData.Fields["type"] = "col_stat"
for key, value := range ColDataStats {
for key, value := range colDataStats {
val := colStatLine.FieldByName(value).Interface()
newColData.Fields[key] = val
}
@ -305,7 +327,7 @@ func (d *MongodbData) AddShardHostStats() {
Fields: make(map[string]interface{}),
}
newDbData.Fields["type"] = "shard_host_stat"
for k, v := range ShardHostStats {
for k, v := range shardHostStats {
val := hostStatLine.FieldByName(v).Interface()
newDbData.Fields[k] = val
}
@ -313,16 +335,32 @@ func (d *MongodbData) AddShardHostStats() {
}
}
func (d *MongodbData) AddTopStats() {
for _, topStat := range d.StatLine.TopStatLines {
topStatLine := reflect.ValueOf(&topStat).Elem()
newTopStatData := &DbData{
Name: topStat.CollectionName,
Fields: make(map[string]interface{}),
}
newTopStatData.Fields["type"] = "top_stat"
for key, value := range topDataStats {
val := topStatLine.FieldByName(value).Interface()
newTopStatData.Fields[key] = val
}
d.TopStatsData = append(d.TopStatsData, *newTopStatData)
}
}
func (d *MongodbData) AddDefaultStats() {
statLine := reflect.ValueOf(d.StatLine).Elem()
d.addStat(statLine, DefaultStats)
d.addStat(statLine, defaultStats)
if d.StatLine.NodeType != "" {
d.addStat(statLine, DefaultReplStats)
d.addStat(statLine, defaultReplStats)
d.Tags["node_type"] = d.StatLine.NodeType
}
if d.StatLine.ReadLatency > 0 {
d.addStat(statLine, DefaultLatencyStats)
d.addStat(statLine, defaultLatencyStats)
}
if d.StatLine.ReplSetName != "" {
@ -337,23 +375,23 @@ func (d *MongodbData) AddDefaultStats() {
d.add("version", d.StatLine.Version)
}
d.addStat(statLine, DefaultAssertsStats)
d.addStat(statLine, DefaultClusterStats)
d.addStat(statLine, DefaultCommandsStats)
d.addStat(statLine, DefaultShardStats)
d.addStat(statLine, DefaultStorageStats)
d.addStat(statLine, DefaultTCMallocStats)
d.addStat(statLine, defaultAssertsStats)
d.addStat(statLine, defaultClusterStats)
d.addStat(statLine, defaultCommandsStats)
d.addStat(statLine, defaultShardStats)
d.addStat(statLine, defaultStorageStats)
d.addStat(statLine, defaultTCMallocStats)
if d.StatLine.StorageEngine == "mmapv1" || d.StatLine.StorageEngine == "rocksdb" {
d.addStat(statLine, MmapStats)
d.addStat(statLine, mmapStats)
} else if d.StatLine.StorageEngine == "wiredTiger" {
for key, value := range WiredTigerStats {
for key, value := range wiredTigerStats {
val := statLine.FieldByName(value).Interface()
percentVal := fmt.Sprintf("%.1f", val.(float64)*100)
floatVal, _ := strconv.ParseFloat(percentVal, 64)
d.add(key, floatVal)
}
d.addStat(statLine, WiredTigerExtStats)
d.addStat(statLine, wiredTigerExtStats)
d.add("page_faults", d.StatLine.FaultsCnt)
}
}
@ -409,4 +447,14 @@ func (d *MongodbData) flush(acc telegraf.Accumulator) {
)
host.Fields = make(map[string]interface{})
}
for _, col := range d.TopStatsData {
d.Tags["collection"] = col.Name
acc.AddFields(
"mongodb_top_stats",
col.Fields,
d.Tags,
d.StatLine.Time,
)
col.Fields = make(map[string]interface{})
}
}

View File

@ -64,7 +64,7 @@ func TestAddNonReplStats(t *testing.T) {
d.AddDefaultStats()
d.flush(&acc)
for key := range DefaultStats {
for key := range defaultStats {
assert.True(t, acc.HasFloatField("mongodb", key) || acc.HasInt64Field("mongodb", key), key)
}
}
@ -85,7 +85,7 @@ func TestAddReplStats(t *testing.T) {
d.AddDefaultStats()
d.flush(&acc)
for key := range MmapStats {
for key := range mmapStats {
assert.True(t, acc.HasInt64Field("mongodb", key), key)
}
}
@ -119,11 +119,11 @@ func TestAddWiredTigerStats(t *testing.T) {
d.AddDefaultStats()
d.flush(&acc)
for key := range WiredTigerStats {
for key := range wiredTigerStats {
assert.True(t, acc.HasFloatField("mongodb", key), key)
}
for key := range WiredTigerExtStats {
for key := range wiredTigerExtStats {
assert.True(t, acc.HasFloatField("mongodb", key) || acc.HasInt64Field("mongodb", key), key)
}
@ -146,7 +146,7 @@ func TestAddShardStats(t *testing.T) {
d.AddDefaultStats()
d.flush(&acc)
for key := range DefaultShardStats {
for key := range defaultShardStats {
assert.True(t, acc.HasInt64Field("mongodb", key))
}
}
@ -169,7 +169,7 @@ func TestAddLatencyStats(t *testing.T) {
d.AddDefaultStats()
d.flush(&acc)
for key := range DefaultLatencyStats {
for key := range defaultLatencyStats {
assert.True(t, acc.HasInt64Field("mongodb", key))
}
}
@ -191,7 +191,7 @@ func TestAddAssertsStats(t *testing.T) {
d.AddDefaultStats()
d.flush(&acc)
for key := range DefaultAssertsStats {
for key := range defaultAssertsStats {
assert.True(t, acc.HasInt64Field("mongodb", key))
}
}
@ -226,7 +226,7 @@ func TestAddCommandsStats(t *testing.T) {
d.AddDefaultStats()
d.flush(&acc)
for key := range DefaultCommandsStats {
for key := range defaultCommandsStats {
assert.True(t, acc.HasInt64Field("mongodb", key))
}
}
@ -262,7 +262,7 @@ func TestAddTCMallocStats(t *testing.T) {
d.AddDefaultStats()
d.flush(&acc)
for key := range DefaultTCMallocStats {
for key := range defaultTCMallocStats {
assert.True(t, acc.HasInt64Field("mongodb", key))
}
}
@ -282,7 +282,7 @@ func TestAddStorageStats(t *testing.T) {
d.AddDefaultStats()
d.flush(&acc)
for key := range DefaultStorageStats {
for key := range defaultStorageStats {
assert.True(t, acc.HasInt64Field("mongodb", key))
}
}
@ -312,7 +312,7 @@ func TestAddShardHostStats(t *testing.T) {
var hostsFound []string
for host := range hostStatLines {
for key := range ShardHostStats {
for key := range shardHostStats {
assert.True(t, acc.HasInt64Field("mongodb_shard_stats", key))
}
@ -485,3 +485,49 @@ func TestStateTag(t *testing.T) {
}
acc.AssertContainsTaggedFields(t, "mongodb", fields, stateTags)
}
func TestAddTopStats(t *testing.T) {
collections := []string{"collectionOne", "collectionTwo"}
var topStatLines []TopStatLine
for _, collection := range collections {
topStatLine := TopStatLine{
CollectionName: collection,
TotalTime: 0,
TotalCount: 0,
ReadLockTime: 0,
ReadLockCount: 0,
WriteLockTime: 0,
WriteLockCount: 0,
QueriesTime: 0,
QueriesCount: 0,
GetMoreTime: 0,
GetMoreCount: 0,
InsertTime: 0,
InsertCount: 0,
UpdateTime: 0,
UpdateCount: 0,
RemoveTime: 0,
RemoveCount: 0,
CommandsTime: 0,
CommandsCount: 0,
}
topStatLines = append(topStatLines, topStatLine)
}
d := NewMongodbData(
&StatLine{
TopStatLines: topStatLines,
},
tags,
)
var acc testutil.Accumulator
d.AddTopStats()
d.flush(&acc)
for range topStatLines {
for key := range topDataStats {
assert.True(t, acc.HasInt64Field("mongodb_top_stats", key))
}
}
}

View File

@ -73,6 +73,20 @@ func (s *Server) gatherReplSetStatus() (*ReplSetStatus, error) {
return replSetStatus, nil
}
func (s *Server) gatherTopStatData() (*TopStats, error) {
topStats := &TopStats{}
err := s.Session.DB("admin").Run(bson.D{
{
Name: "top",
Value: 1,
},
}, topStats)
if err != nil {
return nil, err
}
return topStats, nil
}
func (s *Server) gatherClusterStatus() (*ClusterStatus, error) {
chunkCount, err := s.Session.DB("config").C("chunks").Find(bson.M{"jumbo": true}).Count()
if err != nil {
@ -192,7 +206,7 @@ func (s *Server) gatherCollectionStats(colStatsDbs []string) (*ColStats, error)
return results, nil
}
func (s *Server) gatherData(acc telegraf.Accumulator, gatherClusterStatus bool, gatherDbStats bool, gatherColStats bool, colStatsDbs []string) error {
func (s *Server) gatherData(acc telegraf.Accumulator, gatherClusterStatus bool, gatherDbStats bool, gatherColStats bool, gatherTopStat bool, colStatsDbs []string) error {
s.Session.SetMode(mgo.Eventual, true)
s.Session.SetSocketTimeout(0)
@ -257,6 +271,16 @@ func (s *Server) gatherData(acc telegraf.Accumulator, gatherClusterStatus bool,
}
}
topStatData := &TopStats{}
if gatherTopStat {
topStats, err := s.gatherTopStatData()
if err != nil {
s.Log.Debugf("Unable to gather top stat data: %s", err.Error())
return err
}
topStatData = topStats
}
result := &MongoStatus{
ServerStatus: serverStatus,
ReplSetStatus: replSetStatus,
@ -265,6 +289,7 @@ func (s *Server) gatherData(acc telegraf.Accumulator, gatherClusterStatus bool,
ColStats: collectionStats,
ShardStats: shardStats,
OplogStats: oplogStats,
TopStats: topStatData,
}
result.SampleTime = time.Now()
@ -282,6 +307,7 @@ func (s *Server) gatherData(acc telegraf.Accumulator, gatherClusterStatus bool,
data.AddDbStats()
data.AddColStats()
data.AddShardHostStats()
data.AddTopStats()
data.flush(acc)
}

View File

@ -35,7 +35,7 @@ func TestAddDefaultStats(t *testing.T) {
err = server.gatherData(&acc, false)
require.NoError(t, err)
for key := range DefaultStats {
for key := range defaultStats {
assert.True(t, acc.HasInt64Field("mongodb", key))
}
}

View File

@ -37,6 +37,7 @@ type MongoStatus struct {
ColStats *ColStats
ShardStats *ShardStats
OplogStats *OplogStats
TopStats *TopStats
}
type ServerStatus struct {
@ -169,6 +170,31 @@ type ShardHostStatsData struct {
Refreshing int64 `bson:"refreshing"`
}
type TopStats struct {
Totals map[string]TopStatCollections `bson:"totals"`
}
type TopStatCollections struct {
TSCollection TopStatCollection `bson:",inline"`
}
type TopStatCollection struct {
Total TopStatCollectionData `bson:"total"`
ReadLock TopStatCollectionData `bson:"readLock"`
WriteLock TopStatCollectionData `bson:"writeLock"`
Queries TopStatCollectionData `bson:"queries"`
GetMore TopStatCollectionData `bson:"getmore"`
Insert TopStatCollectionData `bson:"insert"`
Update TopStatCollectionData `bson:"update"`
Remove TopStatCollectionData `bson:"remove"`
Commands TopStatCollectionData `bson:"commands"`
}
type TopStatCollectionData struct {
Time int64 `bson:"time"`
Count int64 `bson:"count"`
}
type ConcurrentTransactions struct {
Write ConcurrentTransStats `bson:"write"`
Read ConcurrentTransStats `bson:"read"`
@ -768,6 +794,8 @@ type StatLine struct {
// Shard Hosts stats field
ShardHostStatsLines map[string]ShardHostStatLine
TopStatLines []TopStatLine
// TCMalloc stats field
TCMallocCurrentAllocatedBytes int64
TCMallocHeapSize int64
@ -825,6 +853,19 @@ type ShardHostStatLine struct {
Refreshing int64
}
type TopStatLine struct {
CollectionName string
TotalTime, TotalCount int64
ReadLockTime, ReadLockCount int64
WriteLockTime, WriteLockCount int64
QueriesTime, QueriesCount int64
GetMoreTime, GetMoreCount int64
InsertTime, InsertCount int64
UpdateTime, UpdateCount int64
RemoveTime, RemoveCount int64
CommandsTime, CommandsCount int64
}
func parseLocks(stat ServerStatus) map[string]LockUsage {
returnVal := map[string]LockUsage{}
for namespace, lockInfo := range stat.Locks {
@ -1101,7 +1142,7 @@ func NewStatLine(oldMongo, newMongo MongoStatus, key string, all bool, sampleSec
returnVal.Time = newMongo.SampleTime
returnVal.IsMongos =
(newStat.ShardCursorType != nil || strings.HasPrefix(newStat.Process, MongosProcess))
newStat.ShardCursorType != nil || strings.HasPrefix(newStat.Process, MongosProcess)
// BEGIN code modification
if oldStat.Mem.Supported.(bool) {
@ -1209,7 +1250,7 @@ func NewStatLine(oldMongo, newMongo MongoStatus, key string, all bool, sampleSec
}
if newStat.GlobalLock != nil {
hasWT := (newStat.WiredTiger != nil && oldStat.WiredTiger != nil)
hasWT := newStat.WiredTiger != nil && oldStat.WiredTiger != nil
//If we have wiredtiger stats, use those instead
if newStat.GlobalLock.CurrentQueue != nil {
if hasWT {
@ -1364,5 +1405,32 @@ func NewStatLine(oldMongo, newMongo MongoStatus, key string, all bool, sampleSec
}
}
if newMongo.TopStats != nil {
for collection, data := range newMongo.TopStats.Totals {
topStatDataLine := &TopStatLine{
CollectionName: collection,
TotalTime: data.TSCollection.Total.Time,
TotalCount: data.TSCollection.Total.Count,
ReadLockTime: data.TSCollection.ReadLock.Time,
ReadLockCount: data.TSCollection.ReadLock.Count,
WriteLockTime: data.TSCollection.WriteLock.Time,
WriteLockCount: data.TSCollection.WriteLock.Count,
QueriesTime: data.TSCollection.Queries.Time,
QueriesCount: data.TSCollection.Queries.Count,
GetMoreTime: data.TSCollection.GetMore.Time,
GetMoreCount: data.TSCollection.GetMore.Count,
InsertTime: data.TSCollection.Insert.Time,
InsertCount: data.TSCollection.Insert.Count,
UpdateTime: data.TSCollection.Update.Time,
UpdateCount: data.TSCollection.Update.Count,
RemoveTime: data.TSCollection.Remove.Time,
RemoveCount: data.TSCollection.Remove.Count,
CommandsTime: data.TSCollection.Commands.Time,
CommandsCount: data.TSCollection.Commands.Count,
}
returnVal.TopStatLines = append(returnVal.TopStatLines, *topStatDataLine)
}
}
return returnVal
}