2018-03-12 08:48:16 +00:00
|
|
|
package biz
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2018-03-22 08:13:54 +00:00
|
|
|
"os"
|
2018-03-12 08:48:16 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/cuigh/auxo/ext/times"
|
|
|
|
"github.com/cuigh/auxo/util/lazy"
|
|
|
|
"github.com/cuigh/swirl/model"
|
|
|
|
pclient "github.com/prometheus/client_golang/api"
|
|
|
|
papi "github.com/prometheus/client_golang/api/prometheus/v1"
|
|
|
|
pmodel "github.com/prometheus/common/model"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Metric return a metric biz instance.
|
|
|
|
var Metric = &metricBiz{
|
|
|
|
api: lazy.Value{
|
|
|
|
New: func() (interface{}, error) {
|
|
|
|
setting, err := Setting.Get()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
client, err := pclient.NewClient(pclient.Config{Address: setting.Metrics.Prometheus})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return papi.NewAPI(client), nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
type metricBiz struct {
|
|
|
|
api lazy.Value
|
|
|
|
}
|
|
|
|
|
2018-03-26 12:44:42 +00:00
|
|
|
// func (b *metricBiz) GetServiceCharts(service string, categories []string) (charts []model.ChartInfo) {
|
|
|
|
// charts = append(charts, model.NewChartInfo("cpu", "CPU", "${name}", `rate(container_cpu_user_seconds_total{container_label_com_docker_swarm_service_name="%s"}[5m]) * 100`))
|
|
|
|
// charts = append(charts, model.NewChartInfo("memory", "Memory", "${name}", `container_memory_usage_bytes{container_label_com_docker_swarm_service_name="%s"}`))
|
|
|
|
// charts = append(charts, model.NewChartInfo("network_in", "Network Receive", "${name}", `sum(irate(container_network_receive_bytes_total{container_label_com_docker_swarm_service_name="%s"}[5m])) by(name)`))
|
|
|
|
// charts = append(charts, model.NewChartInfo("network_out", "Network Send", "${name}", `sum(irate(container_network_transmit_bytes_total{container_label_com_docker_swarm_service_name="%s"}[5m])) by(name)`))
|
|
|
|
// for _, c := range categories {
|
|
|
|
// if c == "java" {
|
|
|
|
// charts = append(charts, model.NewChartInfo("threads", "Threads", "${instance}", `jvm_threads_current{service="%s"}`))
|
|
|
|
// charts = append(charts, model.NewChartInfo("gc_duration", "GC Duration", "${instance}", `rate(jvm_gc_collection_seconds_sum{service="%s"}[1m])`))
|
|
|
|
// } else if c == "go" {
|
|
|
|
// charts = append(charts, model.NewChartInfo("threads", "Threads", "${instance}", `go_threads{service="%s"}`))
|
|
|
|
// charts = append(charts, model.NewChartInfo("goroutines", "Goroutines", "${instance}", `go_goroutines{service="%s"}`))
|
|
|
|
// charts = append(charts, model.NewChartInfo("gc_duration", "GC Duration", "${instance}", `sum(go_gc_duration_seconds{service="%s"}) by (instance)`))
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// for i, c := range charts {
|
|
|
|
// charts[i].Query = fmt.Sprintf(c.Query, service)
|
|
|
|
// }
|
|
|
|
// return
|
|
|
|
// }
|
2018-03-12 08:48:16 +00:00
|
|
|
|
2018-04-02 08:19:12 +00:00
|
|
|
func (b *metricBiz) GetMatrix(query, legend string, start, end time.Time) (data *model.ChartMatrixData, err error) {
|
2018-03-12 08:48:16 +00:00
|
|
|
api, err := b.getAPI()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
period := end.Sub(start)
|
2021-02-26 05:19:40 +00:00
|
|
|
value, _, err := api.QueryRange(context.Background(), query, papi.Range{
|
2018-03-12 08:48:16 +00:00
|
|
|
Start: start,
|
|
|
|
End: end,
|
|
|
|
Step: b.calcStep(period),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-04-02 08:19:12 +00:00
|
|
|
data = &model.ChartMatrixData{}
|
2018-03-12 08:48:16 +00:00
|
|
|
matrix := value.(pmodel.Matrix)
|
|
|
|
for _, stream := range matrix {
|
2018-04-02 08:19:12 +00:00
|
|
|
data.Legend = append(data.Legend, b.formatLabel(legend, stream.Metric))
|
|
|
|
line := model.ChartLine{Name: b.formatLabel(legend, stream.Metric)}
|
2018-03-12 08:48:16 +00:00
|
|
|
for _, v := range stream.Values {
|
|
|
|
p := model.ChartPoint{
|
|
|
|
X: int64(v.Timestamp),
|
|
|
|
Y: float64(v.Value),
|
|
|
|
}
|
|
|
|
line.Data = append(line.Data, p)
|
|
|
|
}
|
2018-04-02 08:19:12 +00:00
|
|
|
data.Series = append(data.Series, line)
|
2018-03-12 08:48:16 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-03-13 10:48:16 +00:00
|
|
|
func (b *metricBiz) GetScalar(query string, t time.Time) (v float64, err error) {
|
|
|
|
api, err := b.getAPI()
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
2021-02-26 05:19:40 +00:00
|
|
|
value, _, err := api.Query(context.Background(), query, t)
|
2018-03-13 10:48:16 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
2018-04-02 08:19:12 +00:00
|
|
|
//scalar := value.(*pmodel.Scalar)
|
|
|
|
vector := value.(pmodel.Vector)
|
|
|
|
if len(vector) > 0 {
|
|
|
|
sample := vector[0]
|
|
|
|
return float64(sample.Value), nil
|
|
|
|
}
|
|
|
|
return 0, nil
|
2018-03-13 10:48:16 +00:00
|
|
|
}
|
|
|
|
|
2018-04-02 08:19:12 +00:00
|
|
|
func (b *metricBiz) GetVector(query, label string, t time.Time) (data *model.ChartVectorData, err error) {
|
2018-03-22 08:13:54 +00:00
|
|
|
var api papi.API
|
|
|
|
api, err = b.getAPI()
|
2018-03-13 10:48:16 +00:00
|
|
|
if err != nil {
|
2018-03-22 08:13:54 +00:00
|
|
|
return
|
2018-03-13 10:48:16 +00:00
|
|
|
}
|
|
|
|
|
2018-03-22 08:13:54 +00:00
|
|
|
var value pmodel.Value
|
2021-02-26 05:19:40 +00:00
|
|
|
value, _, err = api.Query(context.Background(), query, t)
|
2018-03-13 10:48:16 +00:00
|
|
|
if err != nil {
|
2018-03-22 08:13:54 +00:00
|
|
|
return
|
2018-03-13 10:48:16 +00:00
|
|
|
}
|
|
|
|
|
2018-04-02 08:19:12 +00:00
|
|
|
data = &model.ChartVectorData{}
|
2018-03-13 10:48:16 +00:00
|
|
|
vector := value.(pmodel.Vector)
|
|
|
|
for _, sample := range vector {
|
2018-04-02 08:19:12 +00:00
|
|
|
cv := model.ChartValue{
|
|
|
|
Name: b.formatLabel(label, sample.Metric),
|
|
|
|
Value: float64(sample.Value),
|
2018-03-22 08:13:54 +00:00
|
|
|
}
|
2018-04-02 08:19:12 +00:00
|
|
|
data.Data = append(data.Data, cv)
|
|
|
|
data.Legend = append(data.Legend, cv.Name)
|
2018-03-13 10:48:16 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-03-12 08:48:16 +00:00
|
|
|
func (b *metricBiz) calcStep(period time.Duration) (step time.Duration) {
|
|
|
|
if period >= times.Day {
|
2018-04-03 03:57:59 +00:00
|
|
|
step = 8 * time.Minute
|
2018-03-12 08:48:16 +00:00
|
|
|
} else if period >= 12*time.Hour {
|
2018-04-03 03:57:59 +00:00
|
|
|
step = 4 * time.Minute
|
2018-03-12 08:48:16 +00:00
|
|
|
} else if period >= 6*time.Hour {
|
2018-04-03 03:57:59 +00:00
|
|
|
step = 2 * time.Minute
|
2018-03-12 08:48:16 +00:00
|
|
|
} else if period >= 3*time.Hour {
|
|
|
|
step = time.Minute
|
2018-04-03 03:57:59 +00:00
|
|
|
} else {
|
|
|
|
step = 30 * time.Second
|
2018-03-12 08:48:16 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *metricBiz) getAPI() (api papi.API, err error) {
|
|
|
|
v, err := b.api.Get()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return v.(papi.API), nil
|
|
|
|
}
|
2018-03-22 08:13:54 +00:00
|
|
|
|
|
|
|
func (b *metricBiz) formatLabel(label string, metric pmodel.Metric) string {
|
|
|
|
return os.Expand(label, func(key string) string {
|
|
|
|
if s := string(metric[pmodel.LabelName(key)]); s != "" {
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
return "[" + key + "]"
|
|
|
|
})
|
|
|
|
}
|