go.ligato.io/vpp-agent/v3@v3.5.0/pkg/metrics/metrics.go (about)

     1  //  Copyright (c) 2019 Cisco and/or its affiliates.
     2  //
     3  //  Licensed under the Apache License, Version 2.0 (the "License");
     4  //  you may not use this file except in compliance with the License.
     5  //  You may obtain a copy of the License at:
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  //  Unless required by applicable law or agreed to in writing, software
    10  //  distributed under the License is distributed on an "AS IS" BASIS,
    11  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  //  See the License for the specific language governing permissions and
    13  //  limitations under the License.
    14  
    15  package metrics
    16  
    17  import (
    18  	"encoding/json"
    19  	"math"
    20  	"sort"
    21  	"time"
    22  )
    23  
    24  // RoundDuration is the default value used for rounding durations.
    25  var RoundDuration = time.Millisecond * 1
    26  
    27  type Calls map[string]*CallStats
    28  
    29  func (m Calls) Copy() Calls {
    30  	calls := make(Calls)
    31  	for k, s := range m {
    32  		copy := *s
    33  		calls[k] = &copy
    34  	}
    35  	return calls
    36  }
    37  
    38  // MarshalJSON implements json.Marshaler interface
    39  func (m Calls) MarshalJSON() ([]byte, error) {
    40  	calls := make([]*CallStats, 0, len(m))
    41  	for _, s := range m {
    42  		calls = append(calls, s)
    43  	}
    44  	sort.Slice(calls, func(i, j int) bool {
    45  		return calls[i].Count > calls[j].Count
    46  	})
    47  
    48  	return json.Marshal(calls)
    49  }
    50  
    51  // CallStats represents generic stats for call metrics.
    52  type CallStats struct {
    53  	Name  string  `json:"name,omitempty"`
    54  	Count uint64  `json:"count"`
    55  	Total float64 `json:"total,omitempty"`
    56  	Avg   float64 `json:"avg,omitempty"`
    57  	Min   float64 `json:"min,omitempty"`
    58  	Max   float64 `json:"max,omitempty"`
    59  }
    60  
    61  // Increment increments call count and recalculates durations
    62  func (m *CallStats) Increment(d time.Duration) {
    63  	took := d.Round(RoundDuration).Seconds()
    64  	m.Count++
    65  	m.Total = round(m.Total + took)
    66  	m.Avg = round(m.Total / float64(m.Count))
    67  	if took > m.Max {
    68  		m.Max = took
    69  	}
    70  	if m.Min == 0 || took < m.Min {
    71  		m.Min = took
    72  	}
    73  }
    74  
    75  func round(n float64) float64 {
    76  	return math.Round(n*1000) / 1000
    77  }