mirror of
https://github.com/cirocosta/monero-exporter.git
synced 2024-10-01 08:25:41 -04:00
debdce3fb2
this is a big refactor, essentially rewriting the custom collector from scratch, and as such, creating a new dashboard based on the new metrics. Signed-off-by: Ciro S. Costa <utxobr@protonmail.com>
301 lines
6.7 KiB
Go
301 lines
6.7 KiB
Go
package collector
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
"github.com/cirocosta/go-monero/pkg/constant"
|
|
"github.com/cirocosta/go-monero/pkg/rpc/daemon"
|
|
)
|
|
|
|
type LastBlockStatsCollector struct {
|
|
client *daemon.Client
|
|
metricsC chan<- prometheus.Metric
|
|
|
|
txns []*daemon.TransactionJSON
|
|
txnSizes []int
|
|
header daemon.BlockHeader
|
|
}
|
|
|
|
var _ CustomCollector = (*LastBlockStatsCollector)(nil)
|
|
|
|
func NewLastBlockStatsCollector(
|
|
client *daemon.Client, metricsC chan<- prometheus.Metric,
|
|
) *LastBlockStatsCollector {
|
|
return &LastBlockStatsCollector{
|
|
client: client,
|
|
metricsC: metricsC,
|
|
}
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) Name() string {
|
|
return "lastblock"
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) Collect(ctx context.Context) error {
|
|
err := c.fetchData(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("fetch last block data: %w", err)
|
|
}
|
|
|
|
c.collectBlockSize()
|
|
c.collectDifficulty()
|
|
c.collectFees()
|
|
c.collectHeight()
|
|
c.collectReward()
|
|
c.collectSubsidy()
|
|
c.collectTransactionsCount()
|
|
c.collectTransactionsFeePerKb()
|
|
c.collectTransactionsInputs()
|
|
c.collectTransactionsOutputs()
|
|
c.collectTransactionsSize()
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) fetchData(ctx context.Context) error {
|
|
lastBlockHeaderResp, err := c.client.GetLastBlockHeader(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("get last block header: %w", err)
|
|
}
|
|
|
|
lastBlockHash := lastBlockHeaderResp.BlockHeader.Hash
|
|
|
|
params := daemon.GetBlockRequestParameters{
|
|
Hash: lastBlockHash,
|
|
}
|
|
blockResp, err := c.client.GetBlock(ctx, params)
|
|
if err != nil {
|
|
return fmt.Errorf("get block '%s': %w", lastBlockHash, err)
|
|
}
|
|
|
|
blockJSON, err := blockResp.InnerJSON()
|
|
if err != nil {
|
|
return fmt.Errorf("block inner json: %w", err)
|
|
}
|
|
|
|
txnsResp, err := c.client.GetTransactions(ctx, blockJSON.TxHashes)
|
|
if err != nil {
|
|
return fmt.Errorf("get txns: %w", err)
|
|
}
|
|
|
|
txnSizes := make([]int, len(txnsResp.Txs))
|
|
for idx, t := range txnsResp.Txs {
|
|
txnSizes[idx] = len(t.AsHex) / 2
|
|
}
|
|
|
|
txns, err := txnsResp.GetTransactions()
|
|
if err != nil {
|
|
return fmt.Errorf("get transactions: %w", err)
|
|
}
|
|
|
|
c.txns = txns
|
|
c.txnSizes = txnSizes
|
|
c.header = blockResp.BlockHeader
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectBlockSize() {
|
|
desc := prometheus.NewDesc(
|
|
"monero_lastblock_size_bytes",
|
|
"total size of the last block",
|
|
nil, nil,
|
|
)
|
|
|
|
c.metricsC <- prometheus.MustNewConstMetric(
|
|
desc,
|
|
prometheus.GaugeValue,
|
|
float64(c.header.BlockSize),
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectDifficulty() {
|
|
desc := prometheus.NewDesc(
|
|
"monero_lastblock_difficulty",
|
|
"difficulty used for the last block",
|
|
nil, nil,
|
|
)
|
|
|
|
c.metricsC <- prometheus.MustNewConstMetric(
|
|
desc,
|
|
prometheus.GaugeValue,
|
|
float64(c.header.Difficulty),
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectFees() {
|
|
desc := prometheus.NewDesc(
|
|
"monero_lastblock_fees_monero",
|
|
"total amount of fees included in this block",
|
|
nil, nil,
|
|
)
|
|
|
|
c.metricsC <- prometheus.MustNewConstMetric(
|
|
desc,
|
|
prometheus.GaugeValue,
|
|
float64(c.gatherFees(c.txns))/constant.XMR,
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectHeight() {
|
|
desc := prometheus.NewDesc(
|
|
"monero_lastblock_height",
|
|
"height of the last block",
|
|
nil, nil,
|
|
)
|
|
|
|
c.metricsC <- prometheus.MustNewConstMetric(
|
|
desc,
|
|
prometheus.GaugeValue,
|
|
float64(c.header.Height),
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectReward() {
|
|
desc := prometheus.NewDesc(
|
|
"monero_lastblock_reward_monero",
|
|
"total amount of rewards granted in the last block "+
|
|
"(subsidy + fees)",
|
|
nil, nil,
|
|
)
|
|
|
|
c.metricsC <- prometheus.MustNewConstMetric(
|
|
desc,
|
|
prometheus.GaugeValue,
|
|
float64(c.header.Reward)/constant.XMR,
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectSubsidy() {
|
|
totalReward := float64(c.header.Reward)
|
|
fees := float64(c.gatherFees(c.txns))
|
|
subsidy := (totalReward - fees) / constant.XMR
|
|
|
|
desc := prometheus.NewDesc(
|
|
"monero_lastblock_subsidy_monero",
|
|
"newly minted monero for this block",
|
|
nil, nil,
|
|
)
|
|
|
|
c.metricsC <- prometheus.MustNewConstMetric(
|
|
desc,
|
|
prometheus.GaugeValue,
|
|
subsidy,
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectTransactionsCount() {
|
|
desc := prometheus.NewDesc(
|
|
"monero_lastblock_transactions",
|
|
"number of transactions seen in the last block",
|
|
nil, nil,
|
|
)
|
|
|
|
c.metricsC <- prometheus.MustNewConstMetric(
|
|
desc,
|
|
prometheus.GaugeValue,
|
|
float64(c.header.NumTxes),
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectTransactionsFeePerKb() {
|
|
summary := NewSummary()
|
|
for idx, txn := range c.txns {
|
|
fee := float64(txn.RctSignatures.Txnfee) / constant.MicroXMR
|
|
size := float64(c.txnSizes[idx]) / 1024
|
|
|
|
summary.Insert(fee / size)
|
|
}
|
|
|
|
c.metricsC <- prometheus.MustNewConstSummary(
|
|
prometheus.NewDesc(
|
|
"monero_lastblock_fees_micronero_per_kb",
|
|
"distribution of the feeperkb utilized for txns",
|
|
nil, nil,
|
|
),
|
|
summary.Count(), summary.Sum(), summary.Quantiles(),
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectTransactionsSize() {
|
|
summary := NewSummary()
|
|
for _, size := range c.txnSizes {
|
|
summary.Insert(float64(size))
|
|
}
|
|
|
|
c.metricsC <- prometheus.MustNewConstSummary(
|
|
prometheus.NewDesc(
|
|
"monero_lastblock_transactions_size_bytes",
|
|
"distribution of the size of the transactions included",
|
|
nil, nil,
|
|
),
|
|
summary.Count(), summary.Sum(), summary.Quantiles(),
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectTransactionsInputs() {
|
|
summary := NewSummary()
|
|
for _, txn := range c.txns {
|
|
summary.Insert(float64(len(txn.Vin)))
|
|
}
|
|
|
|
c.metricsC <- prometheus.MustNewConstSummary(
|
|
prometheus.NewDesc(
|
|
"monero_lastblock_transactions_inputs",
|
|
"distribution of inputs in the last block",
|
|
nil, nil,
|
|
),
|
|
summary.Count(), summary.Sum(), summary.Quantiles(),
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectTransactionsOutputs() {
|
|
summary := NewSummary()
|
|
for _, txn := range c.txns {
|
|
summary.Insert(float64(len(txn.Vout)))
|
|
}
|
|
|
|
c.metricsC <- prometheus.MustNewConstSummary(
|
|
prometheus.NewDesc(
|
|
"monero_lastblock_transactions_outputs",
|
|
"distribution of outputs in the last block",
|
|
nil, nil,
|
|
),
|
|
summary.Count(), summary.Sum(), summary.Quantiles(),
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) collectVersions() {
|
|
c.metricsC <- prometheus.MustNewConstMetric(
|
|
prometheus.NewDesc(
|
|
"monero_lastblock_version_major",
|
|
"major version of the block format",
|
|
nil, nil,
|
|
),
|
|
prometheus.GaugeValue,
|
|
float64(c.header.MajorVersion),
|
|
)
|
|
|
|
c.metricsC <- prometheus.MustNewConstMetric(
|
|
prometheus.NewDesc(
|
|
"monero_lastblock_version_minor",
|
|
"minor version of the block format",
|
|
nil, nil,
|
|
),
|
|
prometheus.GaugeValue,
|
|
float64(c.header.MinorVersion),
|
|
)
|
|
}
|
|
|
|
func (c *LastBlockStatsCollector) gatherFees(txns []*daemon.TransactionJSON) uint64 {
|
|
fees := uint64(0)
|
|
for _, txn := range txns {
|
|
fees += txn.RctSignatures.Txnfee
|
|
}
|
|
|
|
return fees
|
|
}
|