178 lines
4.3 KiB
Go
178 lines
4.3 KiB
Go
|
package metric
|
|||
|
|
|||
|
// prometheus metric:unique identifier: name and optional key-value pairs called labels
|
|||
|
// 1. name regexp: [a-zA-Z_:][a-zA-Z0-9_:]*
|
|||
|
// 2. label name regexp: [a-zA-Z_][a-zA-Z0-9_]*
|
|||
|
// 3. Label names beginning with __ are reserved for internal use.
|
|||
|
// 4. Label values may contain any Unicode characters.
|
|||
|
// 5. notation: <metric name>{<label name>=<label value>, ...}
|
|||
|
// for example: api_http_requests_total{method="POST", handler="/messages"}
|
|||
|
// A label with an empty label value is considered equivalent to a label that does not exist.
|
|||
|
|
|||
|
// each sample consists of :
|
|||
|
// - a float64 value
|
|||
|
// - a millisecond-precision timestamp
|
|||
|
|
|||
|
// metric type:
|
|||
|
// - Counter
|
|||
|
// A cumulative metric that represents a single monotonically increasing counter whose value can only increase or be reset to zero on restart.
|
|||
|
// - Gauge
|
|||
|
// A gauge is a metric that represents a single numerical value that can arbitrarily go up and down.
|
|||
|
// - Histogram
|
|||
|
// A histogram samples observations (usually things like request durations or response sizes) and counts them in configurable buckets. It also provides a sum of all observed values.
|
|||
|
// - Summary
|
|||
|
// Similar to a histogram, a summary samples observations (usually things like request durations and response sizes). While it also provides a total count of observations and a sum of all observed values, it calculates configurable quantiles over a sliding time window.
|
|||
|
// metric:
|
|||
|
// Counter:
|
|||
|
// - req_total_count
|
|||
|
// - req_failed_count
|
|||
|
// Gauge:
|
|||
|
// - heap_inuse_size
|
|||
|
// - heap_total_size
|
|||
|
// - heap_object_num
|
|||
|
// - goroutine_num
|
|||
|
// Histogram:
|
|||
|
// - req_cost_time
|
|||
|
// Summary:
|
|||
|
// - req_cost_time
|
|||
|
|
|||
|
import (
|
|||
|
"net/http"
|
|||
|
"sync"
|
|||
|
|
|||
|
"github.com/prometheus/client_golang/prometheus"
|
|||
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|||
|
)
|
|||
|
|
|||
|
const (
|
|||
|
//ENV = "env"
|
|||
|
APP = "snow"
|
|||
|
VER = "ver"
|
|||
|
)
|
|||
|
|
|||
|
var (
|
|||
|
collectors = []prometheus.Collector{}
|
|||
|
)
|
|||
|
|
|||
|
func RegisterCollector(c ...prometheus.Collector) {
|
|||
|
collectors = append(collectors, c...)
|
|||
|
}
|
|||
|
|
|||
|
type Options struct {
|
|||
|
labels map[string]string
|
|||
|
processEnable bool
|
|||
|
runtimeEnable bool
|
|||
|
}
|
|||
|
|
|||
|
type Option func(opt *Options)
|
|||
|
|
|||
|
// 添加App和Ver label
|
|||
|
func AppVer(app, ver string) Option {
|
|||
|
return func(opt *Options) {
|
|||
|
if app != "" {
|
|||
|
opt.labels[APP] = app
|
|||
|
}
|
|||
|
if ver != "" {
|
|||
|
opt.labels[VER] = ver
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 添加额外label
|
|||
|
func WithLabel(key, val string) Option {
|
|||
|
return func(opt *Options) {
|
|||
|
if key != "" && val != "" {
|
|||
|
opt.labels[key] = val
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 收集进程信息
|
|||
|
func EnableProcess() Option {
|
|||
|
return func(opt *Options) {
|
|||
|
opt.processEnable = true
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func EnableRuntime() Option {
|
|||
|
return func(opt *Options) {
|
|||
|
opt.runtimeEnable = true
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
type Reporter struct {
|
|||
|
opts Options
|
|||
|
collectors []prometheus.Collector
|
|||
|
// registerer
|
|||
|
registerer prometheus.Registerer
|
|||
|
gatherer prometheus.Gatherer
|
|||
|
}
|
|||
|
|
|||
|
var (
|
|||
|
once sync.Once
|
|||
|
reporter Reporter
|
|||
|
)
|
|||
|
|
|||
|
func Init(opts ...Option) {
|
|||
|
_opts := Options{
|
|||
|
labels: map[string]string{},
|
|||
|
}
|
|||
|
for _, opt := range opts {
|
|||
|
opt(&_opts)
|
|||
|
}
|
|||
|
|
|||
|
once.Do(func() {
|
|||
|
cs := collectors
|
|||
|
if _opts.processEnable {
|
|||
|
cs = append(cs, prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}))
|
|||
|
}
|
|||
|
|
|||
|
if _opts.runtimeEnable {
|
|||
|
cs = append(cs, prometheus.NewGoCollector())
|
|||
|
}
|
|||
|
|
|||
|
reporter = Reporter{
|
|||
|
opts: _opts,
|
|||
|
collectors: cs,
|
|||
|
}
|
|||
|
|
|||
|
registry := prometheus.NewRegistry()
|
|||
|
|
|||
|
reporter.registerer = prometheus.WrapRegistererWith(reporter.opts.labels, registry)
|
|||
|
reporter.gatherer = registry
|
|||
|
|
|||
|
reporter.registerer.MustRegister(reporter.collectors...)
|
|||
|
|
|||
|
})
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (p *Reporter) newCounterVec(metric string, labels []string) *prometheus.CounterVec {
|
|||
|
counterVec := prometheus.NewCounterVec(prometheus.CounterOpts{
|
|||
|
Name: metric,
|
|||
|
}, labels)
|
|||
|
|
|||
|
return counterVec
|
|||
|
}
|
|||
|
|
|||
|
func (p *Reporter) newGaugeVec(metric string, labels []string) *prometheus.GaugeVec {
|
|||
|
gaugeVec := prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
|||
|
Name: metric,
|
|||
|
}, labels)
|
|||
|
return gaugeVec
|
|||
|
}
|
|||
|
|
|||
|
func (p *Reporter) newHistogramVec(metric string, labels []string, buckets []float64) *prometheus.HistogramVec {
|
|||
|
histogramVec := prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
|||
|
Name: metric,
|
|||
|
Buckets: buckets,
|
|||
|
}, labels)
|
|||
|
return histogramVec
|
|||
|
}
|
|||
|
|
|||
|
func Handler() http.Handler {
|
|||
|
return promhttp.InstrumentMetricHandler(
|
|||
|
reporter.registerer, promhttp.HandlerFor(reporter.gatherer, promhttp.HandlerOpts{}),
|
|||
|
)
|
|||
|
}
|