-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Record wallet metrics in the bus (#1458)
This PR adds a recorder in the bus that periodically records wallet metrics. Kept it simple, figured that is fine for now, couple of things I considered were: - expose the update interval - increasing interval and add a `Trigger` which we call on `FundTransaction`
- Loading branch information
Showing
11 changed files
with
142 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package bus | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
"time" | ||
|
||
"go.sia.tech/coreutils/wallet" | ||
"go.sia.tech/renterd/api" | ||
"go.uber.org/zap" | ||
) | ||
|
||
type ( | ||
WalletMetricsRecorder struct { | ||
store MetricsStore | ||
wallet WalletBalance | ||
|
||
shutdownChan chan struct{} | ||
wg sync.WaitGroup | ||
|
||
logger *zap.SugaredLogger | ||
} | ||
|
||
MetricsStore interface { | ||
RecordWalletMetric(ctx context.Context, metrics ...api.WalletMetric) error | ||
} | ||
|
||
WalletBalance interface { | ||
Balance() (wallet.Balance, error) | ||
} | ||
) | ||
|
||
// NewWalletMetricRecorder returns a recorder that periodically records wallet | ||
// metrics. The recorder is already running and can be stopped by calling | ||
// Shutdown. | ||
func NewWalletMetricRecorder(store MetricsStore, wallet WalletBalance, interval time.Duration, logger *zap.Logger) *WalletMetricsRecorder { | ||
logger = logger.Named("walletmetricsrecorder") | ||
recorder := &WalletMetricsRecorder{ | ||
store: store, | ||
wallet: wallet, | ||
shutdownChan: make(chan struct{}), | ||
logger: logger.Sugar(), | ||
} | ||
recorder.run(interval) | ||
return recorder | ||
} | ||
|
||
func (wmr *WalletMetricsRecorder) run(interval time.Duration) { | ||
wmr.wg.Add(1) | ||
go func() { | ||
defer wmr.wg.Done() | ||
|
||
t := time.NewTicker(interval) | ||
defer t.Stop() | ||
|
||
for { | ||
balance, err := wmr.wallet.Balance() | ||
if err != nil { | ||
wmr.logger.Error("failed to get wallet balance", zap.Error(err)) | ||
} else { | ||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) | ||
if err = wmr.store.RecordWalletMetric(ctx, api.WalletMetric{ | ||
Timestamp: api.TimeRFC3339(time.Now().UTC()), | ||
Spendable: balance.Spendable, | ||
Confirmed: balance.Confirmed, | ||
Unconfirmed: balance.Unconfirmed, | ||
Immature: balance.Immature, | ||
}); err != nil { | ||
wmr.logger.Error("failed to record wallet metric", zap.Error(err)) | ||
} else { | ||
wmr.logger.Debugw("successfully recorded wallet metrics", | ||
zap.Stringer("spendable", balance.Spendable), | ||
zap.Stringer("confirmed", balance.Confirmed), | ||
zap.Stringer("unconfirmed", balance.Unconfirmed), | ||
zap.Stringer("immature", balance.Immature)) | ||
} | ||
cancel() | ||
} | ||
|
||
select { | ||
case <-wmr.shutdownChan: | ||
return | ||
case <-t.C: | ||
} | ||
} | ||
}() | ||
} | ||
|
||
func (wmr *WalletMetricsRecorder) Shutdown(ctx context.Context) error { | ||
close(wmr.shutdownChan) | ||
|
||
waitChan := make(chan struct{}) | ||
go func() { | ||
wmr.wg.Wait() | ||
close(waitChan) | ||
}() | ||
|
||
select { | ||
case <-ctx.Done(): | ||
return context.Cause(ctx) | ||
case <-waitChan: | ||
return nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
stores/sql/mysql/migrations/metrics/migration_00002_idx_wallet_metrics_immature.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
ALTER TABLE `wallets` ADD COLUMN `immature_lo` bigint NOT NULL, ADD COLUMN `immature_hi` bigint NOT NULL; | ||
CREATE INDEX `idx_wallets_immature` ON `wallets`(`immature_lo`,`immature_hi`); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
stores/sql/sqlite/migrations/metrics/migration_00002_idx_wallet_metrics_immature.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
ALTER TABLE `wallets` ADD COLUMN `immature_lo` BIGINT NOT NULL, ADD COLUMN `immature_hi` BIGINT NOT NULL; | ||
CREATE INDEX `idx_wallets_immature` ON `wallets`(`immature_lo`,`immature_hi`); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters