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  }