138 lines
3.9 KiB
Go
138 lines
3.9 KiB
Go
package monitoring
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
|
|
"go.opentelemetry.io/otel/exporters/prometheus"
|
|
"go.opentelemetry.io/otel/metric"
|
|
"go.opentelemetry.io/otel/metric/global"
|
|
"go.opentelemetry.io/otel/metric/instrument/syncfloat64"
|
|
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
|
|
controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
|
|
"go.opentelemetry.io/otel/sdk/metric/export/aggregation"
|
|
processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
|
|
selector "go.opentelemetry.io/otel/sdk/metric/selector/simple"
|
|
)
|
|
|
|
// Metrics stores all collected metrics
|
|
type Metrics struct {
|
|
meter metric.Meter
|
|
counters map[string]syncfloat64.Counter
|
|
upDownCounters map[string]syncfloat64.UpDownCounter
|
|
histograms map[string]syncfloat64.Histogram
|
|
}
|
|
|
|
func New(name string) *Metrics {
|
|
m := &Metrics{
|
|
counters: make(map[string]syncfloat64.Counter),
|
|
upDownCounters: make(map[string]syncfloat64.UpDownCounter),
|
|
histograms: make(map[string]syncfloat64.Histogram),
|
|
}
|
|
m.initPrometheusDataExporter()
|
|
m.initMetrics(name)
|
|
return m
|
|
}
|
|
|
|
// initPrometheusDataExporter allows to use collected metrics in prometheus
|
|
func (m *Metrics) initPrometheusDataExporter() {
|
|
config := prometheus.Config{
|
|
DefaultHistogramBoundaries: []float64{1, 2, 5, 10, 20, 50},
|
|
}
|
|
c := controller.New(
|
|
processor.NewFactory(
|
|
selector.NewWithHistogramDistribution(
|
|
histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries),
|
|
),
|
|
aggregation.CumulativeTemporalitySelector(),
|
|
processor.WithMemory(true),
|
|
),
|
|
)
|
|
exporter, err := prometheus.New(config, c)
|
|
if err != nil {
|
|
log.Panicf("failed to initialize prometheus exporter %v", err)
|
|
}
|
|
|
|
global.SetMeterProvider(exporter.MeterProvider())
|
|
|
|
http.HandleFunc("/metrics", exporter.ServeHTTP)
|
|
go func() {
|
|
_ = http.ListenAndServe(":8888", nil)
|
|
}()
|
|
|
|
fmt.Println("Prometheus server running on :8888")
|
|
}
|
|
|
|
func (m *Metrics) initMetrics(name string) {
|
|
m.meter = global.Meter(name)
|
|
}
|
|
|
|
/*
|
|
Counter is a synchronous instrument that measures additive non-decreasing values, for example, the number of:
|
|
- processed requests
|
|
- received bytes
|
|
- disk reads
|
|
*/
|
|
|
|
func (m *Metrics) RegisterCounter(name string) (syncfloat64.Counter, error) {
|
|
if _, ok := m.counters[name]; ok {
|
|
return nil, fmt.Errorf("counter %s already exists", name)
|
|
}
|
|
counter, err := m.meter.SyncFloat64().Counter(name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to initialize counter: %v", err)
|
|
}
|
|
m.counters[name] = counter
|
|
return counter, nil
|
|
}
|
|
|
|
func (m *Metrics) GetCounter(name string) syncfloat64.Counter {
|
|
return m.counters[name]
|
|
}
|
|
|
|
/*
|
|
UpDownCounter is a synchronous instrument which measures additive values that increase or decrease with time,
|
|
for example, the number of:
|
|
- active requests
|
|
- open connections
|
|
- memory in use (megabytes)
|
|
*/
|
|
|
|
func (m *Metrics) RegisterUpDownCounter(name string) (syncfloat64.UpDownCounter, error) {
|
|
if _, ok := m.upDownCounters[name]; ok {
|
|
return nil, fmt.Errorf("upDownCounter %s already exists", name)
|
|
}
|
|
counter, err := m.meter.SyncFloat64().UpDownCounter(name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to initialize upDownCounter: %v", err)
|
|
}
|
|
m.upDownCounters[name] = counter
|
|
return counter, nil
|
|
}
|
|
|
|
func (m *Metrics) GetUpDownCounter(name string) syncfloat64.UpDownCounter {
|
|
return m.upDownCounters[name]
|
|
}
|
|
|
|
/*
|
|
Histogram is a synchronous instrument that produces a histogram from recorded values, for example:
|
|
- request latency
|
|
- request size
|
|
*/
|
|
|
|
func (m *Metrics) RegisterHistogram(name string) (syncfloat64.Histogram, error) {
|
|
if _, ok := m.histograms[name]; ok {
|
|
return nil, fmt.Errorf("histogram %s already exists", name)
|
|
}
|
|
hist, err := m.meter.SyncFloat64().Histogram(name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to initialize histogram: %v", err)
|
|
}
|
|
m.histograms[name] = hist
|
|
return hist, nil
|
|
}
|
|
|
|
func (m *Metrics) GetHistogram(name string) syncfloat64.Histogram {
|
|
return m.histograms[name]
|
|
}
|