github.com/cloudwego/kitex@v0.9.0/pkg/stats/event.go (about) 1 /* 2 * Copyright 2021 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package stats 18 19 import ( 20 "errors" 21 "sync" 22 "sync/atomic" 23 ) 24 25 // EventIndex indicates a unique event. 26 type EventIndex int 27 28 // Level sets the record level. 29 type Level int 30 31 // Event levels. 32 const ( 33 LevelDisabled Level = iota 34 LevelBase 35 LevelDetailed 36 ) 37 38 // Event is used to indicate a specific event. 39 type Event interface { 40 Index() EventIndex 41 Level() Level 42 } 43 44 type event struct { 45 idx EventIndex 46 level Level 47 } 48 49 // Index implements the Event interface. 50 func (e event) Index() EventIndex { 51 return e.idx 52 } 53 54 // Level implements the Event interface. 55 func (e event) Level() Level { 56 return e.level 57 } 58 59 const ( 60 _ EventIndex = iota 61 serverHandleStart 62 serverHandleFinish 63 clientConnStart 64 clientConnFinish 65 rpcStart 66 rpcFinish 67 readStart 68 readFinish 69 waitReadStart 70 waitReadFinish 71 writeStart 72 writeFinish 73 streamRecv 74 streamSend 75 76 // NOTE: add new events before this line 77 predefinedEventNum 78 ) 79 80 // Predefined events. 81 var ( 82 RPCStart = newEvent(rpcStart, LevelBase) 83 RPCFinish = newEvent(rpcFinish, LevelBase) 84 85 ServerHandleStart = newEvent(serverHandleStart, LevelDetailed) 86 ServerHandleFinish = newEvent(serverHandleFinish, LevelDetailed) 87 ClientConnStart = newEvent(clientConnStart, LevelDetailed) 88 ClientConnFinish = newEvent(clientConnFinish, LevelDetailed) 89 ReadStart = newEvent(readStart, LevelDetailed) 90 ReadFinish = newEvent(readFinish, LevelDetailed) 91 WaitReadStart = newEvent(waitReadStart, LevelDetailed) 92 WaitReadFinish = newEvent(waitReadFinish, LevelDetailed) 93 WriteStart = newEvent(writeStart, LevelDetailed) 94 WriteFinish = newEvent(writeFinish, LevelDetailed) 95 96 // Streaming Events 97 StreamRecv = newEvent(streamRecv, LevelDetailed) 98 StreamSend = newEvent(streamSend, LevelDetailed) 99 ) 100 101 // errors 102 var ( 103 ErrNotAllowed = errors.New("event definition is not allowed after initialization") 104 ErrDuplicated = errors.New("event name is already defined") 105 ) 106 107 var ( 108 lock sync.RWMutex 109 inited int32 110 userDefined = make(map[string]Event) 111 maxEventNum = int(predefinedEventNum) 112 ) 113 114 // FinishInitialization freezes all events defined and prevents further definitions to be added. 115 func FinishInitialization() { 116 lock.Lock() 117 defer lock.Unlock() 118 atomic.StoreInt32(&inited, 1) 119 } 120 121 // DefineNewEvent allows user to add event definitions during program initialization. 122 func DefineNewEvent(name string, level Level) (Event, error) { 123 if atomic.LoadInt32(&inited) == 1 { 124 return nil, ErrNotAllowed 125 } 126 lock.Lock() 127 defer lock.Unlock() 128 evt, exist := userDefined[name] 129 if exist { 130 return evt, ErrDuplicated 131 } 132 userDefined[name] = newEvent(EventIndex(maxEventNum), level) 133 maxEventNum++ 134 return userDefined[name], nil 135 } 136 137 // MaxEventNum returns the number of event defined. 138 func MaxEventNum() int { 139 lock.RLock() 140 defer lock.RUnlock() 141 return maxEventNum 142 } 143 144 // PredefinedEventNum returns the number of predefined events of kitex. 145 func PredefinedEventNum() int { 146 return int(predefinedEventNum) 147 } 148 149 func newEvent(idx EventIndex, level Level) Event { 150 return event{ 151 idx: idx, 152 level: level, 153 } 154 }