blob: 1154f71087f7287861928b4b2eb25cda47cf6929 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.package services
package services
import (
"context"
"net/http"
"time"
logger2 "github.com/apache/dubbo-kubernetes/pkg/core/logger"
set "github.com/dubbogo/gost/container/set"
"github.com/prometheus/client_golang/api"
prom_v1 "github.com/prometheus/client_golang/api/prometheus/v1"
"github.com/apache/dubbo-kubernetes/pkg/admin/config"
"github.com/apache/dubbo-kubernetes/pkg/admin/constant"
"github.com/apache/dubbo-kubernetes/pkg/admin/model"
util2 "github.com/apache/dubbo-kubernetes/pkg/admin/util"
"github.com/apache/dubbo-kubernetes/pkg/core/monitor/prometheus"
)
var (
providerService ProviderService = &ProviderServiceImpl{}
consumerService ConsumerService = &ConsumerServiceImpl{}
providerServiceImpl = &ProviderServiceImpl{}
)
type PrometheusServiceImpl struct{}
func (p *PrometheusServiceImpl) PromDiscovery(w http.ResponseWriter) ([]model.Target, error) {
w.Header().Set("Content-Type", "application/json")
// Reduce the call chain and improve performance.
// Find all provider addresses
proAddr, err := providerServiceImpl.findAddresses()
if err != nil {
logger2.Sugar().Errorf("Error provider findAddresses: %v\n", err)
return nil, err
}
addresses := set.NewSet()
items := proAddr.Values()
for i := 0; i < len(items); i++ {
addresses.Add(util2.GetDiscoveryPath(items[i].(string)))
}
targets := make([]string, 0, addresses.Size())
items = addresses.Values()
for _, v := range items {
targets = append(targets, v.(string))
}
target := []model.Target{
{
Targets: targets,
Labels: map[string]string{},
},
}
return target, err
}
func (p *PrometheusServiceImpl) ClusterMetrics() (model.ClusterMetricsRes, error) {
res := model.ClusterMetricsRes{
Data: make(map[string]int),
}
// total application number
applications, err := providerService.FindApplications()
appNum := 0
if err != nil {
logger2.Sugar().Errorf("Error find applications: %v\n", err)
} else {
appNum = applications.Size()
}
res.Data["application"] = appNum
// total service number
services, err := providerService.FindServices()
svc := 0
if err != nil {
logger2.Sugar().Errorf("Error find services: %v\n", err)
} else {
svc = services.Size()
}
res.Data["services"] = svc
providers, err := providerService.FindService(constant.IP, constant.AnyValue)
pro := 0
if err != nil {
logger2.Sugar().Errorf("Error find providers: %v\n", err)
} else {
pro = len(providers)
}
res.Data["providers"] = pro
consumers, err := consumerService.FindAll()
con := 0
if err != nil {
logger2.Sugar().Errorf("Error find consumers: %v\n", err)
} else {
con = len(consumers)
}
res.Data["consumers"] = con
res.Data["all"] = con
return res, nil
}
func (p *PrometheusServiceImpl) FlowMetrics() (model.FlowMetricsRes, error) {
res := model.FlowMetricsRes{
Data: make(map[string]float64),
}
client, err := api.NewClient(api.Config{
Address: config.PrometheusAddress,
})
if err != nil {
logger2.Sugar().Errorf("Error creating clientgen: %v\n", err)
return res, err
}
v1api := prom_v1.NewAPI(client)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// qps
vector1 := prometheus.FetchQuery(ctx, v1api, constant.MetricsQps, nil)
err = vector1.Err
qps := float64(0)
if err != nil {
logger2.Sugar().Errorf("Error query qps: %v\n", err)
} else {
if vector1.Vector.Len() != 0 {
qps = float64(vector1.Vector[0].Value)
}
res.Data["qps"] = qps
}
// total count
vector3 := prometheus.FetchQuery(ctx, v1api, constant.MetricsHttpRequestTotalCount, nil)
total := float64(0)
if vector3.Err != nil {
logger2.Sugar().Errorf("Error query total count: %v\n", err)
} else {
if vector3.Vector.Len() != 0 {
total = float64(vector3.Vector[0].Value)
}
res.Data["total"] = total
}
// success count
vector2 := prometheus.FetchQuery(ctx, v1api, constant.MetricsHttpRequestSuccessCount, nil)
success := float64(0)
if vector2.Err != nil {
logger2.Sugar().Errorf("Error query success count: %v\n", err)
} else {
if vector2.Vector.Len() != 0 {
success = float64(vector2.Vector[0].Value)
}
res.Data["total"] = success
}
// timeout count
vector4 := prometheus.FetchQuery(ctx, v1api, constant.MetricsHttpRequestOutOfTimeCount, nil)
timeout := float64(0)
if vector4.Err != nil {
logger2.Sugar().Errorf("Error query timeout count: %v\n", err)
} else {
if vector4.Vector.Len() != 0 {
timeout = float64(vector4.Vector[0].Value)
}
res.Data["timeout"] = timeout
}
// address not found count
vector5 := prometheus.FetchQuery(ctx, v1api, constant.MetricsHttpRequestAddressNotFount, nil)
addrNotFound := float64(0)
if vector5.Err != nil {
logger2.Sugar().Errorf("Error query address not found count: %v\n", err)
} else {
if vector5.Vector.Len() != 0 {
addrNotFound = float64(vector5.Vector[0].Value)
}
res.Data["addressNotFound"] = addrNotFound
}
// other exceptions count
vector6 := prometheus.FetchQuery(ctx, v1api, constant.MetricsHttpRequestOtherException, nil)
others := float64(0)
if vector6.Err != nil {
logger2.Sugar().Errorf("Error query othere exceptions count: %v\n", err)
} else {
if vector6.Vector.Len() != 0 {
others = float64(vector6.Vector[0].Value)
}
res.Data["others"] = others
}
return res, nil
}
func (p *PrometheusServiceImpl) Metadata() (model.Metadata, error) {
metadata := model.Metadata{}
// versions
versions, err := providerService.FindVersions()
if err != nil {
logger2.Error("Failed to parse versions!")
}
metadata.Versions = versions.Values()
// protocols
protocols, err := providerService.FindProtocols()
if err != nil {
logger2.Error("Failed to parse protocols!")
}
metadata.Protocols = protocols.Values()
// centers
metadata.Registry = config.RegistryCenter.GetURL().Location
metadata.MetadataCenter = config.RegistryCenter.GetURL().Location
metadata.ConfigCenter = config.RegistryCenter.GetURL().Location
metadata.Grafana = config.GrafanaAddress
metadata.Prometheus = config.PrometheusAddress
// rules
rules, err := GetRules("", "*")
if err != nil {
return model.Metadata{}, err
}
keys := make([]string, 0, len(rules))
for k := range rules {
keys = append(keys, k)
}
metadata.Rules = keys
return metadata, nil
}