github.com/alibaba/sentinel-golang@v1.0.4/core/stat/base/metric_bucket.go (about) 1 // Copyright 1999-2020 Alibaba Group Holding Ltd. 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 base 16 17 import ( 18 "sync/atomic" 19 20 "github.com/alibaba/sentinel-golang/core/base" 21 "github.com/alibaba/sentinel-golang/logging" 22 "github.com/pkg/errors" 23 ) 24 25 // MetricBucket represents the entity to record metrics per minimum time unit (i.e. the bucket time span). 26 // Note that all operations of the MetricBucket are required to be thread-safe. 27 type MetricBucket struct { 28 // Value of statistic 29 counter [base.MetricEventTotal]int64 30 minRt int64 31 maxConcurrency int32 32 } 33 34 func NewMetricBucket() *MetricBucket { 35 mb := &MetricBucket{ 36 minRt: base.DefaultStatisticMaxRt, 37 maxConcurrency: 0, 38 } 39 return mb 40 } 41 42 // Add statistic count for the given metric event. 43 func (mb *MetricBucket) Add(event base.MetricEvent, count int64) { 44 if event >= base.MetricEventTotal || event < 0 { 45 logging.Error(errors.Errorf("Unknown metric event: %v", event), "") 46 return 47 } 48 if event == base.MetricEventRt { 49 mb.AddRt(count) 50 return 51 } 52 mb.addCount(event, count) 53 } 54 55 func (mb *MetricBucket) addCount(event base.MetricEvent, count int64) { 56 atomic.AddInt64(&mb.counter[event], count) 57 } 58 59 // Get current statistic count of the given metric event. 60 func (mb *MetricBucket) Get(event base.MetricEvent) int64 { 61 if event >= base.MetricEventTotal || event < 0 { 62 logging.Error(errors.Errorf("Unknown metric event: %v", event), "") 63 return 0 64 } 65 return atomic.LoadInt64(&mb.counter[event]) 66 } 67 68 func (mb *MetricBucket) reset() { 69 for i := 0; i < int(base.MetricEventTotal); i++ { 70 atomic.StoreInt64(&mb.counter[i], 0) 71 } 72 atomic.StoreInt64(&mb.minRt, base.DefaultStatisticMaxRt) 73 atomic.StoreInt32(&mb.maxConcurrency, int32(0)) 74 } 75 76 func (mb *MetricBucket) AddRt(rt int64) { 77 mb.addCount(base.MetricEventRt, rt) 78 if rt < atomic.LoadInt64(&mb.minRt) { 79 // Might not be accurate here. 80 atomic.StoreInt64(&mb.minRt, rt) 81 } 82 } 83 84 func (mb *MetricBucket) MinRt() int64 { 85 return atomic.LoadInt64(&mb.minRt) 86 } 87 88 func (mb *MetricBucket) UpdateConcurrency(concurrency int32) { 89 cc := concurrency 90 if cc > atomic.LoadInt32(&mb.maxConcurrency) { 91 // Might not be accurate here. 92 atomic.StoreInt32(&mb.maxConcurrency, cc) 93 } 94 } 95 96 func (mb *MetricBucket) MaxConcurrency() int32 { 97 return atomic.LoadInt32(&mb.maxConcurrency) 98 }