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 }