[ADD] add metrcs: active server

This commit is contained in:
GLYASAI 2018-12-21 17:21:52 +08:00
parent 724cbb26af
commit 6655d48574
6 changed files with 214 additions and 4 deletions

View File

@ -63,6 +63,8 @@ type Config struct {
// health check
HealthPath string
HealthCheckTimeout time.Duration
EnableMetrics bool
}
// ListenPorts describe the ports required to run the gateway controller
@ -99,6 +101,7 @@ func (g *GWServer) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&g.HealthPath, "health-path", "/healthz", "absolute path to the kubeconfig file")
fs.DurationVar(&g.HealthCheckTimeout, "health-check-timeout", 10, `Time limit, in seconds, for a probe to health-check-path to succeed.`)
fs.IntVar(&g.ListenPorts.Health, "healthz-port", 10254, `Port to use for the healthz endpoint.`)
fs.BoolVar(&g.EnableMetrics, "enable-metrics", true, "Enables the collection of rbd-gateway metrics")
}
// SetLog sets log

View File

@ -21,6 +21,9 @@ package server
import (
"context"
"fmt"
"github.com/goodrain/rainbond/gateway/metric"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
"os"
"os/signal"
@ -38,12 +41,30 @@ func Run(s *option.GWServer) error {
errCh := make(chan error)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
gwc, err := controller.NewGWController(ctx, &s.Config)
reg := prometheus.NewRegistry()
reg.MustRegister(prometheus.NewGoCollector())
//reg.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{
// PidFn: func() (int, error) { return os.Getpid(), nil },
// ReportErrors: true,
//}))
mc := metric.NewDummyCollector()
var err error
if s.Config.EnableMetrics {
mc, err = metric.NewCollector(reg)
if err != nil {
logrus.Fatalf("Error creating prometheus collector: %v", err)
}
}
mc.Start()
gwc, err := controller.NewGWController(ctx, &s.Config, mc)
if err != nil {
return err
}
if gwc == nil {
return fmt.Errorf("fail to new GWController")
return fmt.Errorf("Fail to new GWController")
}
if err := gwc.Start(errCh); err != nil {
return err
@ -52,10 +73,11 @@ func Run(s *option.GWServer) error {
mux := http.NewServeMux()
registerHealthz(gwc, mux)
registerMetrics(reg, mux)
go startHTTPServer(s.ListenPorts.Health, mux)
logrus.Info("RBD app gateway start success!")
term := make(chan os.Signal)
signal.Notify(term, os.Interrupt, syscall.SIGTERM)
select {
@ -65,6 +87,7 @@ func Run(s *option.GWServer) error {
logrus.Errorf("Received a error %s, exiting gracefully...", err.Error())
}
logrus.Info("See you next time!")
return nil
}
@ -76,6 +99,14 @@ func registerHealthz(gc *controller.GWController, mux *http.ServeMux) {
)
}
func registerMetrics(reg *prometheus.Registry, mux *http.ServeMux) {
mux.Handle(
"/metrics",
promhttp.HandlerFor(reg, promhttp.HandlerOpts{}),
)
}
func startHTTPServer(port int, mux *http.ServeMux) {
server := &http.Server{
Addr: fmt.Sprintf(":%v", port),

View File

@ -22,6 +22,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/goodrain/rainbond/gateway/metric"
"strconv"
"strings"
"sync"
@ -72,6 +73,8 @@ type GWController struct {
EtcdCli *client.Client
ctx context.Context
metricCollector metric.Collector
}
// Start starts Gateway
@ -160,6 +163,7 @@ func (gwc *GWController) syncGateway(key interface{}) error {
if err != nil {
// TODO: if nginx is not ready, then stop gateway
logrus.Errorf("Fail to persist Nginx config: %v\n", err)
return nil
} else {
// refresh http pools dynamically
httpPools = append(httpPools, gwc.rrbdp...)
@ -167,6 +171,8 @@ func (gwc *GWController) syncGateway(key interface{}) error {
gwc.rhp = httpPools
}
gwc.metricCollector.SetServerNum(len(httpPools), len(tcpPools))
return nil
}
@ -200,13 +206,14 @@ func (gwc *GWController) getDelUpdPools(updPools []*v1.Pool) ([]*v1.Pool, []*v1.
}
//NewGWController new Gateway controller
func NewGWController(ctx context.Context, cfg *option.Config) (*GWController, error) {
func NewGWController(ctx context.Context, cfg *option.Config, mc metric.Collector) (*GWController, error) {
gwc := &GWController{
updateCh: channels.NewRingChannel(1024),
stopLock: &sync.Mutex{},
stopCh: make(chan struct{}),
ocfg: cfg,
ctx: ctx,
metricCollector: mc,
}
if cfg.EnableRbdEndpoints {
@ -231,6 +238,7 @@ func NewGWController(ctx context.Context, cfg *option.Config) (*GWController, er
gwc.updateCh,
cfg)
gwc.syncQueue = task.NewTaskQueue(gwc.syncGateway)
return gwc, nil
}

View File

@ -0,0 +1,72 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package collectors
import "github.com/prometheus/client_golang/prometheus"
// PrometheusNamespace default metric namespace
var PrometheusNamespace = "gateway_controller"
// Controller defines base metrics about the rbd-gateway
type Controller struct {
prometheus.Collector
activeDomain *prometheus.GaugeVec
constLabels prometheus.Labels
}
// NewController creates a new prometheus collector for the
// gateway controller operations
func NewController() *Controller {
constLabels := prometheus.Labels{
"foo": "bar",
}
cm := &Controller{
activeDomain: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: PrometheusNamespace,
Name: "active_server",
Help: "Cumulative number of active server",
ConstLabels: constLabels,
},
[]string{"type"}),
}
return cm
}
// Describe implements prometheus.Collector
func (cm Controller) Describe(ch chan<- *prometheus.Desc) {
cm.activeDomain.Describe(ch)
}
// Collect implements the prometheus.Collector interface.
func (cm Controller) Collect(ch chan<- prometheus.Metric) {
cm.activeDomain.Collect(ch)
}
// SetServerNum sets the number of active domain
func (cm *Controller) SetServerNum(httpNum, tcpNum int) {
labels := make(prometheus.Labels, 1)
labels["type"] = "http"
cm.activeDomain.With(labels).Set(float64(httpNum))
labels["type"] = "tcp"
cm.activeDomain.With(labels).Set(float64(tcpNum))
}

35
gateway/metric/dummy.go Normal file
View File

@ -0,0 +1,35 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package metric
// NewDummyCollector returns a dummy metric collector
func NewDummyCollector() Collector {
return &DummyCollector{}
}
// DummyCollector dummy implementation for mocks in tests
type DummyCollector struct{}
// Start ...
func (dc DummyCollector) Start() {}
// Stop ...
func (dc DummyCollector) Stop() {}
func (dc DummyCollector) SetServerNum(httpNum, tcpNum int) {}

61
gateway/metric/metric.go Normal file
View File

@ -0,0 +1,61 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package metric
import (
"github.com/goodrain/rainbond/gateway/metric/collectors"
"github.com/prometheus/client_golang/prometheus"
)
// Collector defines the interface for a metric collector
type Collector interface {
Start()
Stop()
SetServerNum(httpNum, tcpNum int)
}
type collector struct {
registry *prometheus.Registry
gatewayController *collectors.Controller
}
// NewCollector creates a new metric collector the for ingress controller
func NewCollector(registry *prometheus.Registry) (Collector, error) {
ic := collectors.NewController()
return Collector(&collector{
gatewayController: ic,
registry: registry,
}), nil
}
func (c *collector) Start() {
c.registry.MustRegister(c.gatewayController)
}
func (c *collector) Stop() {
c.registry.Unregister(c.gatewayController)
}
func (c *collector) SetServerNum(httpNum, tcpNum int) {
c.gatewayController.SetServerNum(httpNum, tcpNum)
}