github.com/polarismesh/polaris@v1.17.8/plugin/statis/base/cachecall.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package base 19 20 import ( 21 "context" 22 "fmt" 23 "sync" 24 "time" 25 26 commonlog "github.com/polarismesh/polaris/common/log" 27 "github.com/polarismesh/polaris/common/metrics" 28 commontime "github.com/polarismesh/polaris/common/time" 29 ) 30 31 // CacheCall 接口调用 32 type CacheCall struct { 33 cacheType string 34 miss bool 35 count int32 36 } 37 38 // CacheCallStatisItem 接口调用统计条目 39 type CacheCallStatisItem struct { 40 cacheType string 41 hitCount int64 42 missCount int64 43 hitRate float64 44 } 45 46 // ComponentCacheStatics statics components 47 type CacheStatics struct { 48 mutex *sync.Mutex 49 statis map[string]*CacheCallStatisItem 50 CacheCallStatis *CacheCallStatis 51 } 52 53 func NewCacheStatics(statis *CacheCallStatis) *CacheStatics { 54 return &CacheStatics{ 55 mutex: &sync.Mutex{}, 56 statis: make(map[string]*CacheCallStatisItem), 57 CacheCallStatis: statis, 58 } 59 } 60 61 func (c *CacheStatics) Add(ac metrics.CallMetric) { 62 index := fmt.Sprintf("%v", ac.Protocol) 63 item, exist := c.statis[index] 64 if !exist { 65 c.statis[index] = &CacheCallStatisItem{ 66 cacheType: ac.Protocol, 67 } 68 } 69 70 item = c.statis[index] 71 if ac.Success { 72 item.hitCount += int64(ac.Times) 73 } else { 74 item.missCount += int64(ac.Times) 75 76 } 77 } 78 79 func (c *CacheStatics) printStatics(staticsSlice []*CacheCallStatisItem, startStr string) { 80 c.mutex.Lock() 81 defer c.mutex.Unlock() 82 msg := fmt.Sprintf("Statis %s:\n", startStr) 83 84 msg += fmt.Sprintf( 85 "%-48v|%12v|%12v|%12v|\n", "", "HitCount", "MissCount", "HitRate") 86 87 for _, item := range staticsSlice { 88 if item.hitCount == 0 && item.missCount == 0 { 89 continue 90 } 91 msg += fmt.Sprintf("%-48v|%12v|%12v|%12.3f|\n", 92 item.cacheType, item.hitCount, item.missCount, 93 float64(item.hitCount)/float64(item.hitCount+item.missCount), 94 ) 95 } 96 commonlog.Info(msg) 97 } 98 99 // log and print the statics messages 100 func (c *CacheStatics) log() { 101 if len(c.statis) == 0 { 102 return 103 } 104 105 duplicateStatis := make([]*CacheCallStatisItem, 0, len(c.statis)) 106 for _, item := range c.statis { 107 duplicateStatis = append(duplicateStatis, item) 108 } 109 c.statis = make(map[string]*CacheCallStatisItem) 110 111 go c.printStatics(duplicateStatis, commontime.Time2String(time.Now())) 112 } 113 114 // CacheCallStatis 接口调用统计 115 type CacheCallStatis struct { 116 cacheCall chan metrics.CallMetric 117 cacheStatics *CacheStatics 118 } 119 120 func NewCacheCallStatis(ctx context.Context) (*CacheCallStatis, error) { 121 value := &CacheCallStatis{ 122 cacheCall: make(chan metrics.CallMetric, 1024), 123 } 124 value.cacheStatics = NewCacheStatics(value) 125 126 go func() { 127 for { 128 select { 129 case <-ctx.Done(): 130 return 131 case ac := <-value.cacheCall: 132 value.cacheStatics.Add(ac) 133 } 134 } 135 }() 136 137 return value, nil 138 } 139 140 // add 添加接口调用数据 141 func (a *CacheCallStatis) Add(ac metrics.CallMetric) { 142 select { 143 case a.cacheCall <- ac: 144 } 145 } 146 147 // log 打印接口调用统计 148 func (a *CacheCallStatis) deal() { 149 a.cacheStatics.log() 150 }