github.com/facebookincubator/go-belt@v0.0.0-20230703220935-39cd348f1a38/tool/experimental/metrics/README.md (about) 1 # Disclaimer 2 3 This API is experimental and has no stability guarantees. 4 5 # Example 6 ```go 7 package metrics_test 8 9 import ( 10 "context" 11 12 "github.com/facebookincubator/go-belt" 13 "github.com/facebookincubator/go-belt/beltctx" 14 "github.com/facebookincubator/go-belt/tool/experimental/metrics" 15 "github.com/facebookincubator/go-belt/tool/experimental/metrics/implementation/prometheus" 16 "github.com/facebookincubator/go-belt/tool/experimental/metrics/implementation/tsmetrics" 17 ) 18 19 func Example() { 20 var m metrics.Metrics 21 22 // easy to use: 23 m = prometheus.Default() 24 someFunction(1, m) 25 26 // implementation agnostic: 27 m = tsmetrics.New() 28 someFunction(2, m) 29 30 // one may still reuse all the features of the backend Metrics: 31 m.(*tsmetrics.Metrics).Registry.SetDisabled(true) 32 33 // use go-belt to manage the Metrics 34 obs := belt.New() 35 obs = metrics.BeltWithMetrics(obs, m) 36 someBeltyFunction(3, obs) 37 38 // use context to manage the Metrics 39 ctx := context.Background() 40 ctx = metrics.CtxWithMetrics(ctx, m) 41 someContextyFunction(ctx, 4) 42 43 // use a singletony Metrics: 44 metrics.Default = func() metrics.Metrics { 45 return m 46 } 47 yetOneMoreFunction(5) 48 } 49 50 func someFunction(arg int, m metrics.Metrics) { 51 // experience close to logrus/zap: 52 m = metrics.WithField(m, "arg", arg) 53 anotherFunction(m) 54 } 55 56 func anotherFunction(m metrics.Metrics) { 57 m.Count("hello").Add(1) 58 } 59 60 func someBeltyFunction(arg int, obs *belt.Belt) { 61 obs = obs.WithField("arg", arg) 62 anotherBeltyFunction(obs) 63 } 64 65 func anotherBeltyFunction(obs *belt.Belt) { 66 metrics.FromBelt(obs).Count("hello").Add(1) 67 } 68 69 func someContextyFunction(ctx context.Context, arg int) { 70 ctx = beltctx.WithField(ctx, "arg", arg) 71 anotherContextyFunction(ctx) 72 } 73 74 func anotherContextyFunction(ctx context.Context) { 75 metrics.FromCtx(ctx).Count("hello").Add(1) 76 } 77 78 func yetOneMoreFunction(arg int) { 79 m := metrics.Default() 80 m = metrics.WithField(m, "arg", arg) 81 m.Count("hello").Add(1) 82 } 83 ``` 84 85 # Interface 86 ```go 87 // Metrics is a generic interface of a metrics handler. 88 // 89 // It implements belt.Tools, but it ignores TraceIDs reported by the Belt. 90 type Metrics interface { 91 belt.Tool 92 93 // Gauge returns the float64 gauge metric with key "key". 94 // 95 // An use case example: temperature. 96 Gauge(key string) Gauge 97 98 // GaugeFields is the same as Gauge but allows also to add 99 // fields. 100 // 101 // In terms of Prometheus the "fields" are called "labels". 102 GaugeFields(key string, additionalFields field.AbstractFields) Gauge 103 104 // IntGauge returns the int64 gauge metric with key "key". 105 // 106 // An use case example: amount of concurrent requests at this moment. 107 IntGauge(key string) IntGauge 108 109 // IntGaugeFields is the same as IntGauge but allows also to add 110 // fields. 111 // 112 // In terms of Prometheus the "fields" are called "labels". 113 IntGaugeFields(key string, additionalFields field.AbstractFields) IntGauge 114 115 // Count returns the counter metric with key "key". Count may never 116 // go down. It is an monotonically increasing integer, and should 117 // be interpreted that way on the emitter services. For example 118 // a restart of an application (which resets the metric to zero) should 119 // not decrease the value on the emitter. 120 // 121 // An use case example: total amount of requests ever received. 122 Count(key string) Count 123 124 // CountFields is the same as Count but allows also to add 125 // fields. 126 // 127 // In terms of Prometheus the "fields" are called "labels". 128 CountFields(key string, additionalFields field.AbstractFields) Count 129 130 // TBD: extend it with percentile-oriented metrics 131 // TBD: extend it with timing-oriented metrics 132 // TBD: ForEach functions 133 } 134 135 // Metric is an abstract metric. 136 type Metric interface { 137 // Value returns the current value of the metric 138 // 139 // Is not supposed to be used for anything else but metrics exporting or/and debugging/testing. 140 Value() any 141 } 142 143 // Gauge is a float64 gauge metric. 144 // 145 // See also https://prometheus.io/docs/concepts/metric_types/ 146 type Gauge interface { 147 Metric 148 149 // Add adds value "v" to the metric and returns the result. 150 Add(v float64) Gauge 151 152 // WithResetFields returns Gauge with fields replaces to the given ones. 153 // 154 // In terms of Prometheus the "fields" are called "labels". 155 WithResetFields(field.AbstractFields) Gauge 156 } 157 158 // IntGauge is a int64 gauge metric. 159 // 160 // See also https://prometheus.io/docs/concepts/metric_types/ 161 type IntGauge interface { 162 Metric 163 164 // Add adds value "v" to the metric and returns the result. 165 Add(v int64) IntGauge 166 167 // WithResetFields returns IntGauge with fields replaces to the given ones. 168 // 169 // In terms of Prometheus the "fields" are called "labels". 170 WithResetFields(field.AbstractFields) IntGauge 171 } 172 173 // Count is a counter metric. 174 // 175 // See also https://prometheus.io/docs/concepts/metric_types/ 176 type Count interface { 177 Metric 178 179 // Add adds value "v" to the metric and returns the result. 180 Add(v uint64) Count 181 182 // WithResetFields returns Count with fields replaces to the given ones. 183 // 184 // In terms of Prometheus the "fields" are called "labels". 185 WithResetFields(field.AbstractFields) Count 186 } 187 ``` 188