Redo code cleanup (#429)
* Code cleanup of routes config loader and API server (#424) (cherry picked from commit1ee3eb4de3) * Refactored server setup and run out of main (#425) (cherry picked from commit05c57c3b85) * Code cleanup in and around connector (#427) (cherry picked from commitb3e88db48c) * Update away from deprecated k8s NewInformer * Tidy up couple of k8s docs examples
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-kit/kit/metrics"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
kitlogrus "github.com/go-kit/kit/log/logrus"
|
||||
discardMetrics "github.com/go-kit/kit/metrics/discard"
|
||||
expvarMetrics "github.com/go-kit/kit/metrics/expvar"
|
||||
kitinflux "github.com/go-kit/kit/metrics/influx"
|
||||
prometheusMetrics "github.com/go-kit/kit/metrics/prometheus"
|
||||
influx "github.com/influxdata/influxdb1-client/v2"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type MetricsBuilder interface {
|
||||
BuildConnectorMetrics() *ConnectorMetrics
|
||||
Start(ctx context.Context) error
|
||||
}
|
||||
|
||||
const (
|
||||
MetricsBackendExpvar = "expvar"
|
||||
MetricsBackendPrometheus = "prometheus"
|
||||
MetricsBackendInfluxDB = "influxdb"
|
||||
MetricsBackendDiscard = "discard"
|
||||
)
|
||||
|
||||
type MetricsBackendConfig struct {
|
||||
Influxdb struct {
|
||||
Interval time.Duration `default:"1m"`
|
||||
Tags map[string]string `usage:"any extra tags to be included with all reported metrics"`
|
||||
Addr string
|
||||
Username string
|
||||
Password string
|
||||
Database string
|
||||
RetentionPolicy string
|
||||
}
|
||||
}
|
||||
|
||||
// NewMetricsBuilder creates a new MetricsBuilder based on the specified backend.
|
||||
// If the backend is not recognized, a discard builder is returned.
|
||||
// config can be nil if the backend is not influxdb.
|
||||
func NewMetricsBuilder(backend string, config *MetricsBackendConfig) MetricsBuilder {
|
||||
switch strings.ToLower(backend) {
|
||||
case MetricsBackendExpvar:
|
||||
return &expvarMetricsBuilder{}
|
||||
case MetricsBackendPrometheus:
|
||||
return &prometheusMetricsBuilder{}
|
||||
case MetricsBackendInfluxDB:
|
||||
return &influxMetricsBuilder{config: config}
|
||||
case MetricsBackendDiscard:
|
||||
return &discardMetricsBuilder{}
|
||||
default:
|
||||
return &discardMetricsBuilder{}
|
||||
}
|
||||
}
|
||||
|
||||
type expvarMetricsBuilder struct {
|
||||
}
|
||||
|
||||
func (b expvarMetricsBuilder) Start(ctx context.Context) error {
|
||||
// nothing needed
|
||||
return nil
|
||||
}
|
||||
|
||||
type ConnectorMetrics struct {
|
||||
Errors metrics.Counter
|
||||
BytesTransmitted metrics.Counter
|
||||
ConnectionsFrontend metrics.Counter
|
||||
ConnectionsBackend metrics.Counter
|
||||
ActiveConnections metrics.Gauge
|
||||
ServerActivePlayer metrics.Gauge
|
||||
ServerLogins metrics.Counter
|
||||
ServerActiveConnections metrics.Gauge
|
||||
}
|
||||
|
||||
func (b expvarMetricsBuilder) BuildConnectorMetrics() *ConnectorMetrics {
|
||||
c := expvarMetrics.NewCounter("connections")
|
||||
return &ConnectorMetrics{
|
||||
Errors: expvarMetrics.NewCounter("errors").With("subsystem", "connector"),
|
||||
BytesTransmitted: expvarMetrics.NewCounter("bytes"),
|
||||
ConnectionsFrontend: c,
|
||||
ConnectionsBackend: c,
|
||||
ActiveConnections: expvarMetrics.NewGauge("active_connections"),
|
||||
ServerActivePlayer: expvarMetrics.NewGauge("server_active_player"),
|
||||
ServerLogins: expvarMetrics.NewCounter("server_logins"),
|
||||
ServerActiveConnections: expvarMetrics.NewGauge("server_active_connections"),
|
||||
}
|
||||
}
|
||||
|
||||
type discardMetricsBuilder struct {
|
||||
}
|
||||
|
||||
func (b discardMetricsBuilder) Start(ctx context.Context) error {
|
||||
// nothing needed
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b discardMetricsBuilder) BuildConnectorMetrics() *ConnectorMetrics {
|
||||
return &ConnectorMetrics{
|
||||
Errors: discardMetrics.NewCounter(),
|
||||
BytesTransmitted: discardMetrics.NewCounter(),
|
||||
ConnectionsFrontend: discardMetrics.NewCounter(),
|
||||
ConnectionsBackend: discardMetrics.NewCounter(),
|
||||
ActiveConnections: discardMetrics.NewGauge(),
|
||||
ServerActivePlayer: discardMetrics.NewGauge(),
|
||||
ServerLogins: discardMetrics.NewCounter(),
|
||||
ServerActiveConnections: discardMetrics.NewGauge(),
|
||||
}
|
||||
}
|
||||
|
||||
type influxMetricsBuilder struct {
|
||||
config *MetricsBackendConfig
|
||||
metrics *kitinflux.Influx
|
||||
}
|
||||
|
||||
func (b *influxMetricsBuilder) Start(ctx context.Context) error {
|
||||
influxConfig := &b.config.Influxdb
|
||||
if influxConfig.Addr == "" {
|
||||
return errors.New("influx addr is required")
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(influxConfig.Interval)
|
||||
client, err := influx.NewHTTPClient(influx.HTTPConfig{
|
||||
Addr: influxConfig.Addr,
|
||||
Username: influxConfig.Username,
|
||||
Password: influxConfig.Password,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create influx http client: %w", err)
|
||||
}
|
||||
|
||||
go b.metrics.WriteLoop(ctx, ticker.C, client)
|
||||
|
||||
logrus.WithField("addr", influxConfig.Addr).
|
||||
Debug("reporting metrics to influxdb")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *influxMetricsBuilder) BuildConnectorMetrics() *ConnectorMetrics {
|
||||
influxConfig := &b.config.Influxdb
|
||||
|
||||
metrics := kitinflux.New(influxConfig.Tags, influx.BatchPointsConfig{
|
||||
Database: influxConfig.Database,
|
||||
RetentionPolicy: influxConfig.RetentionPolicy,
|
||||
}, kitlogrus.NewLogger(logrus.StandardLogger()))
|
||||
|
||||
b.metrics = metrics
|
||||
|
||||
c := metrics.NewCounter("mc_router_connections")
|
||||
return &ConnectorMetrics{
|
||||
Errors: metrics.NewCounter("mc_router_errors"),
|
||||
BytesTransmitted: metrics.NewCounter("mc_router_transmitted_bytes"),
|
||||
ConnectionsFrontend: c.With("side", "frontend"),
|
||||
ConnectionsBackend: c.With("side", "backend"),
|
||||
ActiveConnections: metrics.NewGauge("mc_router_connections_active"),
|
||||
ServerActivePlayer: metrics.NewGauge("mc_router_server_player_active"),
|
||||
ServerLogins: metrics.NewCounter("mc_router_server_logins"),
|
||||
ServerActiveConnections: metrics.NewGauge("mc_router_server_active_connections"),
|
||||
}
|
||||
}
|
||||
|
||||
type prometheusMetricsBuilder struct {
|
||||
}
|
||||
|
||||
var pcv *prometheusMetrics.Counter
|
||||
|
||||
func (b prometheusMetricsBuilder) Start(ctx context.Context) error {
|
||||
|
||||
// nothing needed
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b prometheusMetricsBuilder) BuildConnectorMetrics() *ConnectorMetrics {
|
||||
pcv = prometheusMetrics.NewCounter(promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: "mc_router",
|
||||
Name: "errors",
|
||||
Help: "The total number of errors",
|
||||
}, []string{"type"}))
|
||||
return &ConnectorMetrics{
|
||||
Errors: pcv,
|
||||
BytesTransmitted: prometheusMetrics.NewCounter(promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: "mc_router",
|
||||
Name: "bytes",
|
||||
Help: "The total number of bytes transmitted",
|
||||
}, nil)),
|
||||
ConnectionsFrontend: prometheusMetrics.NewCounter(promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: "mc_router",
|
||||
Subsystem: "frontend",
|
||||
Name: "connections",
|
||||
Help: "The total number of connections",
|
||||
ConstLabels: prometheus.Labels{"side": "frontend"},
|
||||
}, nil)),
|
||||
ConnectionsBackend: prometheusMetrics.NewCounter(promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: "mc_router",
|
||||
Subsystem: "backend",
|
||||
Name: "connections",
|
||||
Help: "The total number of backend connections",
|
||||
ConstLabels: prometheus.Labels{"side": "backend"},
|
||||
}, []string{"host"})),
|
||||
ActiveConnections: prometheusMetrics.NewGauge(promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: "mc_router",
|
||||
Name: "active_connections",
|
||||
Help: "The number of active connections",
|
||||
}, nil)),
|
||||
ServerActivePlayer: prometheusMetrics.NewGauge(promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: "mc_router",
|
||||
Name: "server_active_player",
|
||||
Help: "Player is active on server",
|
||||
}, []string{"player_name", "player_uuid", "server_address"})),
|
||||
ServerLogins: prometheusMetrics.NewCounter(promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: "mc_router",
|
||||
Name: "server_logins",
|
||||
Help: "The total number of player logins",
|
||||
}, []string{"player_name", "player_uuid", "server_address"})),
|
||||
ServerActiveConnections: prometheusMetrics.NewGauge(promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: "mc_router",
|
||||
Name: "server_active_connections",
|
||||
Help: "The number of active connections per server",
|
||||
}, []string{"server_address"})),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user