github.com/alibaba/ilogtail/pkg@v0.0.0-20250526110833-c53b480d046c/selfmonitor/metrics_imp.go (about)

     1  // Copyright 2021 iLogtail Authors
     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 selfmonitor
    16  
    17  import (
    18  	"sync"
    19  	"sync/atomic"
    20  	"time"
    21  
    22  	"github.com/alibaba/ilogtail/pkg/protocol"
    23  )
    24  
    25  var mu sync.Mutex
    26  
    27  type StrMetric struct {
    28  	name   string
    29  	value  string
    30  	labels []*protocol.Log_Content
    31  }
    32  
    33  func (s *StrMetric) Name() string {
    34  	return getNameWithLables(s.name, s.labels)
    35  }
    36  
    37  func (s *StrMetric) Set(v string) {
    38  	mu.Lock()
    39  	s.value = v
    40  	mu.Unlock()
    41  }
    42  
    43  func (s *StrMetric) Get() string {
    44  	mu.Lock()
    45  	v := s.value
    46  	mu.Unlock()
    47  	return v
    48  }
    49  
    50  func (s *StrMetric) Collect() string {
    51  	mu.Lock()
    52  	v := s.value
    53  	s.value = ""
    54  	mu.Unlock()
    55  	return v
    56  }
    57  
    58  type NormalMetric struct {
    59  	name   string
    60  	value  int64
    61  	labels []*protocol.Log_Content
    62  }
    63  
    64  func (s *NormalMetric) Add(v int64) {
    65  	atomic.AddInt64(&s.value, v)
    66  }
    67  
    68  func (s *NormalMetric) Clear(v int64) {
    69  	atomic.StoreInt64(&s.value, v)
    70  }
    71  
    72  func (s *NormalMetric) Get() int64 {
    73  	return atomic.LoadInt64(&s.value)
    74  }
    75  
    76  func (s *NormalMetric) Name() string {
    77  	return getNameWithLables(s.name, s.labels)
    78  }
    79  
    80  func (s *NormalMetric) Collect() int64 {
    81  	return atomic.SwapInt64(&s.value, 0)
    82  }
    83  
    84  type AvgMetric struct {
    85  	name    string
    86  	value   int64
    87  	count   int64
    88  	prevAvg float64
    89  	labels  []*protocol.Log_Content
    90  }
    91  
    92  func (s *AvgMetric) Add(v int64) {
    93  	mu.Lock()
    94  	s.value += v
    95  	s.count++
    96  	mu.Unlock()
    97  }
    98  
    99  func (s *AvgMetric) Clear(v int64) {
   100  	mu.Lock()
   101  	s.value = 0
   102  	s.count = 0
   103  	s.prevAvg = 0.0
   104  	mu.Unlock()
   105  }
   106  
   107  func (s *AvgMetric) Get() int64 {
   108  	return int64(s.GetAvg())
   109  }
   110  
   111  func (s *AvgMetric) GetAvg() float64 {
   112  	var avg float64
   113  	mu.Lock()
   114  	if s.count > 0 {
   115  		s.prevAvg, avg = float64(s.value)/float64(s.count), float64(s.value)/float64(s.count)
   116  		s.value = 0
   117  		s.count = 0
   118  	} else {
   119  		avg = s.prevAvg
   120  	}
   121  	mu.Unlock()
   122  	return avg
   123  }
   124  
   125  func (s *AvgMetric) Name() string {
   126  	return getNameWithLables(s.name, s.labels)
   127  }
   128  
   129  func (s *AvgMetric) Collect() int64 {
   130  	var avg float64
   131  	mu.Lock()
   132  	if s.count > 0 {
   133  		s.prevAvg, avg = float64(s.value)/float64(s.count), float64(s.value)/float64(s.count)
   134  		s.value = 0
   135  		s.count = 0
   136  	} else {
   137  		avg = s.prevAvg
   138  	}
   139  	s.value = 0
   140  	s.count = 0
   141  	s.prevAvg = 0.0
   142  	mu.Unlock()
   143  	return int64(avg)
   144  }
   145  
   146  type LatMetric struct {
   147  	name       string
   148  	t          time.Time
   149  	count      int
   150  	latencySum time.Duration
   151  	labels     []*protocol.Log_Content
   152  }
   153  
   154  func (s *LatMetric) Name() string {
   155  	return getNameWithLables(s.name, s.labels)
   156  }
   157  
   158  func (s *LatMetric) Begin() {
   159  	mu.Lock()
   160  	s.t = time.Now()
   161  	mu.Unlock()
   162  }
   163  
   164  func (s *LatMetric) End() {
   165  	endT := time.Now()
   166  	mu.Lock()
   167  	s.count++
   168  	s.latencySum += endT.Sub(s.t)
   169  	mu.Unlock()
   170  }
   171  
   172  func (s *LatMetric) Clear() {
   173  	mu.Lock()
   174  	s.count = 0
   175  	s.latencySum = 0
   176  	s.t = time.Unix(0, 0)
   177  	mu.Unlock()
   178  }
   179  
   180  func (s *LatMetric) Get() int64 {
   181  	mu.Lock()
   182  	v := int64(0)
   183  	if s.count != 0 {
   184  		v = int64(s.latencySum) / int64(s.count)
   185  	}
   186  	mu.Unlock()
   187  	return v
   188  }
   189  
   190  func (s *LatMetric) Collect() int64 {
   191  	mu.Lock()
   192  	v := int64(0)
   193  	if s.count != 0 {
   194  		v = int64(s.latencySum) / int64(s.count)
   195  	}
   196  	s.count = 0
   197  	s.latencySum = 0
   198  	s.t = time.Unix(0, 0)
   199  	mu.Unlock()
   200  	return v
   201  }
   202  
   203  func getNameWithLables(name string, labels []*protocol.Log_Content) string {
   204  	n := name
   205  	for _, lable := range labels {
   206  		n = n + "#" + lable.Key + "=" + lable.Value
   207  	}
   208  	return n
   209  }