// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package raftboltdb import ( "context" "time" "github.com/boltdb/bolt" metrics "github.com/hashicorp/go-metrics/compat" ) const ( defaultMetricsInterval = 5 * time.Second ) // RunMetrics should be executed in a go routine and will periodically emit // metrics on the given interval until the context has been cancelled. func (b *BoltStore) RunMetrics(ctx context.Context, interval time.Duration) { if interval == 0 { interval = defaultMetricsInterval } tick := time.NewTicker(interval) defer tick.Stop() stats := b.emitMetrics(nil) for { select { case <-ctx.Done(): return case <-tick.C: stats = b.emitMetrics(stats) } } } func (b *BoltStore) emitMetrics(prev *bolt.Stats) *bolt.Stats { newStats := b.conn.Stats() stats := newStats if prev != nil { stats = newStats.Sub(prev) } // freelist metrics metrics.SetGauge([]string{"raft", "boltdb", "numFreePages"}, float32(newStats.FreePageN)) metrics.SetGauge([]string{"raft", "boltdb", "numPendingPages"}, float32(newStats.PendingPageN)) metrics.SetGauge([]string{"raft", "boltdb", "freePageBytes"}, float32(newStats.FreeAlloc)) metrics.SetGauge([]string{"raft", "boltdb", "freelistBytes"}, float32(newStats.FreelistInuse)) // txn metrics metrics.IncrCounter([]string{"raft", "boltdb", "totalReadTxn"}, float32(stats.TxN)) metrics.SetGauge([]string{"raft", "boltdb", "openReadTxn"}, float32(newStats.OpenTxN)) // tx stats metrics.SetGauge([]string{"raft", "boltdb", "txstats", "pageCount"}, float32(newStats.TxStats.PageCount)) metrics.SetGauge([]string{"raft", "boltdb", "txstats", "pageAlloc"}, float32(newStats.TxStats.PageAlloc)) metrics.IncrCounter([]string{"raft", "boltdb", "txstats", "cursorCount"}, float32(stats.TxStats.CursorCount)) metrics.IncrCounter([]string{"raft", "boltdb", "txstats", "nodeCount"}, float32(stats.TxStats.NodeCount)) metrics.IncrCounter([]string{"raft", "boltdb", "txstats", "nodeDeref"}, float32(stats.TxStats.NodeDeref)) metrics.IncrCounter([]string{"raft", "boltdb", "txstats", "rebalance"}, float32(stats.TxStats.Rebalance)) metrics.AddSample([]string{"raft", "boltdb", "txstats", "rebalanceTime"}, float32(stats.TxStats.RebalanceTime.Nanoseconds())/1000000) metrics.IncrCounter([]string{"raft", "boltdb", "txstats", "split"}, float32(stats.TxStats.Split)) metrics.IncrCounter([]string{"raft", "boltdb", "txstats", "spill"}, float32(stats.TxStats.Spill)) metrics.AddSample([]string{"raft", "boltdb", "txstats", "spillTime"}, float32(stats.TxStats.SpillTime.Nanoseconds())/1000000) metrics.IncrCounter([]string{"raft", "boltdb", "txstats", "write"}, float32(stats.TxStats.Write)) metrics.AddSample([]string{"raft", "boltdb", "txstats", "writeTime"}, float32(stats.TxStats.WriteTime.Nanoseconds())/1000000) return &newStats }