feat(go-cache-service): metrics (+grafana) (#68)

* feat(go-proxy-cache): handle when cache is not accessible

* feat(go-proxy-cache): serve metrics over http

* feat(go-proxy-cache): metrics

* feat(go-proxy-cache): fix pr comments

fixes #67

* feat(go-proxy-cache): update github actions

* feat(go-proxy-cache): fix linter
This commit is contained in:
Andrey Bocharnikov
2025-09-17 17:26:23 +04:00
committed by GitHub
parent df369f0949
commit b4ea66fa1f
29 changed files with 2254 additions and 494 deletions
@@ -0,0 +1,50 @@
package httpserver
import (
"context"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.uber.org/zap"
)
// MetricsServer represents a separate HTTP server for metrics
type MetricsServer struct {
logger *zap.Logger
server *http.Server
}
// NewMetricsServer creates a new metrics HTTP server
func NewMetricsServer(logger *zap.Logger) *MetricsServer {
return &MetricsServer{
logger: logger,
}
}
// Start starts the metrics HTTP server on the specified port
func (ms *MetricsServer) Start(port string) error {
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())
ms.server = &http.Server{
Addr: ":" + port,
Handler: mux,
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 60 * time.Second,
}
ms.logger.Info("Starting metrics HTTP server", zap.String("port", port))
return ms.server.ListenAndServe()
}
// Stop stops the metrics HTTP server
func (ms *MetricsServer) Stop(ctx context.Context) error {
if ms.server == nil {
return nil
}
ms.logger.Info("Stopping metrics HTTP server")
return ms.server.Shutdown(ctx)
}
+7 -5
View File
@@ -10,7 +10,6 @@ import (
"time"
"github.com/gorilla/mux"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.uber.org/zap"
"go-proxy-cache/internal/cache/service"
@@ -65,7 +64,13 @@ func (s *Server) StartUnixSocket(socketPath string) error {
// Stop stops the HTTP server
func (s *Server) Stop(ctx context.Context) error {
s.logger.Info("Stopping cache HTTP server")
return s.server.Shutdown(ctx)
// Stop main server
if s.server != nil {
return s.server.Shutdown(ctx)
}
return nil
}
// createRouter creates and configures the HTTP router
@@ -82,9 +87,6 @@ func (s *Server) createRouter() *mux.Router {
// Cache info endpoint (equivalent to cache rules check)
router.HandleFunc("/cache/info", s.handleCacheInfo).Methods("POST")
// Prometheus metrics endpoint
router.Handle("/metrics", promhttp.Handler()).Methods("GET")
return router
}
@@ -61,25 +61,6 @@ func (m *mockCache) Delete(key string) {
delete(m.data, key)
}
// mockKeyBuilder implements the KeyBuilder interface for testing
type mockKeyBuilder struct{}
func (m *mockKeyBuilder) Build(chain string, network string, req *models.JSONRPCRequest) (key string, paramsHash uint32) {
if req == nil || req.Method == "" {
return "", 0
}
return chain + ":" + network + ":" + req.Method, 12345
}
func (m *mockKeyBuilder) BuildBatch(chain, network string, reqs []models.JSONRPCRequest) ([]string, []uint32) {
keys := make([]string, len(reqs))
hashes := make([]uint32, len(reqs))
for i, req := range reqs {
keys[i], hashes[i] = m.Build(chain, network, &req)
}
return keys, hashes
}
// setupMockCacheClassifier configures the mock cache classifier with common expectations
func setupMockCacheClassifier(ctrl *gomock.Controller) *mock.MockCacheRulesClassifier {
mockClassifier := mock.NewMockCacheRulesClassifier(ctrl)