309 lines
8.4 KiB
Go
309 lines
8.4 KiB
Go
package prom
|
|
|
|
import (
|
|
"math/rand"
|
|
"runtime"
|
|
"sync"
|
|
"time"
|
|
|
|
"go-common/app/interface/openplatform/monitor-end/conf"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
const (
|
|
_department = "open"
|
|
_typeCommon = "Common"
|
|
_typeDetailed = "Detailed"
|
|
_NaN = "NaN"
|
|
)
|
|
|
|
var (
|
|
// HTTPClientSum HTTP Client request cost sum.
|
|
HTTPClientSum *Prom
|
|
// HTTPClientCount HTTP Client request count.
|
|
HTTPClientCount *Prom
|
|
// HTTPClientCode HTTP Client request server code count.
|
|
HTTPClientCode *Prom
|
|
// HTTPClientStatus HTTP Client request status.
|
|
HTTPClientStatus *Prom
|
|
// HTTPClientSummary HTTP Client request quantiles.
|
|
HTTPClientSummary *Prom
|
|
)
|
|
|
|
var c *conf.Config
|
|
|
|
// Prom struct info
|
|
type Prom struct {
|
|
timer *prometheus.HistogramVec
|
|
counter *prometheus.CounterVec
|
|
state *prometheus.GaugeVec
|
|
summary *prometheus.SummaryVec
|
|
}
|
|
|
|
// Init .
|
|
func Init(ce *conf.Config) {
|
|
c = ce
|
|
NewProm(true)
|
|
go clearMemory()
|
|
}
|
|
|
|
func clearMemory() {
|
|
for {
|
|
// default 512MB accloc
|
|
var limit = uint64(512 * 1024 * 1024)
|
|
memStat := new(runtime.MemStats)
|
|
runtime.ReadMemStats(memStat)
|
|
used := memStat.Alloc
|
|
if c.Prom.Limit > 0 && c.Prom.Limit < 3072 {
|
|
limit = uint64(c.Prom.Limit * 1024 * 1024)
|
|
}
|
|
if used > limit {
|
|
NewProm(false)
|
|
}
|
|
time.Sleep(time.Minute)
|
|
}
|
|
}
|
|
|
|
// NewProm .
|
|
func NewProm(isFirst bool) {
|
|
if isFirst {
|
|
HTTPClientSum = New().WithCounter("http_client_sum", []string{"target", "client_app", "department", "type", "method", "event", "version", "detail"})
|
|
HTTPClientCount = New().WithCounter("http_client_count", []string{"target", "client_app", "department", "type", "method", "event", "version", "detail"})
|
|
HTTPClientCode = New().WithCounter("http_client_code", []string{"target", "client_app", "department", "type", "method", "event", "version", "code"})
|
|
HTTPClientStatus = New().WithCounter("http_client_status", []string{"target", "client_app", "department", "type", "method", "event", "version", "status"})
|
|
HTTPClientSummary = New().WithQuantile("http_client_summary", []string{"target", "client_app", "department", "type", "method", "event", "version", "detail"})
|
|
return
|
|
}
|
|
var mutex sync.Mutex
|
|
mutex.Lock()
|
|
HTTPClientSum.Unregister()
|
|
HTTPClientSum = New().WithCounter("http_client_sum", []string{"target", "client_app", "department", "type", "method", "event", "version", "detail"})
|
|
HTTPClientCount.Unregister()
|
|
HTTPClientCount = New().WithCounter("http_client_count", []string{"target", "client_app", "department", "type", "method", "event", "version", "detail"})
|
|
HTTPClientCode.Unregister()
|
|
HTTPClientCode = New().WithCounter("http_client_code", []string{"target", "client_app", "department", "type", "method", "event", "version", "code"})
|
|
HTTPClientStatus.Unregister()
|
|
HTTPClientStatus = New().WithCounter("http_client_status", []string{"target", "client_app", "department", "type", "method", "event", "version", "status"})
|
|
HTTPClientSummary.Unregister()
|
|
HTTPClientSummary = New().WithQuantile("http_client_summary", []string{"target", "client_app", "department", "type", "method", "event", "version", "detail"})
|
|
mutex.Unlock()
|
|
}
|
|
|
|
// New creates a Prom instance.
|
|
func New() *Prom {
|
|
return &Prom{}
|
|
}
|
|
|
|
// WithTimer with summary timer
|
|
func (p *Prom) WithTimer(name string, labels []string) *Prom {
|
|
if p == nil || p.timer != nil {
|
|
return p
|
|
}
|
|
p.timer = prometheus.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: name,
|
|
Help: name,
|
|
}, labels)
|
|
prometheus.MustRegister(p.timer)
|
|
return p
|
|
}
|
|
|
|
// WithCounter sets counter.
|
|
func (p *Prom) WithCounter(name string, labels []string) *Prom {
|
|
if p == nil || p.counter != nil {
|
|
return p
|
|
}
|
|
p.counter = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: name,
|
|
Help: name,
|
|
}, labels)
|
|
prometheus.MustRegister(p.counter)
|
|
return p
|
|
}
|
|
|
|
// WithState sets state.
|
|
func (p *Prom) WithState(name string, labels []string) *Prom {
|
|
if p == nil || p.state != nil {
|
|
return p
|
|
}
|
|
p.state = prometheus.NewGaugeVec(
|
|
prometheus.GaugeOpts{
|
|
Name: name,
|
|
Help: name,
|
|
}, labels)
|
|
prometheus.MustRegister(p.state)
|
|
return p
|
|
}
|
|
|
|
// WithQuantile sets quantiles.
|
|
func (p *Prom) WithQuantile(name string, labels []string) *Prom {
|
|
if p == nil || p.summary != nil {
|
|
return p
|
|
}
|
|
p.summary = prometheus.NewSummaryVec(
|
|
prometheus.SummaryOpts{
|
|
Name: name,
|
|
Help: name,
|
|
}, labels)
|
|
prometheus.MustRegister(p.summary)
|
|
return p
|
|
}
|
|
|
|
// Unregister .
|
|
func (p *Prom) Unregister() {
|
|
if p.counter != nil {
|
|
prometheus.Unregister(p.counter)
|
|
}
|
|
if p.state != nil {
|
|
prometheus.Unregister(p.state)
|
|
}
|
|
if p.timer != nil {
|
|
prometheus.Unregister(p.timer)
|
|
}
|
|
if p.summary != nil {
|
|
prometheus.Unregister(p.summary)
|
|
}
|
|
}
|
|
|
|
// Timing log timing information (in milliseconds) without sampling
|
|
func (p *Prom) Timing(name string, time int64, extra ...string) {
|
|
label := append([]string{name}, extra...)
|
|
if p.timer != nil {
|
|
p.timer.WithLabelValues(label...).Observe(float64(time))
|
|
}
|
|
}
|
|
|
|
// Incr increments one stat counter without sampling
|
|
func (p *Prom) Incr(name string, extra ...string) {
|
|
label := append([]string{name}, extra...)
|
|
if p.counter != nil {
|
|
p.counter.WithLabelValues(label...).Inc()
|
|
}
|
|
if p.state != nil {
|
|
p.state.WithLabelValues(label...).Inc()
|
|
}
|
|
}
|
|
|
|
// Decr decrements one stat counter without sampling
|
|
func (p *Prom) Decr(name string, extra ...string) {
|
|
if p.state != nil {
|
|
label := append([]string{name}, extra...)
|
|
p.state.WithLabelValues(label...).Dec()
|
|
}
|
|
}
|
|
|
|
// State set state
|
|
func (p *Prom) State(name string, v int64, extra ...string) {
|
|
if p.state != nil {
|
|
label := append([]string{name}, extra...)
|
|
p.state.WithLabelValues(label...).Set(float64(v))
|
|
}
|
|
}
|
|
|
|
// Add add count v must > 0
|
|
func (p *Prom) Add(name string, v int64, extra ...string) {
|
|
label := append([]string{name}, extra...)
|
|
if p.counter != nil {
|
|
p.counter.WithLabelValues(label...).Add(float64(v))
|
|
}
|
|
if p.state != nil {
|
|
p.state.WithLabelValues(label...).Add(float64(v))
|
|
}
|
|
}
|
|
|
|
// AddCommonLog .
|
|
func AddCommonLog(target string, app string, method string, event string, version string, v int64) {
|
|
if HTTPClientCount.counter == nil || HTTPClientSum.counter == nil || HTTPClientSummary.summary == nil {
|
|
return
|
|
}
|
|
if target == "" || app == "" || method == "" || event == "" {
|
|
return
|
|
}
|
|
var ok = true
|
|
if c.Prom.Factor > 0 && c.Prom.Factor < 100 {
|
|
if rand.Intn(100) >= c.Prom.Factor {
|
|
ok = false
|
|
}
|
|
}
|
|
if version == "" {
|
|
version = _NaN
|
|
}
|
|
// default 1ms per request
|
|
i := float64(v)
|
|
if i <= 0 {
|
|
i = 1
|
|
}
|
|
labels := []string{target, app, _department, _typeCommon, method, event, version, _NaN}
|
|
// labels := append(label, _NaN)
|
|
HTTPClientCount.counter.WithLabelValues(labels...).Inc()
|
|
HTTPClientSum.counter.WithLabelValues(labels...).Add(i)
|
|
if ok {
|
|
HTTPClientSummary.summary.WithLabelValues(labels...).Observe(i)
|
|
}
|
|
}
|
|
|
|
// AddDetailedLog .
|
|
func AddDetailedLog(target string, app string, method string, event string, version string, details map[string]int64) {
|
|
if HTTPClientCount.counter == nil || HTTPClientSum.counter == nil || HTTPClientSummary.summary == nil {
|
|
return
|
|
}
|
|
if target == "" || app == "" || method == "" || event == "" || details == nil {
|
|
return
|
|
}
|
|
var ok = true
|
|
if c.Prom.Factor > 0 && c.Prom.Factor < 100 {
|
|
if rand.Intn(100) >= c.Prom.Factor {
|
|
ok = false
|
|
}
|
|
}
|
|
if version == "" {
|
|
version = _NaN
|
|
}
|
|
label := []string{target, app, _department, _typeDetailed, method, event, version}
|
|
for k, v := range details {
|
|
labels := append(label, k)
|
|
// default 1ms per request
|
|
i := float64(v)
|
|
if i <= 0 {
|
|
i = 1
|
|
}
|
|
HTTPClientCount.counter.WithLabelValues(labels...).Inc()
|
|
HTTPClientSum.counter.WithLabelValues(labels...).Add(i)
|
|
if ok {
|
|
HTTPClientSummary.summary.WithLabelValues(labels...).Observe(i)
|
|
}
|
|
}
|
|
}
|
|
|
|
// AddHTTPCode .
|
|
func AddHTTPCode(target string, app string, method string, event string, version string, code string) {
|
|
if HTTPClientStatus.counter == nil {
|
|
return
|
|
}
|
|
if target == "" || app == "" || method == "" || event == "" || code == "" {
|
|
return
|
|
}
|
|
if version == "" {
|
|
version = _NaN
|
|
}
|
|
label := []string{target, app, _department, _typeCommon, method, event, version, code}
|
|
HTTPClientStatus.counter.WithLabelValues(label...).Inc()
|
|
}
|
|
|
|
// AddCode .
|
|
func AddCode(target string, app string, method string, event string, version string, code string) {
|
|
if HTTPClientCode.counter == nil {
|
|
return
|
|
}
|
|
if target == "" || app == "" || method == "" || event == "" || code == "" {
|
|
return
|
|
}
|
|
if version == "" {
|
|
version = _NaN
|
|
}
|
|
label := []string{target, app, _department, _typeCommon, method, event, version, code}
|
|
HTTPClientCode.counter.WithLabelValues(label...).Inc()
|
|
}
|