Skip to content

Commit

Permalink
fix(server/v2/api/telemetry): enable global metrics (#22571)
Browse files Browse the repository at this point in the history
(cherry picked from commit b45cf75)

# Conflicts:
#	server/v2/api/telemetry/server.go
  • Loading branch information
tac0turtle authored and mergify[bot] committed Nov 20, 2024
1 parent f1b3b3d commit 94d6b1d
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 1 deletion.
130 changes: 130 additions & 0 deletions server/v2/api/telemetry/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package telemetry

import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"

"cosmossdk.io/core/server"
"cosmossdk.io/core/transaction"
"cosmossdk.io/log"
serverv2 "cosmossdk.io/server/v2"

Check failure on line 13 in server/v2/api/telemetry/server.go

View workflow job for this annotation

GitHub Actions / split-test-files

no required module provides package cosmossdk.io/server/v2; to add it:

Check failure on line 13 in server/v2/api/telemetry/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

no required module provides package cosmossdk.io/server/v2; to add it:

Check failure on line 13 in server/v2/api/telemetry/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

no required module provides package cosmossdk.io/server/v2; to add it:

Check failure on line 13 in server/v2/api/telemetry/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

could not import cosmossdk.io/server/v2 (invalid package name: "")
)

var (
_ serverv2.ServerComponent[transaction.Tx] = (*Server[transaction.Tx])(nil)
_ serverv2.HasConfig = (*Server[transaction.Tx])(nil)
)

const ServerName = "telemetry"

type Server[T transaction.Tx] struct {
logger log.Logger
config *Config

Check failure on line 25 in server/v2/api/telemetry/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: Config
server *http.Server
metrics *Metrics

Check failure on line 27 in server/v2/api/telemetry/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: Metrics
}

// New creates a new telemetry server.
func New[T transaction.Tx](cfg server.ConfigMap, logger log.Logger, enableTelemetry func()) (*Server[T], error) {
srv := &Server[T]{}
serverCfg := srv.Config().(*Config)

Check failure on line 33 in server/v2/api/telemetry/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: Config
if len(cfg) > 0 {
if err := serverv2.UnmarshalSubConfig(cfg, srv.Name(), &serverCfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
}
}
srv.config = serverCfg
srv.logger = logger.With(log.ModuleKey, srv.Name())

if enableTelemetry == nil {
panic("enableTelemetry must be provided")
}

if srv.config.Enable {
enableTelemetry()
}

metrics, err := NewMetrics(srv.config)

Check failure on line 50 in server/v2/api/telemetry/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: NewMetrics
if err != nil {
return nil, fmt.Errorf("failed to initialize metrics: %w", err)
}
srv.metrics = metrics
return srv, nil
}

// Name returns the server name.
func (s *Server[T]) Name() string {
return ServerName
}

func (s *Server[T]) Config() any {
if s.config == nil || s.config.Address == "" {
return DefaultConfig()

Check failure on line 65 in server/v2/api/telemetry/server.go

View workflow job for this annotation

GitHub Actions / dependency-review

undefined: DefaultConfig
}

return s.config
}

func (s *Server[T]) Start(ctx context.Context) error {
if !s.config.Enable {
s.logger.Info(fmt.Sprintf("%s server is disabled via config", s.Name()))
return nil
}

mux := http.NewServeMux()
// /metrics is the default standard path for Prometheus metrics.
mux.HandleFunc("/metrics", s.metricsHandler)
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/metrics", http.StatusMovedPermanently)
})

s.server = &http.Server{
Addr: s.config.Address,
Handler: mux,
}

s.logger.Info("starting telemetry server...", "address", s.config.Address)
if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
return fmt.Errorf("failed to start telemetry server: %w", err)
}

return nil
}

func (s *Server[T]) Stop(ctx context.Context) error {
if !s.config.Enable || s.server == nil {
return nil
}

s.logger.Info("stopping telemetry server...", "address", s.config.Address)
return s.server.Shutdown(ctx)
}

func (s *Server[T]) metricsHandler(w http.ResponseWriter, r *http.Request) {
format := strings.TrimSpace(r.FormValue("format"))

// errorResponse defines the attributes of a JSON error response.
type errorResponse struct {
Code int `json:"code,omitempty"`
Error string `json:"error"`
}

gr, err := s.metrics.Gather(format)
if err != nil {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
bz, err := json.Marshal(errorResponse{Code: 400, Error: fmt.Sprintf("failed to gather metrics: %s", err)})
if err != nil {
return
}
_, _ = w.Write(bz)

return
}

w.Header().Set("Content-Type", gr.ContentType)
_, _ = w.Write(gr.Metrics)
}
3 changes: 2 additions & 1 deletion simapp/v2/simdv2/cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/cosmos/cosmos-sdk/client/debug"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/client/rpc"
sdktelemetry "github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
"github.com/cosmos/cosmos-sdk/x/genutil"
Expand Down Expand Up @@ -118,7 +119,7 @@ func InitRootCmd[T transaction.Tx](
}
}

telemetryServer, err := telemetry.New[T](deps.GlobalConfig, logger)
telemetryServer, err := telemetry.New[T](deps.GlobalConfig, logger, sdktelemetry.EnableTelemetry)
if err != nil {
return nil, err
}
Expand Down
5 changes: 5 additions & 0 deletions telemetry/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ func IsTelemetryEnabled() bool {
return globalTelemetryEnabled
}

// EnableTelemetry allows for the global telemetry enabled state to be set.
func EnableTelemetry() {
globalTelemetryEnabled = true
}

// globalLabels defines the set of global labels that will be applied to all
// metrics emitted using the telemetry package function wrappers.
var globalLabels = []metrics.Label{}
Expand Down

0 comments on commit 94d6b1d

Please sign in to comment.