nightingale/http/router_ts_data.go

177 lines
4.2 KiB
Go
Raw Normal View History

package http
import (
"errors"
"fmt"
"github.com/didi/nightingale/v5/backend"
"github.com/didi/nightingale/v5/cache"
"github.com/didi/nightingale/v5/trans"
"github.com/didi/nightingale/v5/vos"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
agentpayload "github.com/n9e/agent-payload/gogen"
"github.com/toolkits/pkg/logger"
)
// 错误消息也是返回了200是和客户端的约定客户端如果发现code!=200就会重试
func PushSeries(c *gin.Context) {
req := agentpayload.N9EMetricsPayload{}
if c.ContentType() == "application/x-protobuf" {
err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
if err != nil {
message := fmt.Sprintf("error: decode protobuf body occur error: %v", err)
logger.Warning(message)
c.String(200, message)
return
}
count := len(req.Samples)
if count == 0 {
c.String(200, "error: samples is empty")
return
}
metricPoints := make([]*vos.MetricPoint, 0, count)
for i := 0; i < count; i++ {
logger.Debugf("recv %v", req.Samples[i])
metricPoints = append(metricPoints, convertAgentdPoint(req.Samples[i]))
}
if err = trans.Push(metricPoints); err != nil {
logger.Debugf("error: trans.push %+v err:%v", req.Samples, err)
c.String(200, "error: "+err.Error())
} else {
c.String(200, "success: received %d points", len(metricPoints))
}
} else {
logger.Debugf("error: trans.push %+v Content-Type(%s) not equals application/x-protobuf", req.Samples)
c.String(200, "error: Content-Type(%s) not equals application/x-protobuf")
}
}
func convertAgentdPoint(obj *agentpayload.N9EMetricsPayload_Sample) *vos.MetricPoint {
return &vos.MetricPoint{
Metric: obj.Metric,
Ident: obj.Ident,
Alias: obj.Alias,
TagsMap: obj.Tags,
Time: obj.Time,
ValueUntyped: obj.Value,
}
}
func PushData(c *gin.Context) {
var points []*vos.MetricPoint
err := c.ShouldBindJSON(&points)
if err != nil {
message := fmt.Sprintf("error: decode json body occur error: %v", err)
logger.Warning(message)
c.String(200, message)
return
}
if err = trans.Push(points); err != nil {
c.String(200, "error: "+err.Error())
} else {
c.String(200, "success")
}
}
func GetTagKeys(c *gin.Context) {
recv := vos.CommonTagQueryParam{}
dangerous(c.ShouldBindJSON(&recv))
dataSource, err := backend.GetDataSourceFor("")
if err != nil {
logger.Warningf("could not find datasource")
renderMessage(c, err)
return
}
resp := dataSource.QueryTagKeys(recv)
renderData(c, resp, nil)
}
func GetTagValues(c *gin.Context) {
recv := vos.CommonTagQueryParam{}
dangerous(c.ShouldBindJSON(&recv))
dataSource, err := backend.GetDataSourceFor("")
if err != nil {
logger.Warningf("could not find datasource")
renderMessage(c, err)
return
}
if recv.TagKey == "" {
renderMessage(c, errors.New("missing tagkey"))
return
}
resp := dataSource.QueryTagValues(recv)
renderData(c, resp, nil)
}
func GetMetrics(c *gin.Context) {
recv := vos.MetricQueryParam{}
dangerous(c.ShouldBindJSON(&recv))
dataSource, err := backend.GetDataSourceFor("")
if err != nil {
logger.Warningf("could not find datasource")
renderMessage(c, err)
return
}
resp := dataSource.QueryMetrics(recv)
logger.Debugf("[GetMetrics][recv:%+v][resp:%+v]", recv, resp)
res := &vos.MetricDesQueryResp{
Metrics: make([]vos.MetricsWithDescription, 0),
}
for _, metric := range resp.Metrics {
t := vos.MetricsWithDescription{
Name: metric,
}
description, exists := cache.MetricDescMapper.Get(metric)
if exists {
t.Description = description.(string)
}
res.Metrics = append(res.Metrics, t)
}
renderData(c, res, nil)
}
func GetTagPairs(c *gin.Context) {
recv := vos.CommonTagQueryParam{}
dangerous(c.ShouldBindJSON(&recv))
dataSource, err := backend.GetDataSourceFor("")
if err != nil {
logger.Warningf("could not find datasource")
renderMessage(c, err)
return
}
resp := dataSource.QueryTagPairs(recv)
renderData(c, resp, nil)
}
func GetData(c *gin.Context) {
dataSource, err := backend.GetDataSourceFor("")
if err != nil {
logger.Warningf("could not find datasource")
renderMessage(c, err)
return
}
var input vos.DataQueryParam
dangerous(c.ShouldBindJSON(&input))
resp := dataSource.QueryData(input)
renderData(c, resp, nil)
}