37 Star 396 Fork 71

GVPrancher/rancher

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
metric_action.go 6.00 KB
一键复制 编辑 原始数据 按行查看 历史
package monitor
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/rancher/norman/parse"
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
"github.com/rancher/rancher/pkg/clustermanager"
monitorutil "github.com/rancher/rancher/pkg/monitoring"
"github.com/rancher/rancher/pkg/ref"
"github.com/rancher/types/apis/management.cattle.io/v3"
"github.com/rancher/types/config/dialer"
)
func NewMetricHandler(dialerFactory dialer.Factory, clustermanager *clustermanager.Manager) *MetricHandler {
return &MetricHandler{
dialerFactory: dialerFactory,
clustermanager: clustermanager,
}
}
type MetricHandler struct {
dialerFactory dialer.Factory
clustermanager *clustermanager.Manager
}
func (h *MetricHandler) Action(actionName string, action *types.Action, apiContext *types.APIContext) error {
switch actionName {
case querycluster, queryproject:
var clusterName, projectName, appName, saNamespace string
var comm v3.CommonQueryMetricInput
var err error
var svcNamespace, svcName, svcPort string
if actionName == querycluster {
var queryMetricInput v3.QueryClusterMetricInput
actionInput, err := parse.ReadBody(apiContext.Request)
if err != nil {
return err
}
if err = convert.ToObj(actionInput, &queryMetricInput); err != nil {
return err
}
clusterName = queryMetricInput.ClusterName
if clusterName == "" {
return fmt.Errorf("clusterName is empty")
}
comm = queryMetricInput.CommonQueryMetricInput
appName, saNamespace = monitorutil.ClusterMonitoringInfo()
svcName, svcNamespace, svcPort = monitorutil.ClusterPrometheusEndpoint()
} else {
var queryMetricInput v3.QueryProjectMetricInput
actionInput, err := parse.ReadBody(apiContext.Request)
if err != nil {
return err
}
if err = convert.ToObj(actionInput, &queryMetricInput); err != nil {
return err
}
projectID := queryMetricInput.ProjectName
clusterName, projectName = ref.Parse(projectID)
if clusterName == "" {
return fmt.Errorf("clusterName is empty")
}
comm = queryMetricInput.CommonQueryMetricInput
appName, saNamespace = monitorutil.ProjectMonitoringInfo(projectName)
svcName, svcNamespace, svcPort = monitorutil.ProjectPrometheusEndpoint(projectName)
}
start, end, step, err := parseTimeParams(comm.From, comm.To, comm.Interval)
if err != nil {
return err
}
userContext, err := h.clustermanager.UserContext(clusterName)
if err != nil {
return fmt.Errorf("get usercontext failed, %v", err)
}
token, err := getAuthToken(userContext, appName, saNamespace)
if err != nil {
return err
}
reqContext, cancel := context.WithTimeout(context.Background(), prometheusReqTimeout)
defer cancel()
prometheusQuery, err := NewPrometheusQuery(reqContext, clusterName, token, svcNamespace, svcName, svcPort, h.dialerFactory)
if err != nil {
return err
}
query := InitPromQuery("", start, end, step, comm.Expr, "", false)
seriesSlice, err := prometheusQuery.QueryRange(query)
if err != nil {
return err
}
if seriesSlice == nil {
apiContext.WriteResponse(http.StatusNoContent, nil)
return nil
}
data := map[string]interface{}{
"type": "queryMetricOutput",
"series": seriesSlice,
}
res, err := json.Marshal(data)
if err != nil {
return fmt.Errorf("marshal query stats result failed, %v", err)
}
apiContext.Response.Write(res)
case listclustermetricname:
var input v3.ClusterMetricNamesInput
actionInput, err := parse.ReadBody(apiContext.Request)
if err != nil {
return err
}
if err = convert.ToObj(actionInput, &input); err != nil {
return err
}
clusterName := input.ClusterName
if clusterName == "" {
return fmt.Errorf("clusterName is empty")
}
userContext, err := h.clustermanager.UserContext(clusterName)
if err != nil {
return fmt.Errorf("get usercontext failed, %v", err)
}
appName, saNamespace := monitorutil.ClusterMonitoringInfo()
token, err := getAuthToken(userContext, appName, saNamespace)
if err != nil {
return err
}
reqContext, cancel := context.WithTimeout(context.Background(), prometheusReqTimeout)
defer cancel()
svcName, svcNamespace, svcPort := monitorutil.ClusterPrometheusEndpoint()
prometheusQuery, err := NewPrometheusQuery(reqContext, clusterName, token, svcNamespace, svcName, svcPort, h.dialerFactory)
if err != nil {
return err
}
names, err := prometheusQuery.GetLabelValues("__name__")
if err != nil {
return err
}
data := map[string]interface{}{
"type": "metricNamesOutput",
"names": names,
}
apiContext.WriteResponse(http.StatusOK, data)
case listprojectmetricname:
// project metric names need to merge cluster level and project level prometheus labels name list
var input v3.ProjectMetricNamesInput
actionInput, err := parse.ReadBody(apiContext.Request)
if err != nil {
return err
}
if err = convert.ToObj(actionInput, &input); err != nil {
return err
}
projectID := input.ProjectName
clusterName, projectName := ref.Parse(projectID)
if clusterName == "" {
return fmt.Errorf("clusterName is empty")
}
userContext, err := h.clustermanager.UserContext(clusterName)
if err != nil {
return fmt.Errorf("get usercontext failed, %v", err)
}
appName, saNamespace := monitorutil.ProjectMonitoringInfo(projectName)
token, err := getAuthToken(userContext, appName, saNamespace)
if err != nil {
return err
}
reqContext, cancel := context.WithTimeout(context.Background(), prometheusReqTimeout)
defer cancel()
svcName, svcNamespace, svcPort := monitorutil.ProjectPrometheusEndpoint(projectName)
prometheusQuery, err := NewPrometheusQuery(reqContext, clusterName, token, svcNamespace, svcName, svcPort, h.dialerFactory)
if err != nil {
return err
}
names, err := prometheusQuery.GetLabelValues("__name__")
if err != nil {
return fmt.Errorf("get project metric list failed, %v", err)
}
data := map[string]interface{}{
"type": "metricNamesOutput",
"names": names,
}
apiContext.WriteResponse(http.StatusOK, data)
}
return nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/rancher/rancher.git
git@gitee.com:rancher/rancher.git
rancher
rancher
rancher
v2.2.3-rc2

搜索帮助

344bd9b3 5694891 D2dac590 5694891