Skip to content

Commit

Permalink
feat: add solana_node_is_active metric
Browse files Browse the repository at this point in the history
  • Loading branch information
andreclaro committed Jan 14, 2025
1 parent cf01b8a commit ed1fda1
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ The table below describes all the metrics collected by the `solana-exporter`:
| `solana_account_balance` | Solana account balances. | `address` |
| `solana_node_version` | Node version of solana.* | `version` |
| `solana_node_is_healthy` | Whether the node is healthy.* | N/A |
| `solana_node_is_active` | Whether the node is active and participating in consensus. | `nodekey` |
| `solana_node_num_slots_behind` | The number of slots that the node is behind the latest cluster confirmed slot.* | N/A |
| `solana_node_minimum_ledger_slot` | The lowest slot that the node has information about in its ledger.* | N/A |
| `solana_node_first_available_block` | The slot of the lowest confirmed block that has not been purged from the node's ledger.* | N/A |
Expand Down
30 changes: 30 additions & 0 deletions cmd/solana-exporter/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type SolanaCollector struct {
NodeNumSlotsBehind *GaugeDesc
NodeMinimumLedgerSlot *GaugeDesc
NodeFirstAvailableBlock *GaugeDesc
NodeIsActive *GaugeDesc
}

func NewSolanaCollector(client *rpc.Client, config *ExporterConfig) *SolanaCollector {
Expand Down Expand Up @@ -104,6 +105,11 @@ func NewSolanaCollector(client *rpc.Client, config *ExporterConfig) *SolanaColle
"solana_node_first_available_block",
"The slot of the lowest confirmed block that has not been purged from the node's ledger.",
),
NodeIsActive: NewGaugeDesc(
"solana_node_is_active",
"Whether the node is active and participating in consensus.",
NodekeyLabel,
),
}
return collector
}
Expand All @@ -120,6 +126,7 @@ func (c *SolanaCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- c.NodeNumSlotsBehind.Desc
ch <- c.NodeMinimumLedgerSlot.Desc
ch <- c.NodeFirstAvailableBlock.Desc
ch <- c.NodeIsActive.Desc
}

func (c *SolanaCollector) collectVoteAccounts(ctx context.Context, ch chan<- prometheus.Metric) {
Expand Down Expand Up @@ -268,6 +275,28 @@ func (c *SolanaCollector) collectHealth(ctx context.Context, ch chan<- prometheu
return
}

func (c *SolanaCollector) collectNodeIdentityPubKey(ctx context.Context, ch chan<- prometheus.Metric) {
c.logger.Info("Collecting node identity pubkey...")

nodeIdentityPubkey, err := c.rpcClient.GetIdentity(ctx)
if err != nil {
c.logger.Errorf("failed to get node identity: %v", err)
ch <- c.NodeIsActive.NewInvalidMetric(err)
return
}

isActive := 0
for _, configuredKey := range c.config.NodeKeys {
if configuredKey == nodeIdentityPubkey {
isActive = 1
break
}
}

ch <- c.NodeIsActive.MustNewConstMetric(float64(isActive), nodeIdentityPubkey)
c.logger.Info("Node identity pubkey collected.")
}

func (c *SolanaCollector) Collect(ch chan<- prometheus.Metric) {
c.logger.Info("========== BEGIN COLLECTION ==========")
ctx, cancel := context.WithCancel(context.Background())
Expand All @@ -280,6 +309,7 @@ func (c *SolanaCollector) Collect(ch chan<- prometheus.Metric) {
c.collectVersion(ctx, ch)
c.collectIdentity(ctx, ch)
c.collectBalances(ctx, ch)
c.collectNodeIdentityPubKey(ctx, ch)

c.logger.Info("=========== END COLLECTION ===========")
}
12 changes: 8 additions & 4 deletions cmd/solana-exporter/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import (
"bytes"
"context"
"fmt"
"github.com/asymmetric-research/solana-exporter/pkg/rpc"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/stretchr/testify/assert"
"math"
"math/rand"
"slices"
"strings"
"testing"
"time"

"github.com/asymmetric-research/solana-exporter/pkg/rpc"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/stretchr/testify/assert"
)

type (
Expand Down Expand Up @@ -240,6 +241,9 @@ func TestSolanaCollector(t *testing.T) {
collector.NodeIdentity.makeCollectionTest(
NewLV(1, "testIdentity"),
),
collector.NodeIsActive.makeCollectionTest(
NewLV(1),
),
collector.NodeIsHealthy.makeCollectionTest(
NewLV(1),
),
Expand Down
14 changes: 13 additions & 1 deletion pkg/rpc/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package rpc

import (
"context"
"github.com/stretchr/testify/assert"
"testing"

"github.com/stretchr/testify/assert"
)

func newMethodTester(t *testing.T, method string, result any) (*MockServer, *Client) {
Expand Down Expand Up @@ -244,3 +245,14 @@ func TestClient_GetVoteAccounts(t *testing.T) {
voteAccounts,
)
}
func TestClient_GetIdentity(t *testing.T) {
_, client := newMethodTester(t, "getIdentity", map[string]string{
"identity": "random2r1F4iWqVcb8M1DbAjQuFpebkQuW2DJtestkey",
})
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

identity, err := client.GetIdentity(ctx)
assert.NoError(t, err)
assert.Equal(t, "random2r1F4iWqVcb8M1DbAjQuFpebkQuW2DJtestkey", identity)
}

0 comments on commit ed1fda1

Please sign in to comment.