github.com/cloudwego/hertz@v0.9.3/pkg/common/tracer/stats/event.go (about)

     1  /*
     2   * Copyright 2022 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  	"sync"
    21  	"sync/atomic"
    22  
    23  	"github.com/cloudwego/hertz/pkg/common/errors"
    24  )
    25  
    26  // EventIndex indicates a unique event.
    27  type EventIndex int
    28  
    29  // Level sets the record level.
    30  type Level int
    31  
    32  // Event levels.
    33  const (
    34  	LevelDisabled Level = iota
    35  	LevelBase
    36  	LevelDetailed
    37  )
    38  
    39  // Event is used to indicate a specific event.
    40  type Event interface {
    41  	Index() EventIndex
    42  	Level() Level
    43  }
    44  
    45  type event struct {
    46  	idx   EventIndex
    47  	level Level
    48  }
    49  
    50  // Index implements the Event interface.
    51  func (e event) Index() EventIndex {
    52  	return e.idx
    53  }
    54  
    55  // Level implements the Event interface.
    56  func (e event) Level() Level {
    57  	return e.level
    58  }
    59  
    60  const (
    61  	_ EventIndex = iota
    62  	serverHandleStart
    63  	serverHandleFinish
    64  	httpStart
    65  	httpFinish
    66  	readHeaderStart
    67  	readHeaderFinish
    68  	readBodyStart
    69  	readBodyFinish
    70  	writeStart
    71  	writeFinish
    72  	predefinedEventNum
    73  )
    74  
    75  // Predefined events.
    76  var (
    77  	HTTPStart  = newEvent(httpStart, LevelBase)
    78  	HTTPFinish = newEvent(httpFinish, LevelBase)
    79  
    80  	ServerHandleStart  = newEvent(serverHandleStart, LevelDetailed)
    81  	ServerHandleFinish = newEvent(serverHandleFinish, LevelDetailed)
    82  	ReadHeaderStart    = newEvent(readHeaderStart, LevelDetailed)
    83  	ReadHeaderFinish   = newEvent(readHeaderFinish, LevelDetailed)
    84  	ReadBodyStart      = newEvent(readBodyStart, LevelDetailed)
    85  	ReadBodyFinish     = newEvent(readBodyFinish, LevelDetailed)
    86  	WriteStart         = newEvent(writeStart, LevelDetailed)
    87  	WriteFinish        = newEvent(writeFinish, LevelDetailed)
    88  )
    89  
    90  // errors
    91  var (
    92  	ErrNotAllowed = errors.NewPublic("event definition is not allowed after initialization")
    93  	ErrDuplicated = errors.NewPublic("event name is already defined")
    94  )
    95  
    96  var (
    97  	lock        sync.RWMutex
    98  	inited      int32
    99  	userDefined = make(map[string]Event)
   100  	maxEventNum = int(predefinedEventNum)
   101  )
   102  
   103  // FinishInitialization freezes all events defined and prevents further definitions to be added.
   104  func FinishInitialization() {
   105  	atomic.StoreInt32(&inited, 1)
   106  }
   107  
   108  // DefineNewEvent allows user to add event definitions during program initialization.
   109  func DefineNewEvent(name string, level Level) (Event, error) {
   110  	if atomic.LoadInt32(&inited) == 1 {
   111  		return nil, ErrNotAllowed
   112  	}
   113  	lock.Lock()
   114  	defer lock.Unlock()
   115  	evt, exist := userDefined[name]
   116  	if exist {
   117  		return evt, ErrDuplicated
   118  	}
   119  	userDefined[name] = newEvent(EventIndex(maxEventNum), level)
   120  	maxEventNum++
   121  	return userDefined[name], nil
   122  }
   123  
   124  // MaxEventNum returns the number of event defined.
   125  func MaxEventNum() int {
   126  	lock.RLock()
   127  	defer lock.RUnlock()
   128  	return maxEventNum
   129  }
   130  
   131  func newEvent(idx EventIndex, level Level) Event {
   132  	return event{
   133  		idx:   idx,
   134  		level: level,
   135  	}
   136  }