github.com/wfusion/gofusion@v1.1.14/common/infra/metrics/start.go (about)

     1  package metrics
     2  
     3  import (
     4  	"os"
     5  	"sync"
     6  	"sync/atomic"
     7  	"time"
     8  
     9  	"github.com/wfusion/gofusion/common/utils"
    10  
    11  	iradix "github.com/hashicorp/go-immutable-radix"
    12  )
    13  
    14  // Config is used to configure metrics settings
    15  type Config struct {
    16  	ServiceName         string        // Prefixed with keys to separate services
    17  	HostName            string        // Hostname to use. If not provided and EnableHostname, it will be os.Hostname
    18  	EnableHostname      bool          // Enable prefixing gauge values with hostname
    19  	EnableHostnameLabel bool          // Enable adding hostname to labels
    20  	EnableServiceLabel  bool          // Enable adding service to labels
    21  	EnableClientIPLabel bool          // Enable adding service ip to labels
    22  	EnableTypePrefix    bool          // Prefixes key with a type ("counter", "gauge", "timer")
    23  	TimerGranularity    time.Duration // Granularity of timers.
    24  	ProfileInterval     time.Duration // Interval to profile runtime metrics
    25  
    26  	AllowedPrefixes []string // A list of metric prefixes to allow, with '.' as the separator
    27  	BlockedPrefixes []string // A list of metric prefixes to block, with '.' as the separator
    28  	AllowedLabels   []string // A list of metric labels to allow, with '.' as the separator
    29  	BlockedLabels   []string // A list of metric labels to block, with '.' as the separator
    30  	FilterDefault   bool     // Whether to allow metrics by default
    31  }
    32  
    33  // Metrics represents an instance of a metrics sink that can
    34  // be used to emit
    35  type Metrics struct {
    36  	Config
    37  	sink          MetricSink
    38  	filter        *iradix.Tree
    39  	allowedLabels map[string]bool
    40  	blockedLabels map[string]bool
    41  	filterLock    sync.RWMutex // Lock filters and allowedLabels/blockedLabels access
    42  }
    43  
    44  // Shared global metrics instance
    45  var globalMetrics atomic.Value // *Metrics
    46  
    47  func init() {
    48  	// Initialize to a blackhole sink to avoid errors
    49  	globalMetrics.Store(&Metrics{sink: &BlackholeSink{}})
    50  }
    51  
    52  // Default returns the shared global metrics instance.
    53  func Default() *Metrics {
    54  	return globalMetrics.Load().(*Metrics)
    55  }
    56  
    57  // DefaultConfig provides a sane default configuration
    58  func DefaultConfig(serviceName string) *Config {
    59  	c := &Config{
    60  		ServiceName:      serviceName, // Use client provided service
    61  		HostName:         "",
    62  		EnableHostname:   true,             // Enable hostname prefix
    63  		EnableTypePrefix: false,            // Disable type prefix
    64  		TimerGranularity: time.Millisecond, // Timers are in milliseconds
    65  		ProfileInterval:  time.Second,      // Poll runtime every second
    66  		FilterDefault:    true,             // Don't filter metrics by default
    67  	}
    68  
    69  	// Try to get the hostname
    70  	name, _ := os.Hostname()
    71  	c.HostName = name
    72  	return c
    73  }
    74  
    75  // New is used to create a new instance of Metrics
    76  func New(conf *Config, sink MetricSink, opts ...utils.OptionExtender) (*Metrics, error) {
    77  	met := &Metrics{}
    78  	met.Config = *conf
    79  	met.sink = sink
    80  	met.UpdateFilterAndLabels(conf.AllowedPrefixes, conf.BlockedPrefixes, conf.AllowedLabels, conf.BlockedLabels)
    81  
    82  	return met, nil
    83  }
    84  
    85  // NewGlobal is the same as New, but it assigns the metrics object to be
    86  // used globally as well as returning it.
    87  func NewGlobal(conf *Config, sink MetricSink) (*Metrics, error) {
    88  	metrics, err := New(conf, sink)
    89  	if err == nil {
    90  		globalMetrics.Store(metrics)
    91  	}
    92  	return metrics, err
    93  }
    94  
    95  // Proxy all the methods to the globalMetrics instance
    96  
    97  // SetGauge Set gauge key and value with 32 bit precision
    98  func SetGauge(key []string, val float32, opts ...utils.OptionExtender) {
    99  	globalMetrics.Load().(*Metrics).SetGauge(key, val, opts...)
   100  }
   101  
   102  // SetGaugeWithLabels Set gauge key and value with 32 bit precision
   103  func SetGaugeWithLabels(key []string, val float32, labels []Label, opts ...utils.OptionExtender) {
   104  	globalMetrics.Load().(*Metrics).SetGaugeWithLabels(key, val, labels, opts...)
   105  }
   106  
   107  // SetPrecisionGauge Set gauge key and value with 64 bit precision
   108  // The Sink needs to implement PrecisionGaugeMetricSink, in case it doesn't,
   109  // the metric value won't be set and ingored instead
   110  func SetPrecisionGauge(key []string, val float64, opts ...utils.OptionExtender) {
   111  	globalMetrics.Load().(*Metrics).SetPrecisionGauge(key, val, opts...)
   112  }
   113  
   114  // SetPrecisionGaugeWithLabels Set gauge key, value with 64 bit precision, and labels
   115  // The Sink needs to implement PrecisionGaugeMetricSink, in case it doesn't,
   116  // the metric value won't be set and ingored instead
   117  func SetPrecisionGaugeWithLabels(key []string, val float64, labels []Label, opts ...utils.OptionExtender) {
   118  	globalMetrics.Load().(*Metrics).SetPrecisionGaugeWithLabels(key, val, labels, opts...)
   119  }
   120  
   121  func EmitKey(key []string, val float32, opts ...utils.OptionExtender) {
   122  	globalMetrics.Load().(*Metrics).EmitKey(key, val, opts...)
   123  }
   124  
   125  func IncrCounter(key []string, val float32, opts ...utils.OptionExtender) {
   126  	globalMetrics.Load().(*Metrics).IncrCounter(key, val, opts...)
   127  }
   128  
   129  func IncrCounterWithLabels(key []string, val float32, labels []Label, opts ...utils.OptionExtender) {
   130  	globalMetrics.Load().(*Metrics).IncrCounterWithLabels(key, val, labels, opts...)
   131  }
   132  
   133  func AddSample(key []string, val float32, opts ...utils.OptionExtender) {
   134  	globalMetrics.Load().(*Metrics).AddSample(key, val, opts...)
   135  }
   136  
   137  func AddSampleWithLabels(key []string, val float32, labels []Label, opts ...utils.OptionExtender) {
   138  	globalMetrics.Load().(*Metrics).AddSampleWithLabels(key, val, labels, opts...)
   139  }
   140  
   141  func MeasureSince(key []string, start time.Time, opts ...utils.OptionExtender) {
   142  	globalMetrics.Load().(*Metrics).MeasureSince(key, start, opts...)
   143  }
   144  
   145  func MeasureSinceWithLabels(key []string, start time.Time, labels []Label, opts ...utils.OptionExtender) {
   146  	globalMetrics.Load().(*Metrics).MeasureSinceWithLabels(key, start, labels, opts...)
   147  }
   148  
   149  func UpdateFilter(allow, block []string) {
   150  	globalMetrics.Load().(*Metrics).UpdateFilter(allow, block)
   151  }
   152  
   153  // UpdateFilterAndLabels set allow/block prefixes of metrics while allowedLabels
   154  // and blockedLabels - when not nil - allow filtering of labels in order to
   155  // block/allow globally labels (especially useful when having large number of
   156  // values for a given label). See README.md for more information about usage.
   157  func UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels []string) {
   158  	globalMetrics.Load().(*Metrics).UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels)
   159  }
   160  
   161  // Shutdown disables metric collection, then blocks while attempting to flush metrics to storage.
   162  // WARNING: Not all MetricSink backends support this functionality, and calling this will cause them to leak resources.
   163  // This is intended for use immediately prior to application exit.
   164  func Shutdown() {
   165  	m := globalMetrics.Load().(*Metrics)
   166  	// Swap whatever MetricSink is currently active with a BlackholeSink. Callers must not have a
   167  	// reason to expect that calls to the library will successfully collect metrics after Shutdown
   168  	// has been called.
   169  	globalMetrics.Store(&Metrics{sink: &BlackholeSink{}})
   170  	m.Shutdown()
   171  }