mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
Capitalize the first letter of all log messages throughout the codebase to improve readability and consistency in logging output. Key improvements: - All log messages now start with capital letters - Consistent formatting across all logging statements - Improved readability for debugging and monitoring - Enhanced user experience with better formatted messages Files updated: - CLI commands and service management - Internal client information discovery - Network operations and configuration - DNS resolver and proxy operations - Platform-specific implementations This completes the final phase of the logging improvement project, ensuring all log messages follow consistent capitalization standards for better readability and professional appearance.
158 lines
4.4 KiB
Go
158 lines
4.4 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net"
|
|
"net/http"
|
|
"runtime"
|
|
"time"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/collectors"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"github.com/prometheus/prom2json"
|
|
)
|
|
|
|
// metricsServer represents a server to expose Prometheus metrics via HTTP.
|
|
// This provides monitoring and observability for the DNS proxy service
|
|
type metricsServer struct {
|
|
server *http.Server
|
|
mux *http.ServeMux
|
|
reg *prometheus.Registry
|
|
addr string
|
|
started bool
|
|
}
|
|
|
|
// newMetricsServer returns new metrics server.
|
|
// This initializes the HTTP server for exposing Prometheus metrics
|
|
func newMetricsServer(addr string, reg *prometheus.Registry) (*metricsServer, error) {
|
|
mux := http.NewServeMux()
|
|
ms := &metricsServer{
|
|
server: &http.Server{Handler: mux},
|
|
mux: mux,
|
|
reg: reg,
|
|
}
|
|
ms.addr = addr
|
|
ms.registerMetricsServerHandler()
|
|
return ms, nil
|
|
}
|
|
|
|
// register adds handlers for given pattern.
|
|
// This provides a clean interface for adding HTTP endpoints to the metrics server
|
|
func (ms *metricsServer) register(pattern string, handler http.Handler) {
|
|
ms.mux.Handle(pattern, handler)
|
|
}
|
|
|
|
// registerMetricsServerHandler adds handlers for metrics server.
|
|
// This sets up both Prometheus format and JSON format endpoints for metrics
|
|
func (ms *metricsServer) registerMetricsServerHandler() {
|
|
ms.register("/metrics", promhttp.HandlerFor(
|
|
ms.reg,
|
|
promhttp.HandlerOpts{
|
|
EnableOpenMetrics: true,
|
|
Timeout: 10 * time.Second,
|
|
},
|
|
))
|
|
ms.register("/metrics/json", jsonResponse(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
g := prometheus.ToTransactionalGatherer(ms.reg)
|
|
mfs, done, err := g.Gather()
|
|
defer done()
|
|
if err != nil {
|
|
msg := "could not gather metrics"
|
|
mainLog.Load().Warn().Err(err).Msg(msg)
|
|
http.Error(w, msg, http.StatusInternalServerError)
|
|
return
|
|
}
|
|
result := make([]*prom2json.Family, 0, len(mfs))
|
|
for _, mf := range mfs {
|
|
result = append(result, prom2json.NewFamily(mf))
|
|
}
|
|
if err := json.NewEncoder(w).Encode(result); err != nil {
|
|
msg := "could not marshal metrics result"
|
|
mainLog.Load().Warn().Err(err).Msg(msg)
|
|
http.Error(w, msg, http.StatusInternalServerError)
|
|
return
|
|
}
|
|
})))
|
|
}
|
|
|
|
// start runs the metricsServer.
|
|
// This starts the HTTP server for metrics exposure
|
|
func (ms *metricsServer) start() error {
|
|
listener, err := net.Listen("tcp", ms.addr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
go ms.server.Serve(listener)
|
|
ms.started = true
|
|
return nil
|
|
}
|
|
|
|
// stop shutdowns the metricsServer within 2 seconds timeout.
|
|
// This ensures graceful shutdown of the metrics server
|
|
func (ms *metricsServer) stop() error {
|
|
if !ms.started {
|
|
return nil
|
|
}
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*1)
|
|
defer cancel()
|
|
return ms.server.Shutdown(ctx)
|
|
}
|
|
|
|
// runMetricsServer initializes metrics stats and runs the metrics server if enabled.
|
|
// This sets up the complete metrics infrastructure including Prometheus collectors
|
|
func (p *prog) runMetricsServer(ctx context.Context, reloadCh chan struct{}) {
|
|
if !p.metricsEnabled() {
|
|
return
|
|
}
|
|
|
|
// Reset all stats.
|
|
statsVersion.Reset()
|
|
statsQueriesCount.Reset()
|
|
statsClientQueriesCount.Reset()
|
|
|
|
reg := prometheus.NewRegistry()
|
|
// Register queries count stats if enabled.
|
|
if p.metricsQueryStats.Load() {
|
|
reg.MustRegister(statsQueriesCount)
|
|
reg.MustRegister(statsClientQueriesCount)
|
|
}
|
|
|
|
addr := p.cfg.Service.MetricsListener
|
|
ms, err := newMetricsServer(addr, reg)
|
|
if err != nil {
|
|
mainLog.Load().Warn().Err(err).Msg("Could not create new metrics server")
|
|
return
|
|
}
|
|
// Only start listener address if defined.
|
|
if addr != "" {
|
|
// Go runtime stats.
|
|
reg.MustRegister(collectors.NewBuildInfoCollector())
|
|
reg.MustRegister(collectors.NewGoCollector(
|
|
collectors.WithGoCollectorRuntimeMetrics(collectors.MetricsAll),
|
|
))
|
|
// ctrld stats.
|
|
reg.MustRegister(statsVersion)
|
|
statsVersion.WithLabelValues(commit, runtime.Version(), curVersion()).Inc()
|
|
reg.MustRegister(statsTimeStart)
|
|
statsTimeStart.Set(float64(time.Now().Unix()))
|
|
mainLog.Load().Debug().Msgf("Starting metrics server on: %s", addr)
|
|
if err := ms.start(); err != nil {
|
|
mainLog.Load().Warn().Err(err).Msg("Could not start metrics server")
|
|
return
|
|
}
|
|
}
|
|
|
|
select {
|
|
case <-p.stopCh:
|
|
case <-ctx.Done():
|
|
case <-reloadCh:
|
|
}
|
|
|
|
if err := ms.stop(); err != nil {
|
|
mainLog.Load().Warn().Err(err).Msg("Could not stop metrics server")
|
|
return
|
|
}
|
|
}
|