diff --git a/.github/workflows/go-test.yaml b/.github/workflows/go-test.yaml
index 67e0e0f..79f8672 100644
--- a/.github/workflows/go-test.yaml
+++ b/.github/workflows/go-test.yaml
@@ -32,7 +32,7 @@ jobs:
run: go test -v -coverprofile=coverage.out ./...
- name: Upload coverage report
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: coverage-report
- path: coverage.out
\ No newline at end of file
+ path: coverage.out
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d36d33b..084ddf1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,23 +12,26 @@ and more configurability.
Below is a list of newly added metrics (see the [README](README.md)
for metric descriptions):
-* `solana_account_balance` ([@johnstonematt](https://github.com/johnstonematt))
-* `solana_node_is_healthy` ([@GranderStark](https://github.com/GranderStark))
-* `solana_nude_num_slots_behind` ([@GranderStark](https://github.com/GranderStark))
-* `solana_node_minimum_ledger_slot` ([@GranderStark](https://github.com/GranderStark))
-* `solana_node_first_available_block` ([@GranderStark](https://github.com/GranderStark))
-* `solana_cluster_slots_by_epoch_total` ([@johnstonematt](https://github.com/johnstonematt))
-* `solana_validator_fee_rewards` ([@johnstonematt](https://github.com/johnstonematt))
-* `solana_validator_block_size` ([@johnstonematt](https://github.com/johnstonematt))
-* `solana_node_block_height` ([@GranderStark](https://github.com/GranderStark))
-* `solana_cluster_active_stake` ([@johnstonematt](https://github.com/johnstonematt))
-* `solana_cluster_last_vote` ([@johnstonematt](https://github.com/johnstonematt))
-* `solana_cluster_root_slot` ([@johnstonematt](https://github.com/johnstonematt))
-* `solana_cluster_validator_count` ([@johnstonematt](https://github.com/johnstonematt))
+* `solana_account_balance` (**[@johnstonematt](https://github.com/johnstonematt)**)
+* `solana_node_is_healthy` (**[@GranderStark](https://github.com/GranderStark)**)
+* `solana_node_num_slots_behind` (**[@GranderStark](https://github.com/GranderStark)**)
+* `solana_node_minimum_ledger_slot` (**[@GranderStark](https://github.com/GranderStark)**)
+* `solana_node_first_available_block` (**[@GranderStark](https://github.com/GranderStark)**)
+* `solana_cluster_slots_by_epoch_total` (**[@johnstonematt](https://github.com/johnstonematt)**)
+* `solana_validator_fee_rewards` (**[@johnstonematt](https://github.com/johnstonematt)**)
+* `solana_validator_block_size` (**[@johnstonematt](https://github.com/johnstonematt)**)
+* `solana_node_block_height` (**[@GranderStark](https://github.com/GranderStark)**)
+* `solana_cluster_active_stake` (**[@johnstonematt](https://github.com/johnstonematt)**)
+* `solana_cluster_last_vote` (**[@johnstonematt](https://github.com/johnstonematt)**)
+* `solana_cluster_root_slot` (**[@johnstonematt](https://github.com/johnstonematt)**)
+* `solana_cluster_validator_count` (**[@johnstonematt](https://github.com/johnstonematt)**)
+* `solana_node_identity` (**[@impactdni2](https://github.com/impactdni2)**)
+* `solana_node_is_active` (**[@andreclaro](https://github.com/andreclaro)**)
+* `solana_foundation_min_required_version` (**[@qedgardo](https://github.com/qedgardo)**)
#### Renamed Metrics
-The table below contains all metrics renamed in `v3.0.0` ([@johnstonematt](https://github.com/johnstonematt)):
+The table below contains all metrics renamed in `v3.0.0` (**[@johnstonematt](https://github.com/johnstonematt)**):
| Old Name | New Name |
|---------------------------------------|------------------------------------------------|
@@ -50,14 +53,14 @@ Metrics were renamed to:
#### Label Updates
-The following labels were renamed ([@johnstonematt](https://github.com/johnstonematt)):
+The following labels were renamed (**[@johnstonematt](https://github.com/johnstonematt)**):
* `pubkey` was renamed to `votekey`, to clearly identity that it refers to the address of a validators vote account.
### Config Updates
#### New Config Parameters
Below is a list of newly added config parameters (see the [README](README.md)
-for parameter descriptions) ([@johnstonematt](https://github.com/johnstonematt)):
+for parameter descriptions) (**[@johnstonematt](https://github.com/johnstonematt)**):
* `-balance-address`
* `-nodekey`
@@ -67,10 +70,12 @@ for parameter descriptions) ([@johnstonematt](https://github.com/john
* `-light-mode`
* `-http-timeout`
* `-comprehensive-vote-account-tracking`
+ * `-active-identity`
+ * `epoch-cleanup-time`
#### Renamed Config Parameters
-The table below contains all config parameters renamed in `v3.0.0` ([@johnstonematt](https://github.com/johnstonematt)):
+The table below contains all config parameters renamed in `v3.0.0` (**[@johnstonematt](https://github.com/johnstonematt)**):
| Old Name | New Name |
|-------------------------------------|-------------------|
@@ -79,21 +84,25 @@ The table below contains all config parameters renamed in `v3.0.0` ([
#### Removed Config Parameters
-The following metrics were removed ([@johnstonematt](https://github.com/johnstonematt)):
+The following metrics were removed (**[@johnstonematt](https://github.com/johnstonematt)**):
* `votepubkey`. Configure validator tracking using the `-nodekey` parameter.
### General Updates
* The project was renamed from `solana_exporter` to `solana-exporter`, to conform with
-[Go naming conventions](https://github.com/unknwon/go-code-convention/blob/main/en-US.md) ([@johnstonematt](https://github.com/johnstonematt)).
-* Testing was significantly improved ([@johnstonematt](https://github.com/johnstonematt)).
+[Go naming conventions](https://github.com/unknwon/go-code-convention/blob/main/en-US.md) (**[@johnstonematt](https://github.com/johnstonematt)**).
+* Testing was significantly improved (**[@johnstonematt](https://github.com/johnstonematt)**).
* [klog](https://github.com/kubernetes/klog) logging was removed and replaced with [zap](https://github.com/uber-go/zap)
- ([@johnstonematt](https://github.com/johnstonematt))
-* Easy usage ([@johnstonematt](https://github.com/johnstonematt)):
+ (**[@johnstonematt](https://github.com/johnstonematt)**)
+* Easy usage (**[@johnstonematt](https://github.com/johnstonematt)**):
* The example dashboard was updated.
* An example prometheus config was added, as well as recording rules for tracking skip rate.
## New Contributors
-* [@GranderStark](https://github.com/GranderStark) made their first contribution.
+* **[@GranderStark](https://github.com/GranderStark)** made their first contribution in **[#33](https://github.com/asymmetric-research/solana-exporter/pull/33)**.
+* **[@dylanschultzie](https://github.com/dylanschultzie)** made their first contribution in **[#49](https://github.com/asymmetric-research/solana-exporter/pull/49)**.
+* **[@impactdni2](https://github.com/impactdni2)** made their first contribution in **[#83](https://github.com/asymmetric-research/solana-exporter/pull/83)**.
+* **[@andreclaro](https://github.com/andreclaro)** made their first contribution in **[#84](https://github.com/asymmetric-research/solana-exporter/pull/84)**.
+* **[@qedgardo](https://github.com/quedgardo)** made their first contribution in **[#85](https://github.com/asymmetric-research/solana-exporter/pull/85)**.
diff --git a/README.md b/README.md
index 90d4042..acf0c8c 100644
--- a/README.md
+++ b/README.md
@@ -15,10 +15,61 @@ solana-exporter \
-balance-address -balance-address \
-comprehensive-slot-tracking \
-monitor-block-sizes
+ -active-identity
```
![Solana Exporter Dashboard Sample](assets/solana-dashboard-screenshot.png)
+### Features
+#### Balance Tracking
+
+Using the `-balance-address ` configuration parameter, the exporter can be used to monitor any account's
+SOL balance. This parameter can be set multiple times to track multiple accounts. Additionally, the balance of all
+configured `-nodekey`'s is automatically tracked.
+
+#### Block Sizes
+
+If the `-monitor-block-sizes` flag is set, then the exporter will export the number of transactions (both vote-only and
+non-vote transactions) in blocks produced by the monitored validators. This is a critical validator performance metric.
+
+Cluster average block size can be inferred by dividing total network transactions by total block height.
+
+#### Income Reporting
+
+The exporter exports metrics regarding total priority fee revenue and inflation reward revenue earned by the
+monitored validators.
+
+#### Skip Rate
+
+The exporter does not directly export skip rate, as this needs to be defined as an average over a desired timeframe.
+However, the exporter does track the monitored validators leader slots and whether they are `valid` or `skipped`.
+
+The example prometheus setup contains [recording rules](prometheus/solana-rules.yml) for measuring average skip rate
+for both individual validators and a cluster-level over hourly, daily and epoch intervals.
+
+#### Active/Passive Monitoring
+
+The `solana_node_is_active` metric simply reports whether the node (on which the exporter is running) has the same
+identity-keypair as that configured with the `-active-identity` flag. The `-active-identity` flag should be used to
+specify the primary identity when using a
+[non-delinquent backup validator](https://pumpkins-pool.gitbook.io/pumpkins-pool).
+
+#### Light Mode
+
+Certain metrics, such as validator leader slots, income, block size and active stake, are visible on-chain through any
+trusted node. However, other metrics such as node health and block height can only be viewed from an exporter running
+on the node in question. Thus, on a node in which fine margins of performance are of critical interest, the exporter
+can be set to `-light-mode`. In light mode, it will only export metrics that cannot be viewed from other nodes.
+
+This is particularly useful in setups that contain an important validator and utility RPC node - the exporter can be
+run in light mode on the validator and in full capacity on the RPC node (configured to monitor the validator through
+use of the `-nodekey` parameter).
+
+#### General Performance and Health
+
+In addition to the above features, the exporter provides key metrics for monitoring Solana node health and performance.
+See [Metrics](#metrics) below for more details.
+
## Installation
### Build
@@ -49,6 +100,7 @@ The exporter is configured via the following command line arguments:
| `-rpc-url` | Solana RPC URL (including protocol and path), e.g., `"http://localhost:8899"` or `"https://api.mainnet-beta.solana.com"` | `"http://localhost:8899"` |
| `-slot-pace` | This is the time (in seconds) between slot-watching metric collections | `1` |
| `-active-identity` | Validator identity public key used to determine if the node is considered active in the `solana_node_is_active` metric. | N/A |
+| `-epoch-cleanup-time` | The time to wait before cleaning old epoch metrics from the prometheus endpoint. | |
### Notes on Configuration
@@ -96,11 +148,6 @@ The tables below describes all the metrics collected by the `solana-exporter`:
| `solana_node_is_active` | Whether the node is active and participating in consensus. | `identity` |
| `solana_foundation_min_required_version` | Minimum required Solana version for the [solana foundation delegation program](https://solana.org/delegation-program) | `version`, `cluster` |
-#### Light Mode
-
-In `-light-mode`, the exporter will only track metrics that uniquely to the node being queried. These metric names
-all begin with `solana_node_*`.
-
#### Vote Account Metrics
The following metrics are all received from the `getVoteAccounts` [RPC endpoint](https://solana.com/docs/rpc/http/getvoteaccounts):
diff --git a/pkg/rpc/client.go b/pkg/rpc/client.go
index b8d5355..53c4ef7 100644
--- a/pkg/rpc/client.go
+++ b/pkg/rpc/client.go
@@ -45,13 +45,12 @@ const (
// CommitmentProcessed level represents a transaction that has been received by the network and included in a block.
CommitmentProcessed Commitment = "processed"
- // Genesis hashes for different Solana clusters
DevnetGenesisHash = "EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG"
TestnetGenesisHash = "4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY"
MainnetGenesisHash = "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d"
)
-// getClusterFromGenesisHash returns the cluster name based on the genesis hash
+// GetClusterFromGenesisHash returns the cluster name based on the genesis hash
func GetClusterFromGenesisHash(hash string) (string, error) {
switch hash {
case DevnetGenesisHash:
@@ -133,7 +132,6 @@ func (c *Client) GetEpochInfo(ctx context.Context, commitment Commitment) (*Epoc
func (c *Client) GetVoteAccounts(ctx context.Context, commitment Commitment) (*VoteAccounts, error) {
// format params:
config := map[string]string{"commitment": string(commitment)}
-
var resp Response[VoteAccounts]
if err := getResponse(ctx, c, "getVoteAccounts", []any{config}, &resp); err != nil {
return nil, err
@@ -186,7 +184,6 @@ func (c *Client) GetBlockProduction(
"commitment": string(commitment),
"range": map[string]int64{"firstSlot": firstSlot, "lastSlot": lastSlot},
}
-
// make request:
var resp Response[contextualResult[BlockProduction]]
if err := getResponse(ctx, c, "getBlockProduction", []any{config}, &resp); err != nil {
@@ -213,7 +210,6 @@ func (c *Client) GetInflationReward(
) ([]InflationReward, error) {
// format params:
config := map[string]any{"commitment": string(commitment), "epoch": epoch}
-
var resp Response[[]InflationReward]
if err := getResponse(ctx, c, "getInflationReward", []any{addresses, config}, &resp); err != nil {
return nil, err