package metrics import ( "fmt" "sync" "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" ) type Key struct { Group string Version string Kind string } func init() { gin.SetMode(gin.ReleaseMode) gin.DisableConsoleColor() } var Mutex sync.Mutex var ( // Variables that are to be registered with prometheus. // promauto automactically registers the variable with prometheus. If promauto is not used variable needs to be registered using prometheus.register // The following variables are of type Gauge metric. CtlfishResourceCreations = promauto.NewCounterVec( prometheus.CounterOpts{ Namespace: "ctlfish", Name: "resource_creations", Help: "Resources Created by ctlfish", }, []string{"Group", "Version", "Kind"}) CtlfishResourceUpdates = promauto.NewCounterVec( prometheus.CounterOpts{ Namespace: "ctlfish", Name: "resource_updates", Help: "Resources Updated by ctlfish", }, []string{"Group", "Version", "Kind"}) CtlfishResourceDeletions = promauto.NewCounterVec( prometheus.CounterOpts{ Namespace: "ctlfish", Name: "resource_deletions", Help: "Resources Deleted by ctlfish", }, []string{"Group", "Version", "Kind"}) ) type ServerConfig struct { Port int } type LogMessageObject struct { Level string `json:"level"` // "info", "warn", "error" Timestamp int64 `json:"ts"` // When the request is received Msg string `json:"msg"` // The log message // Request info RequestBody []byte // base64 encoded in logs for better parsing/safety. UserAgent string RemoteAddr string Method string URL string // Response info Status int Latency string // How long the request took to process. } type Server struct { Router *gin.Engine Config ServerConfig } var MetricsEndpoints = []string{"/metrics", "/ctlfish/metrics"} // NewServer creates a Ctlfish server that runs on the desired port. func NewServer(cfg ServerConfig) (*Server, error) { if cfg.Port <= 0 || cfg.Port > 65535 { return nil, fmt.Errorf("Invalid port number %q", cfg.Port) } s := &Server{ Config: cfg, } // setup router s.Router = gin.New() // metrics (prometheus) endpoints metricsHandlerFunc := gin.WrapH(promhttp.Handler()) for _, mep := range MetricsEndpoints { s.Router.GET(mep, metricsHandlerFunc) } return s, nil } // Run runs the Gin server on the configured port func (s *Server) Run() { addr := fmt.Sprintf(":%d", s.Config.Port) err := s.Router.Run(addr) if err != nil { fmt.Print("Error when Running the router") } }