cloud-game/pkg/monitoring/monitoring.go
sergystepanov 431d215eee
Update server HTTPS configuration (#337)
* Merge HTTP and HTTPS routes builder in coordinator

* Extract HTTP/S routes

* Rename config in coordinator

* Generalize child services

* Extract games library helper function

* Use string address instead of port for HTTP/S

* Use a dedicated port extractor function

* Add missing GA tag templating

* Rename shared server address and port params

* Introduce TLS config parameters

* Simplify HTTP/S server constructors

* Update server auto port roll

* Extract init function in worker

* Reorder return params of address type port fn

* Refactor config handler names

* Update TLS default config params

* Extract HTTP to HTTPS redirect function

* Use httpx in monitoring

* Don't log echo requests

* Remove error return from the abstract server

* Add WSS option to the worker-coordinator connection

* Change default worker config

* Make worker send its internal connection params

* Decouple gamelib from the coordinator

* Expose HTTP/S listener address

* Keep original HTTP/S addresses

* Remove no config handler in worker

* Use HTTP-HTTPS redirection

* Wrap net.Listener into a struct

* Clean http server creation fn

* Redirect to https with a generated address

* Use URL in the redirector

* Use zone address param in worker

* Make use of actual addr and port in the monitoring servers

* Use auto-justified monitoring addresses info

* Add the non-HTTPS worker to HTTPS coordinator connection warning

* Embed TLS struct

* Move connection API struct into cws package
2021-08-09 10:42:06 +03:00

111 lines
3.2 KiB
Go

package monitoring
import (
"context"
"fmt"
"log"
"math"
"net"
"net/http"
"net/http/pprof"
"strconv"
"strings"
"github.com/giongto35/cloud-game/v2/pkg/config/monitoring"
"github.com/giongto35/cloud-game/v2/pkg/network/httpx"
"github.com/giongto35/cloud-game/v2/pkg/service"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
const debugEndpoint = "/debug/pprof"
const metricsEndpoint = "/metrics"
type Monitoring struct {
service.RunnableService
conf monitoring.Config
tag string
server *httpx.Server
}
// New creates new monitoring service.
// The tag param specifies owner label for logs.
func New(conf monitoring.Config, baseAddr string, tag string) *Monitoring {
serv, err := httpx.NewServer(
net.JoinHostPort(baseAddr, strconv.Itoa(conf.Port)),
func(*httpx.Server) http.Handler {
h := http.NewServeMux()
if conf.ProfilingEnabled {
prefix := conf.URLPrefix + debugEndpoint
h.HandleFunc(prefix+"/", pprof.Index)
h.HandleFunc(prefix+"/cmdline", pprof.Cmdline)
h.HandleFunc(prefix+"/profile", pprof.Profile)
h.HandleFunc(prefix+"/symbol", pprof.Symbol)
h.HandleFunc(prefix+"/trace", pprof.Trace)
h.Handle(prefix+"/allocs", pprof.Handler("allocs"))
h.Handle(prefix+"/block", pprof.Handler("block"))
h.Handle(prefix+"/goroutine", pprof.Handler("goroutine"))
h.Handle(prefix+"/heap", pprof.Handler("heap"))
h.Handle(prefix+"/mutex", pprof.Handler("mutex"))
h.Handle(prefix+"/threadcreate", pprof.Handler("threadcreate"))
}
if conf.MetricEnabled {
h.Handle(conf.URLPrefix+metricsEndpoint, promhttp.Handler())
}
return h
},
httpx.WithPortRoll(true))
if err != nil {
log.Fatalf("couldn't start monitoring server: %v", err)
}
return &Monitoring{conf: conf, tag: tag, server: serv}
}
func (m *Monitoring) Run() {
m.printInfo()
m.server.Run()
}
func (m *Monitoring) Shutdown(ctx context.Context) error {
log.Printf("[%v] Shutting down monitoring server", m.tag)
return m.server.Shutdown(ctx)
}
func (m *Monitoring) String() string {
return fmt.Sprintf("monitoring::%s:%d", m.conf.URLPrefix, m.conf.Port)
}
func (m *Monitoring) GetMetricsPublicAddress() string {
return m.server.GetProtocol() + "://" + m.server.Addr + m.conf.URLPrefix + metricsEndpoint
}
func (m *Monitoring) GetProfilingAddress() string {
return m.server.GetProtocol() + "://" + m.server.Addr + m.conf.URLPrefix + debugEndpoint
}
func (m *Monitoring) printInfo() {
length, pad := 42, 20
var table, records strings.Builder
table.Grow(length * 4)
records.Grow(length * 2)
if m.conf.ProfilingEnabled {
addr := m.GetProfilingAddress()
length = int(math.Max(float64(length), float64(len(addr)+pad)))
records.WriteString(" Profiling " + addr + "\n")
}
if m.conf.MetricEnabled {
addr := m.GetMetricsPublicAddress()
length = int(math.Max(float64(length), float64(len(addr)+pad)))
records.WriteString(" Prometheus " + addr + "\n")
}
title := "Monitoring"
edge := strings.Repeat("-", length)
c := (length-len(title)-3)/2 + 1 + len(title) - 3
table.WriteString(fmt.Sprintf("[%s]\n", m.tag))
table.WriteString(fmt.Sprintf("%s\n---%*s%*s\n%s\n", edge, c, title, length-(c+len(title))+6+1, "---", edge))
table.WriteString(records.String())
table.WriteString(edge)
log.Printf(table.String())
}