diff --git a/api/metrics/multi_gatherer.go b/api/metrics/multi_gatherer.go index 79affd4b7b2e..45d4439622b4 100644 --- a/api/metrics/multi_gatherer.go +++ b/api/metrics/multi_gatherer.go @@ -15,6 +15,7 @@ import ( "golang.org/x/exp/slices" "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/metric" ) var ( @@ -50,23 +51,19 @@ func (g *multiGatherer) Gather() ([]*dto.MetricFamily, error) { var results []*dto.MetricFamily for namespace, gatherer := range g.gatherers { - metrics, err := gatherer.Gather() + gatheredMetrics, err := gatherer.Gather() if err != nil { return nil, err } - for _, metric := range metrics { + for _, gatheredMetric := range gatheredMetrics { var name string - if metric.Name != nil { - if len(namespace) > 0 { - name = fmt.Sprintf("%s_%s", namespace, *metric.Name) - } else { - name = *metric.Name - } + if gatheredMetric.Name != nil { + name = metric.AppendNamespace(namespace, *gatheredMetric.Name) } else { name = namespace } - metric.Name = &name - results = append(results, metric) + gatheredMetric.Name = &name + results = append(results, gatheredMetric) } } // Because we overwrite every metric's name, we are guaranteed that there diff --git a/chains/manager.go b/chains/manager.go index 97f80e1a79c5..84762d3eb3f2 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -50,6 +50,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/metric" "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/version" @@ -447,7 +448,7 @@ func (m *manager) buildChain(chainParams ChainParameters, sb subnets.Subnet) (*c } consensusMetrics := prometheus.NewRegistry() - chainNamespace := fmt.Sprintf("%s_%s", constants.PlatformName, primaryAlias) + chainNamespace := metric.AppendNamespace(constants.PlatformName, primaryAlias) if err := m.Metrics.Register(chainNamespace, consensusMetrics); err != nil { return nil, fmt.Errorf("error while registering chain's metrics %w", err) } @@ -456,13 +457,13 @@ func (m *manager) buildChain(chainParams ChainParameters, sb subnets.Subnet) (*c // `avalanche_{chainID}_` into `avalanche_{chainID}_avalanche_` so that // there are no conflicts when registering the Snowman consensus metrics. avalancheConsensusMetrics := prometheus.NewRegistry() - avalancheDAGNamespace := fmt.Sprintf("%s_avalanche", chainNamespace) + avalancheDAGNamespace := metric.AppendNamespace(chainNamespace, "avalanche") if err := m.Metrics.Register(avalancheDAGNamespace, avalancheConsensusMetrics); err != nil { return nil, fmt.Errorf("error while registering DAG metrics %w", err) } vmMetrics := metrics.NewOptionalGatherer() - vmNamespace := fmt.Sprintf("%s_vm", chainNamespace) + vmNamespace := metric.AppendNamespace(chainNamespace, "vm") if err := m.Metrics.Register(vmNamespace, vmMetrics); err != nil { return nil, fmt.Errorf("error while registering vm's metrics %w", err) } diff --git a/message/creator.go b/message/creator.go index a5711375c331..8040bccb1861 100644 --- a/message/creator.go +++ b/message/creator.go @@ -4,13 +4,13 @@ package message import ( - "fmt" "time" "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/metric" ) var _ Creator = (*creator)(nil) @@ -32,7 +32,7 @@ func NewCreator( compressionType compression.Type, maxMessageTimeout time.Duration, ) (Creator, error) { - namespace := fmt.Sprintf("%s_codec", parentNamespace) + namespace := metric.AppendNamespace(parentNamespace, "codec") builder, err := newMsgBuilder( log, namespace, diff --git a/network/throttling/inbound_msg_throttler.go b/network/throttling/inbound_msg_throttler.go index 86e20085466c..ea9167deca15 100644 --- a/network/throttling/inbound_msg_throttler.go +++ b/network/throttling/inbound_msg_throttler.go @@ -5,7 +5,6 @@ package throttling import ( "context" - "fmt" "github.com/prometheus/client_golang/prometheus" @@ -13,6 +12,7 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/metric" ) var _ InboundMsgThrottler = (*inboundMsgThrottler)(nil) @@ -90,7 +90,7 @@ func NewInboundMsgThrottler( return nil, err } cpuThrottler, err := NewSystemThrottler( - fmt.Sprintf("%s_cpu", namespace), + metric.AppendNamespace(namespace, "cpu"), registerer, throttlerConfig.CPUThrottlerConfig, resourceTracker.CPUTracker(), @@ -100,7 +100,7 @@ func NewInboundMsgThrottler( return nil, err } diskThrottler, err := NewSystemThrottler( - fmt.Sprintf("%s_disk", namespace), + metric.AppendNamespace(namespace, "disk"), registerer, throttlerConfig.DiskThrottlerConfig, resourceTracker.DiskTracker(), diff --git a/snow/engine/common/queue/state.go b/snow/engine/common/queue/state.go index 68ba67ce38c1..76bce7c838c1 100644 --- a/snow/engine/common/queue/state.go +++ b/snow/engine/common/queue/state.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/metric" "github.com/ava-labs/avalanchego/utils/set" ) @@ -61,7 +62,7 @@ func newState( metricsNamespace string, metricsRegisterer prometheus.Registerer, ) (*state, error) { - jobsCacheMetricsNamespace := fmt.Sprintf("%s_jobs_cache", metricsNamespace) + jobsCacheMetricsNamespace := metric.AppendNamespace(metricsNamespace, "jobs_cache") jobsCache, err := metercacher.New[ids.ID, Job]( jobsCacheMetricsNamespace, metricsRegisterer, diff --git a/snow/networking/handler/message_queue_metrics.go b/snow/networking/handler/message_queue_metrics.go index 429295ae04cb..20bc4c7766f9 100644 --- a/snow/networking/handler/message_queue_metrics.go +++ b/snow/networking/handler/message_queue_metrics.go @@ -9,6 +9,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/avalanchego/message" + "github.com/ava-labs/avalanchego/utils/metric" "github.com/ava-labs/avalanchego/utils/wrappers" ) @@ -24,7 +25,7 @@ func (m *messageQueueMetrics) initialize( metricsRegisterer prometheus.Registerer, ops []message.Op, ) error { - namespace := fmt.Sprintf("%s_%s", metricsNamespace, "unprocessed_msgs") + namespace := metric.AppendNamespace(metricsNamespace, "unprocessed_msgs") m.len = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, Name: "len", diff --git a/utils/metric/namespace.go b/utils/metric/namespace.go new file mode 100644 index 000000000000..4371bb1dc077 --- /dev/null +++ b/utils/metric/namespace.go @@ -0,0 +1,17 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package metric + +import "strings" + +func AppendNamespace(prefix, suffix string) string { + switch { + case len(prefix) == 0: + return suffix + case len(suffix) == 0: + return prefix + default: + return strings.Join([]string{prefix, suffix}, "_") + } +} diff --git a/utils/metric/namespace_test.go b/utils/metric/namespace_test.go new file mode 100644 index 000000000000..b1daf8ec11b1 --- /dev/null +++ b/utils/metric/namespace_test.go @@ -0,0 +1,46 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package metric + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestAppendNamespace(t *testing.T) { + tests := []struct { + prefix string + suffix string + expected string + }{ + { + prefix: "avalanchego", + suffix: "isgreat", + expected: "avalanchego_isgreat", + }, + { + prefix: "", + suffix: "sucks", + expected: "sucks", + }, + { + prefix: "sucks", + suffix: "", + expected: "sucks", + }, + { + prefix: "", + suffix: "", + expected: "", + }, + } + for _, test := range tests { + t.Run(strings.Join([]string{test.prefix, test.suffix}, "_"), func(t *testing.T) { + namespace := AppendNamespace(test.prefix, test.suffix) + require.Equal(t, test.expected, namespace) + }) + } +} diff --git a/vms/proposervm/state/block_state.go b/vms/proposervm/state/block_state.go index 862d492b925b..0c5e210a8d81 100644 --- a/vms/proposervm/state/block_state.go +++ b/vms/proposervm/state/block_state.go @@ -5,7 +5,6 @@ package state import ( "errors" - "fmt" "github.com/prometheus/client_golang/prometheus" @@ -15,6 +14,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/metric" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/version" @@ -69,7 +69,7 @@ func NewBlockState(db database.Database) BlockState { func NewMeteredBlockState(db database.Database, namespace string, metrics prometheus.Registerer) (BlockState, error) { blkCache, err := metercacher.New[ids.ID, *blockWrapper]( - fmt.Sprintf("%s_block_cache", namespace), + metric.AppendNamespace(namespace, "block_cache"), metrics, cache.NewSizedLRU[ids.ID, *blockWrapper]( blockCacheSize,