From 98e0634edfe33540c3588b151f2dcef46873cc36 Mon Sep 17 00:00:00 2001 From: Robert Pirtle Date: Fri, 25 Aug 2023 12:23:53 -0700 Subject: [PATCH 1/2] feat(x/metrics): add module for emiting custom chain metrics (#1668) * initialize x/metrics with metrics collection * include global labels in x/metrics metrics * add x/metrics spec * add x/metrics test coverage * update changelog (cherry picked from commit 9a0aed7626582a50ac08bd69d8f43b98de8ae196) # Conflicts: # CHANGELOG.md # app/app.go # go.mod --- CHANGELOG.md | 72 ++++++++++++++++++ app/app.go | 44 +++++++++++ cmd/kava/cmd/app.go | 2 + go.mod | 29 ++++++++ x/metrics/abci.go | 12 +++ x/metrics/abci_test.go | 45 ++++++++++++ x/metrics/module.go | 125 ++++++++++++++++++++++++++++++++ x/metrics/spec/README.md | 36 +++++++++ x/metrics/types/keys.go | 6 ++ x/metrics/types/metrics.go | 89 +++++++++++++++++++++++ x/metrics/types/metrics_test.go | 72 ++++++++++++++++++ 11 files changed, 532 insertions(+) create mode 100644 x/metrics/abci.go create mode 100644 x/metrics/abci_test.go create mode 100644 x/metrics/module.go create mode 100644 x/metrics/spec/README.md create mode 100644 x/metrics/types/keys.go create mode 100644 x/metrics/types/metrics.go create mode 100644 x/metrics/types/metrics_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d875b2457..7acbe075eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,8 +36,16 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] +<<<<<<< HEAD ### State Machine Breaking [\#1158](https://github.com/Kava-Labs/kava/pull/1158) Split existing auction `bid_duration` parameter into `forward_bid_duration` and `reverse_bid_duration` +======= +### Features +- (metrics) [#1668] Adds non-state breaking x/metrics module for custom telemetry. + +### Bug Fixes +- (evmutil) [#1655] Initialize x/evmutil module account in InitGenesis +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) ## [v0.16.1](https://github.com/Kava-Labs/kava/releases/tag/v0.16.1) @@ -153,4 +161,68 @@ Bump tendermint version to 0.32.10 to address [cosmos security advisory Lavender ### Improvements +<<<<<<< HEAD [\#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run large-scale simulations remotely using aws-batch +======= +- [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run + large-scale simulations remotely using aws-batch + +[#1668]: https://github.com/Kava-Labs/kava/pull/1668 +[#1655]: https://github.com/Kava-Labs/kava/pull/1655 +[#1624]: https://github.com/Kava-Labs/kava/pull/1624 +[#1631]: https://github.com/Kava-Labs/kava/pull/1631 +[#1622]: https://github.com/Kava-Labs/kava/pull/1622 +[#1614]: https://github.com/Kava-Labs/kava/pull/1614 +[#1610]: https://github.com/Kava-Labs/kava/pull/1610 +[#1609]: https://github.com/Kava-Labs/kava/pull/1609 +[#1605]: https://github.com/Kava-Labs/kava/pull/1605 +[#1604]: https://github.com/Kava-Labs/kava/pull/1604 +[#1603]: https://github.com/Kava-Labs/kava/pull/1603 +[#1598]: https://github.com/Kava-Labs/kava/pull/1598 +[#1596]: https://github.com/Kava-Labs/kava/pull/1596 +[#1591]: https://github.com/Kava-Labs/kava/pull/1591 +[#1590]: https://github.com/Kava-Labs/kava/pull/1590 +[#1568]: https://github.com/Kava-Labs/kava/pull/1568 +[#1567]: https://github.com/Kava-Labs/kava/pull/1567 +[#1566]: https://github.com/Kava-Labs/kava/pull/1566 +[#1565]: https://github.com/Kava-Labs/kava/pull/1565 +[#1563]: https://github.com/Kava-Labs/kava/pull/1563 +[#1562]: https://github.com/Kava-Labs/kava/pull/1562 +[#1550]: https://github.com/Kava-Labs/kava/pull/1550 +[#1544]: https://github.com/Kava-Labs/kava/pull/1544 +[#1477]: https://github.com/Kava-Labs/kava/pull/1477 +[#1512]: https://github.com/Kava-Labs/kava/pull/1512 +[#1519]: https://github.com/Kava-Labs/kava/pull/1519 +[#1106]: https://github.com/Kava-Labs/kava/pull/1106 +[#1152]: https://github.com/Kava-Labs/kava/pull/1152 +[#1542]: https://github.com/Kava-Labs/kava/pull/1542 +[#253]: https://github.com/Kava-Labs/kava/pull/253 +[#260]: https://github.com/Kava-Labs/kava/pull/260 +[#266]: https://github.com/Kava-Labs/kava/pull/266 +[#364]: https://github.com/Kava-Labs/kava/pull/364 +[#590]: https://github.com/Kava-Labs/kava/pull/590 +[#591]: https://github.com/Kava-Labs/kava/pull/591 +[#596]: https://github.com/Kava-Labs/kava/pull/596 +[#598]: https://github.com/Kava-Labs/kava/pull/598 +[#625]: https://github.com/Kava-Labs/kava/pull/625 +[#701]: https://github.com/Kava-Labs/kava/pull/701 +[#750]: https://github.com/Kava-Labs/kava/pull/750 +[#751]: https://github.com/Kava-Labs/kava/pull/751 +[#780]: https://github.com/Kava-Labs/kava/pull/780 +[unreleased]: https://github.com/Kava-Labs/kava/compare/v0.24.0...HEAD +[v0.24.0]: https://github.com/Kava-Labs/kava/compare/v0.24.0...v0.23.2 +[v0.23.2]: https://github.com/Kava-Labs/kava/compare/v0.23.1...v0.23.2 +[v0.23.1]: https://github.com/Kava-Labs/kava/compare/v0.23.0...v0.23.1 +[v0.23.0]: https://github.com/Kava-Labs/kava/compare/v0.21.1...v0.23.0 +[v0.16.1]: https://github.com/Kava-Labs/kava/compare/v0.16.0...v0.16.1 +[v0.16.0]: https://github.com/Kava-Labs/kava/compare/v0.15.2...v0.16.0 +[v0.13.0]: https://github.com/Kava-Labs/kava/compare/v0.12.4...v0.13.0 +[v0.12.0]: https://github.com/Kava-Labs/kava/compare/v0.11.1...v0.12.0 +[v0.11.0]: https://github.com/Kava-Labs/kava/compare/v0.10.0...v0.11.0 +[v0.8.1]: https://github.com/Kava-Labs/kava/compare/v0.8.0...v0.8.1 +[v0.8.0]: https://github.com/Kava-Labs/kava/compare/v0.7.0...v0.8.0 +[v0.3.5]: https://github.com/Kava-Labs/kava/compare/v0.3.4...v0.3.5 +[v0.3.2]: https://github.com/Kava-Labs/kava/compare/v0.3.1...v0.3.2 +[v0.3.1]: https://github.com/Kava-Labs/kava/compare/v0.3.0...v0.3.1 +[v0.3.0]: https://github.com/Kava-Labs/kava/compare/v0.2.0...v0.3.0 +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) diff --git a/app/app.go b/app/app.go index e5e6c082ae..a041504fc7 100644 --- a/app/app.go +++ b/app/app.go @@ -126,6 +126,14 @@ import ( kavadistclient "github.com/kava-labs/kava/x/kavadist/client" kavadistkeeper "github.com/kava-labs/kava/x/kavadist/keeper" kavadisttypes "github.com/kava-labs/kava/x/kavadist/types" +<<<<<<< HEAD +======= + "github.com/kava-labs/kava/x/liquid" + liquidkeeper "github.com/kava-labs/kava/x/liquid/keeper" + liquidtypes "github.com/kava-labs/kava/x/liquid/types" + metrics "github.com/kava-labs/kava/x/metrics" + metricstypes "github.com/kava-labs/kava/x/metrics/types" +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) pricefeed "github.com/kava-labs/kava/x/pricefeed" pricefeedkeeper "github.com/kava-labs/kava/x/pricefeed/keeper" pricefeedtypes "github.com/kava-labs/kava/x/pricefeed/types" @@ -193,7 +201,16 @@ var ( savings.AppModuleBasic{}, validatorvesting.AppModuleBasic{}, evmutil.AppModuleBasic{}, +<<<<<<< HEAD bridge.AppModuleBasic{}, +======= + liquid.AppModuleBasic{}, + earn.AppModuleBasic{}, + router.AppModuleBasic{}, + mint.AppModuleBasic{}, + community.AppModuleBasic{}, + metrics.AppModuleBasic{}, +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) ) // module account permissions @@ -236,6 +253,7 @@ type Options struct { MempoolAuthAddresses []sdk.AccAddress EVMTrace string EVMMaxGasWanted uint64 + TelemetryOptions metricstypes.TelemetryOptions } // DefaultOptions is a sensible default Options value. @@ -696,11 +714,22 @@ func NewApp( incentive.NewAppModule(app.incentiveKeeper, app.accountKeeper, app.bankKeeper, app.cdpKeeper), evmutil.NewAppModule(app.evmutilKeeper, app.bankKeeper), savings.NewAppModule(app.savingsKeeper, app.accountKeeper, app.bankKeeper), +<<<<<<< HEAD bridge.NewAppModule(app.bridgeKeeper, app.accountKeeper), +======= + liquid.NewAppModule(app.liquidKeeper), + earn.NewAppModule(app.earnKeeper, app.accountKeeper, app.bankKeeper), + router.NewAppModule(app.routerKeeper), + // nil InflationCalculationFn, use SDK's default inflation function + mint.NewAppModule(appCodec, app.mintKeeper, app.accountKeeper, nil), + community.NewAppModule(app.communityKeeper, app.accountKeeper), + metrics.NewAppModule(options.TelemetryOptions), +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) ) // Warning: Some begin blockers must run before others. Ensure the dependencies are understood before modifying this list. app.mm.SetOrderBeginBlockers( + metricstypes.ModuleName, // Upgrade begin blocker runs migrations on the first block after an upgrade. It should run before any other module. upgradetypes.ModuleName, // Capability begin blocker runs non state changing initialization. @@ -782,7 +811,16 @@ func NewApp( authz.ModuleName, evmutiltypes.ModuleName, savingstypes.ModuleName, +<<<<<<< HEAD bridgetypes.ModuleName, +======= + liquidtypes.ModuleName, + earntypes.ModuleName, + routertypes.ModuleName, + minttypes.ModuleName, + communitytypes.ModuleName, + metricstypes.ModuleName, +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) ) // Warning: Some init genesis methods must run before others. Ensure the dependencies are understood before modifying this list @@ -821,6 +859,12 @@ func NewApp( paramstypes.ModuleName, upgradetypes.ModuleName, validatorvestingtypes.ModuleName, +<<<<<<< HEAD +======= + liquidtypes.ModuleName, + routertypes.ModuleName, + metricstypes.ModuleName, +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) ) app.mm.RegisterInvariants(&app.crisisKeeper) diff --git a/cmd/kava/cmd/app.go b/cmd/kava/cmd/app.go index 755d620c3f..317ad8e3d2 100644 --- a/cmd/kava/cmd/app.go +++ b/cmd/kava/cmd/app.go @@ -23,6 +23,7 @@ import ( "github.com/kava-labs/kava/app" "github.com/kava-labs/kava/app/params" + metricstypes "github.com/kava-labs/kava/x/metrics/types" ) const ( @@ -93,6 +94,7 @@ func (ac appCreator) newApp( MempoolAuthAddresses: mempoolAuthAddresses, EVMTrace: cast.ToString(appOpts.Get(ethermintflags.EVMTracer)), EVMMaxGasWanted: cast.ToUint64(appOpts.Get(ethermintflags.EVMMaxTxGasWanted)), + TelemetryOptions: metricstypes.TelemetryOptionsFromAppOpts(appOpts), }, baseapp.SetPruning(pruningOpts), baseapp.SetMinGasPrices(strings.Replace(cast.ToString(appOpts.Get(server.FlagMinGasPrices)), ";", ",", -1)), diff --git a/go.mod b/go.mod index 2f3ee0b12b..c05ebb4548 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,35 @@ module github.com/kava-labs/kava go 1.18 require ( +<<<<<<< HEAD github.com/cosmos/cosmos-proto v1.0.0-alpha6 github.com/cosmos/cosmos-sdk v0.45.9 github.com/cosmos/ibc-go/v3 v3.0.0 github.com/ethereum/go-ethereum v1.10.16 +======= + cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/math v1.0.0-beta.6.0.20230216172121-959ce49135e4 + github.com/cenkalti/backoff/v4 v4.1.3 + github.com/cosmos/cosmos-proto v1.0.0-beta.3 + github.com/cosmos/cosmos-sdk v0.46.11 + github.com/cosmos/go-bip39 v1.0.0 + github.com/cosmos/ibc-go/v6 v6.1.1 + github.com/ethereum/go-ethereum v1.10.26 + github.com/evmos/ethermint v0.21.0 + github.com/go-kit/kit v0.12.0 +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.2 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 +<<<<<<< HEAD github.com/kava-labs/kava-bridge v0.2.0 +======= + github.com/linxGnu/grocksdb v1.8.0 + github.com/pelletier/go-toml/v2 v2.0.6 + github.com/prometheus/client_golang v1.14.0 +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.5.0 github.com/stretchr/testify v1.8.0 @@ -62,7 +81,11 @@ require ( github.com/felixge/httpsnoop v1.0.1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect +<<<<<<< HEAD github.com/go-kit/kit v0.12.0 // indirect +======= + github.com/gin-gonic/gin v1.8.1 // indirect +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-ole/go-ole v1.2.5 // indirect @@ -113,10 +136,16 @@ require ( github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect +<<<<<<< HEAD github.com/prometheus/client_golang v1.12.2 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.34.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect +======= + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.40.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect +>>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) github.com/prometheus/tsdb v0.7.1 // indirect github.com/rakyll/statik v0.1.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect diff --git a/x/metrics/abci.go b/x/metrics/abci.go new file mode 100644 index 0000000000..14a77d717f --- /dev/null +++ b/x/metrics/abci.go @@ -0,0 +1,12 @@ +package metrics + +import ( + "github.com/kava-labs/kava/x/metrics/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// BeginBlocker publishes metrics at the start of each block. +func BeginBlocker(ctx sdk.Context, metrics *types.Metrics) { + metrics.LatestBlockHeight.Set(float64(ctx.BlockHeight())) +} diff --git a/x/metrics/abci_test.go b/x/metrics/abci_test.go new file mode 100644 index 0000000000..5ab542eea5 --- /dev/null +++ b/x/metrics/abci_test.go @@ -0,0 +1,45 @@ +package metrics_test + +import ( + "testing" + + kitmetrics "github.com/go-kit/kit/metrics" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/kava-labs/kava/app" + "github.com/kava-labs/kava/x/metrics" + "github.com/kava-labs/kava/x/metrics/types" +) + +type MockGauge struct { + value float64 +} + +func (mg *MockGauge) With(labelValues ...string) kitmetrics.Gauge { return mg } +func (mg *MockGauge) Set(value float64) { mg.value = value } +func (*MockGauge) Add(_ float64) {} + +func ctxWithHeight(height int64) sdk.Context { + tApp := app.NewTestApp() + tApp.InitializeFromGenesisStates() + return tApp.NewContext(false, tmproto.Header{Height: height}) +} + +func TestBeginBlockEmitsLatestHeight(t *testing.T) { + gauge := MockGauge{} + myMetrics := &types.Metrics{ + LatestBlockHeight: &gauge, + } + + metrics.BeginBlocker(ctxWithHeight(1), myMetrics) + require.EqualValues(t, 1, gauge.value) + + metrics.BeginBlocker(ctxWithHeight(100), myMetrics) + require.EqualValues(t, 100, gauge.value) + + metrics.BeginBlocker(ctxWithHeight(17e6), myMetrics) + require.EqualValues(t, 17e6, gauge.value) +} diff --git a/x/metrics/module.go b/x/metrics/module.go new file mode 100644 index 0000000000..3b74fad555 --- /dev/null +++ b/x/metrics/module.go @@ -0,0 +1,125 @@ +package metrics + +import ( + "encoding/json" + + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/kava-labs/kava/x/metrics/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic app module basics object +type AppModuleBasic struct{} + +// Name returns the module name +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec register module codec +// Deprecated: unused but necessary to fulfill AppModuleBasic interface +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} + +// DefaultGenesis default genesis state +func (AppModuleBasic) DefaultGenesis(_ codec.JSONCodec) json.RawMessage { + return []byte("{}") +} + +// ValidateGenesis module validate genesis +func (AppModuleBasic) ValidateGenesis(_ codec.JSONCodec, _ client.TxEncodingConfig, _ json.RawMessage) error { + return nil +} + +// RegisterInterfaces implements InterfaceModule.RegisterInterfaces +func (a AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. +func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} + +// GetTxCmd returns the root tx command for the module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return nil +} + +// GetQueryCmd returns no root query command for the module. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return nil +} + +//____________________________________________________________________________ + +// AppModule app module type +type AppModule struct { + AppModuleBasic + metrics *types.Metrics +} + +// NewAppModule creates a new AppModule object +func NewAppModule(telemetryOpts types.TelemetryOptions) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + metrics: types.NewMetrics(telemetryOpts), + } +} + +// Name module name +func (am AppModule) Name() string { + return am.AppModuleBasic.Name() +} + +// RegisterInvariants register module invariants +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// Route module message route name +// Deprecated: unused but necessary to fulfill AppModule interface +func (am AppModule) Route() sdk.Route { return sdk.Route{} } + +// QuerierRoute module querier route name +// Deprecated: unused but necessary to fulfill AppModule interface +func (AppModule) QuerierRoute() string { return types.ModuleName } + +// LegacyQuerierHandler returns no sdk.Querier. +// Deprecated: unused but necessary to fulfill AppModule interface +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { + return nil +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) {} + +// InitGenesis module init-genesis +func (am AppModule) InitGenesis(ctx sdk.Context, _ codec.JSONCodec, _ json.RawMessage) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ExportGenesis module export genesis +func (am AppModule) ExportGenesis(_ sdk.Context, cdc codec.JSONCodec) json.RawMessage { + return nil +} + +// BeginBlock module begin-block +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { + BeginBlocker(ctx, am.metrics) +} + +// EndBlock module end-block +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} diff --git a/x/metrics/spec/README.md b/x/metrics/spec/README.md new file mode 100644 index 0000000000..648ce38afc --- /dev/null +++ b/x/metrics/spec/README.md @@ -0,0 +1,36 @@ + + +# `metrics` + + +## Abstract + +`x/metrics` is a stateless module that does not affect consensus. It captures chain metrics and emits them when the `instrumentation.prometheus` option is enabled in `config.toml`. + +## Precision + +The metrics emitted by `x/metrics` are `float64`s. They use `github.com/go-kit/kit/metrics` Prometheus gauges. Cosmos-sdk's `telemetry` package was not used because, at the time of writing, it only supports `float32`s and so does not maintain accurate representations of ints larger than ~16.8M. With `float64`s, integers may be accurately represented up to ~9e15. + +## Metrics + +The following metrics are defined: +* `cometbft_blocksync_latest_block_height` - this emulates the blocksync `latest_block_height` metric in CometBFT v0.38+. The `cometbft` namespace comes from the `instrumentation.namespace` config.toml value. + +## Metric Labels + +All metrics emitted have the labels defined in app.toml's `telemetry.global-labels` field. This is the same field used by cosmos-sdk's `telemetry` package. + +example: +```toml +# app.toml +[telemetry] +global-labels = [ + ["chain_id", "kava_2222-10"], + ["my_label", "my_value"], +] +``` diff --git a/x/metrics/types/keys.go b/x/metrics/types/keys.go new file mode 100644 index 0000000000..c7a9577aba --- /dev/null +++ b/x/metrics/types/keys.go @@ -0,0 +1,6 @@ +package types + +const ( + // Name of the module + ModuleName = "metrics" +) diff --git a/x/metrics/types/metrics.go b/x/metrics/types/metrics.go new file mode 100644 index 0000000000..7c01e4745a --- /dev/null +++ b/x/metrics/types/metrics.go @@ -0,0 +1,89 @@ +package types + +import ( + "github.com/go-kit/kit/metrics" + "github.com/go-kit/kit/metrics/discard" + prometheus "github.com/go-kit/kit/metrics/prometheus" + stdprometheus "github.com/prometheus/client_golang/prometheus" + "github.com/spf13/cast" + + servertypes "github.com/cosmos/cosmos-sdk/server/types" +) + +// TelemetryOptions defines the app configurations for the x/metrics module +type TelemetryOptions struct { + // CometBFT config value for instrumentation.prometheus (config.toml) + PrometheusEnabled bool + // Namespace for CometBFT metrics. Used to emulate CometBFT metrics. + CometBFTMetricsNamespace string + // A list of keys and values used as labels on all metrics + GlobalLabelsAndValues []string +} + +// TelemetryOptionsFromAppOpts creates the TelemetryOptions from server AppOptions +func TelemetryOptionsFromAppOpts(appOpts servertypes.AppOptions) TelemetryOptions { + prometheusEnabled := cast.ToBool(appOpts.Get("instrumentation.prometheus")) + if !prometheusEnabled { + return TelemetryOptions{ + GlobalLabelsAndValues: []string{}, + } + } + + // parse the app.toml global-labels into a slice of alternating label & value strings + // the value is expected to be a list of [label, value] tuples. + rawLabels := cast.ToSlice(appOpts.Get("telemetry.global-labels")) + globalLabelsAndValues := make([]string, 0, len(rawLabels)*2) + for _, gl := range rawLabels { + l := cast.ToStringSlice(gl) + globalLabelsAndValues = append(globalLabelsAndValues, l[0], l[1]) + } + + return TelemetryOptions{ + PrometheusEnabled: true, + CometBFTMetricsNamespace: cast.ToString(appOpts.Get("instrumentation.namespace")), + GlobalLabelsAndValues: globalLabelsAndValues, + } +} + +// Metrics contains metrics exposed by this module. +// They use go-kit metrics like CometBFT as opposed to using cosmos-sdk telemetry +// because the sdk's telemetry only supports float32s, whereas go-kit prometheus +// metrics correctly handle float64s (and thus a larger number of int64s) +type Metrics struct { + // The height of the latest block. + // This gauges exactly emulates the default blocksync metric in CometBFT v0.38+ + // It should be removed when kava has been updated to CometBFT v0.38+. + // see https://github.com/cometbft/cometbft/blob/v0.38.0-rc3/blocksync/metrics.gen.go + LatestBlockHeight metrics.Gauge +} + +// NewMetrics creates a new Metrics object based on whether or not prometheus instrumentation is enabled. +func NewMetrics(opts TelemetryOptions) *Metrics { + if opts.PrometheusEnabled { + return PrometheusMetrics(opts) + } + return NoopMetrics() +} + +// PrometheusMetrics returns the gauges for when prometheus instrumentation is enabled. +func PrometheusMetrics(opts TelemetryOptions) *Metrics { + labels := []string{} + for i := 0; i < len(opts.GlobalLabelsAndValues); i += 2 { + labels = append(labels, opts.GlobalLabelsAndValues[i]) + } + return &Metrics{ + LatestBlockHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: opts.CometBFTMetricsNamespace, + Subsystem: "blocksync", + Name: "latest_block_height", + Help: "The height of the latest block.", + }, labels).With(opts.GlobalLabelsAndValues...), + } +} + +// NoopMetrics are a do-nothing placeholder used when prometheus instrumentation is not enabled. +func NoopMetrics() *Metrics { + return &Metrics{ + LatestBlockHeight: discard.NewGauge(), + } +} diff --git a/x/metrics/types/metrics_test.go b/x/metrics/types/metrics_test.go new file mode 100644 index 0000000000..2af68d2520 --- /dev/null +++ b/x/metrics/types/metrics_test.go @@ -0,0 +1,72 @@ +package types_test + +import ( + "testing" + + "github.com/go-kit/kit/metrics" + "github.com/go-kit/kit/metrics/prometheus" + "github.com/kava-labs/kava/x/metrics/types" + "github.com/stretchr/testify/require" +) + +func isPrometheusGauge(g metrics.Gauge) bool { + _, ok := g.(*prometheus.Gauge) + return ok +} + +var ( + disabledOpts = types.TelemetryOptions{ + PrometheusEnabled: false, + } + enabledOpts = types.TelemetryOptions{ + PrometheusEnabled: true, + CometBFTMetricsNamespace: "cometbft", + GlobalLabelsAndValues: []string{"label1", "value1", "label2", "value2"}, + } +) + +func TestNewMetrics_DisabledVsEnabled(t *testing.T) { + myMetrics := types.NewMetrics(disabledOpts) + require.False(t, isPrometheusGauge(myMetrics.LatestBlockHeight)) + + myMetrics = types.NewMetrics(enabledOpts) + require.True(t, isPrometheusGauge(myMetrics.LatestBlockHeight)) +} + +type MockAppOpts struct { + store map[string]interface{} +} + +func (mao *MockAppOpts) Get(key string) interface{} { + return mao.store[key] +} + +func TestTelemetryOptionsFromAppOpts(t *testing.T) { + appOpts := MockAppOpts{store: make(map[string]interface{})} + + // test disabled functionality + appOpts.store["instrumentation.prometheus"] = false + + opts := types.TelemetryOptionsFromAppOpts(&appOpts) + require.False(t, opts.PrometheusEnabled) + + // test enabled functionality + appOpts.store["instrumentation.prometheus"] = true + appOpts.store["instrumentation.namespace"] = "magic" + appOpts.store["telemetry.global-labels"] = []interface{}{} + + opts = types.TelemetryOptionsFromAppOpts(&appOpts) + require.True(t, opts.PrometheusEnabled) + require.Equal(t, "magic", opts.CometBFTMetricsNamespace) + require.Len(t, opts.GlobalLabelsAndValues, 0) + + appOpts.store["telemetry.global-labels"] = []interface{}{ + []interface{}{"label1", "value1"}, + []interface{}{"label2", "value2"}, + } + opts = types.TelemetryOptionsFromAppOpts(&appOpts) + require.True(t, opts.PrometheusEnabled) + require.Equal(t, "magic", opts.CometBFTMetricsNamespace) + require.Len(t, opts.GlobalLabelsAndValues, 4) + require.Equal(t, enabledOpts.GlobalLabelsAndValues, opts.GlobalLabelsAndValues) +} From 687b1fca280059a32c81f4a5e51adb6683a185f0 Mon Sep 17 00:00:00 2001 From: Robert Pirtle Date: Fri, 25 Aug 2023 13:18:53 -0700 Subject: [PATCH 2/2] fix merge conflicts, add docker-build command --- CHANGELOG.md | 99 +++++++++++++-------------------------------- Makefile | 3 ++ app/app.go | 36 ----------------- go.mod | 31 +------------- x/metrics/module.go | 7 ++++ 5 files changed, 38 insertions(+), 138 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7acbe075eb..27ff31c188 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,27 +36,44 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] -<<<<<<< HEAD -### State Machine Breaking -[\#1158](https://github.com/Kava-Labs/kava/pull/1158) Split existing auction `bid_duration` parameter into `forward_bid_duration` and `reverse_bid_duration` -======= -### Features - (metrics) [#1668] Adds non-state breaking x/metrics module for custom telemetry. -### Bug Fixes -- (evmutil) [#1655] Initialize x/evmutil module account in InitGenesis ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) +## [v0.18.2](https://github.com/Kava-Labs/kava/releases/tag/v0.18.2) + +* Update to go 1.18, cosmos v0.45.9, and tendermint v0.34.21 +* Update ci & docker to go 1.18 +* Config updates for iavl changes and broadcast mode flag +* Ensure fast node is disable if config value is not set in order to + avoid fast node upgrade for nodes that do not update their app.toml +* Update to new circle ci image instead of using legacy image +* Remove previous ics23 package -- now used directly from cosmos-sdk repo + +## [v0.18.1](https://github.com/Kava-Labs/kava/releases/tag/v0.18.1) + +Patch for IBC Security Advisory Dragonberry: https://forum.cosmos.network/t/ibc-security-advisory-dragonberry/7702 + +## [v0.18.0](https://github.com/Kava-Labs/kava/releases/tag/v0.18.0) + +Security upgrade patch release for kava 10. + +## [v0.17.3](https://github.com/Kava-Labs/kava/releases/tag/v0.17.3) + +Release of Kava EVM & the first binary with chain id `kava_2222-10`. + +See Release for full details: +* [v0.17.3](https://github.com/Kava-Labs/kava/releases/tag/v0.17.3) +* [v0.17.1](https://github.com/Kava-Labs/kava/releases/tag/v0.17.1) ## [v0.16.1](https://github.com/Kava-Labs/kava/releases/tag/v0.16.1) ### State Machine Breaking -[\#1152](https://github.com/Kava-Labs/kava/pull/1152) Fix MultiSpend Proposal With Async Upgrade Time +[\#1152](https://github.com/Kava-Labs/kava/pull/1152) Fix MultiSpend Proposal With Async Upgrade Time ## [v0.16.0](https://github.com/Kava-Labs/kava/releases/tag/v0.16.0) ### State Machine Breaking -[\#1106](https://github.com/Kava-Labs/kava/pull/1106) Upgrades app to cosmos-sdk v0.44.x and adds IBC and ICS-20 modules. +[\#1106](https://github.com/Kava-Labs/kava/pull/1106) Upgrades app to cosmos-sdk v0.44.x and adds IBC and ICS-20 modules. ## [v0.13.0] @@ -161,68 +178,6 @@ Bump tendermint version to 0.32.10 to address [cosmos security advisory Lavender ### Improvements -<<<<<<< HEAD [\#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run large-scale simulations remotely using aws-batch -======= -- [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run - large-scale simulations remotely using aws-batch [#1668]: https://github.com/Kava-Labs/kava/pull/1668 -[#1655]: https://github.com/Kava-Labs/kava/pull/1655 -[#1624]: https://github.com/Kava-Labs/kava/pull/1624 -[#1631]: https://github.com/Kava-Labs/kava/pull/1631 -[#1622]: https://github.com/Kava-Labs/kava/pull/1622 -[#1614]: https://github.com/Kava-Labs/kava/pull/1614 -[#1610]: https://github.com/Kava-Labs/kava/pull/1610 -[#1609]: https://github.com/Kava-Labs/kava/pull/1609 -[#1605]: https://github.com/Kava-Labs/kava/pull/1605 -[#1604]: https://github.com/Kava-Labs/kava/pull/1604 -[#1603]: https://github.com/Kava-Labs/kava/pull/1603 -[#1598]: https://github.com/Kava-Labs/kava/pull/1598 -[#1596]: https://github.com/Kava-Labs/kava/pull/1596 -[#1591]: https://github.com/Kava-Labs/kava/pull/1591 -[#1590]: https://github.com/Kava-Labs/kava/pull/1590 -[#1568]: https://github.com/Kava-Labs/kava/pull/1568 -[#1567]: https://github.com/Kava-Labs/kava/pull/1567 -[#1566]: https://github.com/Kava-Labs/kava/pull/1566 -[#1565]: https://github.com/Kava-Labs/kava/pull/1565 -[#1563]: https://github.com/Kava-Labs/kava/pull/1563 -[#1562]: https://github.com/Kava-Labs/kava/pull/1562 -[#1550]: https://github.com/Kava-Labs/kava/pull/1550 -[#1544]: https://github.com/Kava-Labs/kava/pull/1544 -[#1477]: https://github.com/Kava-Labs/kava/pull/1477 -[#1512]: https://github.com/Kava-Labs/kava/pull/1512 -[#1519]: https://github.com/Kava-Labs/kava/pull/1519 -[#1106]: https://github.com/Kava-Labs/kava/pull/1106 -[#1152]: https://github.com/Kava-Labs/kava/pull/1152 -[#1542]: https://github.com/Kava-Labs/kava/pull/1542 -[#253]: https://github.com/Kava-Labs/kava/pull/253 -[#260]: https://github.com/Kava-Labs/kava/pull/260 -[#266]: https://github.com/Kava-Labs/kava/pull/266 -[#364]: https://github.com/Kava-Labs/kava/pull/364 -[#590]: https://github.com/Kava-Labs/kava/pull/590 -[#591]: https://github.com/Kava-Labs/kava/pull/591 -[#596]: https://github.com/Kava-Labs/kava/pull/596 -[#598]: https://github.com/Kava-Labs/kava/pull/598 -[#625]: https://github.com/Kava-Labs/kava/pull/625 -[#701]: https://github.com/Kava-Labs/kava/pull/701 -[#750]: https://github.com/Kava-Labs/kava/pull/750 -[#751]: https://github.com/Kava-Labs/kava/pull/751 -[#780]: https://github.com/Kava-Labs/kava/pull/780 -[unreleased]: https://github.com/Kava-Labs/kava/compare/v0.24.0...HEAD -[v0.24.0]: https://github.com/Kava-Labs/kava/compare/v0.24.0...v0.23.2 -[v0.23.2]: https://github.com/Kava-Labs/kava/compare/v0.23.1...v0.23.2 -[v0.23.1]: https://github.com/Kava-Labs/kava/compare/v0.23.0...v0.23.1 -[v0.23.0]: https://github.com/Kava-Labs/kava/compare/v0.21.1...v0.23.0 -[v0.16.1]: https://github.com/Kava-Labs/kava/compare/v0.16.0...v0.16.1 -[v0.16.0]: https://github.com/Kava-Labs/kava/compare/v0.15.2...v0.16.0 -[v0.13.0]: https://github.com/Kava-Labs/kava/compare/v0.12.4...v0.13.0 -[v0.12.0]: https://github.com/Kava-Labs/kava/compare/v0.11.1...v0.12.0 -[v0.11.0]: https://github.com/Kava-Labs/kava/compare/v0.10.0...v0.11.0 -[v0.8.1]: https://github.com/Kava-Labs/kava/compare/v0.8.0...v0.8.1 -[v0.8.0]: https://github.com/Kava-Labs/kava/compare/v0.7.0...v0.8.0 -[v0.3.5]: https://github.com/Kava-Labs/kava/compare/v0.3.4...v0.3.5 -[v0.3.2]: https://github.com/Kava-Labs/kava/compare/v0.3.1...v0.3.2 -[v0.3.1]: https://github.com/Kava-Labs/kava/compare/v0.3.0...v0.3.1 -[v0.3.0]: https://github.com/Kava-Labs/kava/compare/v0.2.0...v0.3.0 ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) diff --git a/Makefile b/Makefile index 5acfc7435d..18f0c22c67 100644 --- a/Makefile +++ b/Makefile @@ -156,6 +156,9 @@ format: ### Localnet ### ############################################################################### +docker-build: + DOCKER_BUILDKIT=1 $(DOCKER) build -t kava/kava:local . + build-docker-local-kava: @$(MAKE) -C networks/local diff --git a/app/app.go b/app/app.go index a041504fc7..5a7922a5b9 100644 --- a/app/app.go +++ b/app/app.go @@ -126,14 +126,8 @@ import ( kavadistclient "github.com/kava-labs/kava/x/kavadist/client" kavadistkeeper "github.com/kava-labs/kava/x/kavadist/keeper" kavadisttypes "github.com/kava-labs/kava/x/kavadist/types" -<<<<<<< HEAD -======= - "github.com/kava-labs/kava/x/liquid" - liquidkeeper "github.com/kava-labs/kava/x/liquid/keeper" - liquidtypes "github.com/kava-labs/kava/x/liquid/types" metrics "github.com/kava-labs/kava/x/metrics" metricstypes "github.com/kava-labs/kava/x/metrics/types" ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) pricefeed "github.com/kava-labs/kava/x/pricefeed" pricefeedkeeper "github.com/kava-labs/kava/x/pricefeed/keeper" pricefeedtypes "github.com/kava-labs/kava/x/pricefeed/types" @@ -201,16 +195,8 @@ var ( savings.AppModuleBasic{}, validatorvesting.AppModuleBasic{}, evmutil.AppModuleBasic{}, -<<<<<<< HEAD bridge.AppModuleBasic{}, -======= - liquid.AppModuleBasic{}, - earn.AppModuleBasic{}, - router.AppModuleBasic{}, - mint.AppModuleBasic{}, - community.AppModuleBasic{}, metrics.AppModuleBasic{}, ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) ) // module account permissions @@ -714,17 +700,8 @@ func NewApp( incentive.NewAppModule(app.incentiveKeeper, app.accountKeeper, app.bankKeeper, app.cdpKeeper), evmutil.NewAppModule(app.evmutilKeeper, app.bankKeeper), savings.NewAppModule(app.savingsKeeper, app.accountKeeper, app.bankKeeper), -<<<<<<< HEAD bridge.NewAppModule(app.bridgeKeeper, app.accountKeeper), -======= - liquid.NewAppModule(app.liquidKeeper), - earn.NewAppModule(app.earnKeeper, app.accountKeeper, app.bankKeeper), - router.NewAppModule(app.routerKeeper), - // nil InflationCalculationFn, use SDK's default inflation function - mint.NewAppModule(appCodec, app.mintKeeper, app.accountKeeper, nil), - community.NewAppModule(app.communityKeeper, app.accountKeeper), metrics.NewAppModule(options.TelemetryOptions), ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) ) // Warning: Some begin blockers must run before others. Ensure the dependencies are understood before modifying this list. @@ -811,16 +788,8 @@ func NewApp( authz.ModuleName, evmutiltypes.ModuleName, savingstypes.ModuleName, -<<<<<<< HEAD bridgetypes.ModuleName, -======= - liquidtypes.ModuleName, - earntypes.ModuleName, - routertypes.ModuleName, - minttypes.ModuleName, - communitytypes.ModuleName, metricstypes.ModuleName, ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) ) // Warning: Some init genesis methods must run before others. Ensure the dependencies are understood before modifying this list @@ -859,12 +828,7 @@ func NewApp( paramstypes.ModuleName, upgradetypes.ModuleName, validatorvestingtypes.ModuleName, -<<<<<<< HEAD -======= - liquidtypes.ModuleName, - routertypes.ModuleName, metricstypes.ModuleName, ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) ) app.mm.RegisterInvariants(&app.crisisKeeper) diff --git a/go.mod b/go.mod index c05ebb4548..a63b666236 100644 --- a/go.mod +++ b/go.mod @@ -3,35 +3,18 @@ module github.com/kava-labs/kava go 1.18 require ( -<<<<<<< HEAD github.com/cosmos/cosmos-proto v1.0.0-alpha6 github.com/cosmos/cosmos-sdk v0.45.9 github.com/cosmos/ibc-go/v3 v3.0.0 github.com/ethereum/go-ethereum v1.10.16 -======= - cosmossdk.io/errors v1.0.0-beta.7 - cosmossdk.io/math v1.0.0-beta.6.0.20230216172121-959ce49135e4 - github.com/cenkalti/backoff/v4 v4.1.3 - github.com/cosmos/cosmos-proto v1.0.0-beta.3 - github.com/cosmos/cosmos-sdk v0.46.11 - github.com/cosmos/go-bip39 v1.0.0 - github.com/cosmos/ibc-go/v6 v6.1.1 - github.com/ethereum/go-ethereum v1.10.26 - github.com/evmos/ethermint v0.21.0 github.com/go-kit/kit v0.12.0 ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.2 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 -<<<<<<< HEAD github.com/kava-labs/kava-bridge v0.2.0 -======= - github.com/linxGnu/grocksdb v1.8.0 - github.com/pelletier/go-toml/v2 v2.0.6 - github.com/prometheus/client_golang v1.14.0 ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) + github.com/prometheus/client_golang v1.12.2 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.5.0 github.com/stretchr/testify v1.8.0 @@ -81,11 +64,6 @@ require ( github.com/felixge/httpsnoop v1.0.1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect -<<<<<<< HEAD - github.com/go-kit/kit v0.12.0 // indirect -======= - github.com/gin-gonic/gin v1.8.1 // indirect ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-ole/go-ole v1.2.5 // indirect @@ -136,16 +114,9 @@ require ( github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect -<<<<<<< HEAD - github.com/prometheus/client_golang v1.12.2 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.34.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect -======= - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.40.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect ->>>>>>> 9a0aed76 (feat(x/metrics): add module for emiting custom chain metrics (#1668)) github.com/prometheus/tsdb v0.7.1 // indirect github.com/rakyll/statik v0.1.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect diff --git a/x/metrics/module.go b/x/metrics/module.go index 3b74fad555..e2223c2335 100644 --- a/x/metrics/module.go +++ b/x/metrics/module.go @@ -3,6 +3,7 @@ package metrics import ( "encoding/json" + "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" @@ -25,6 +26,9 @@ var ( // AppModuleBasic app module basics object type AppModuleBasic struct{} +// RegisterRESTRoutes implements module.AppModuleBasic. +func (AppModuleBasic) RegisterRESTRoutes(client.Context, *mux.Router) {} + // Name returns the module name func (AppModuleBasic) Name() string { return types.ModuleName @@ -68,6 +72,9 @@ type AppModule struct { metrics *types.Metrics } +// RegisterRESTRoutes implements module.AppModule. +func (AppModule) RegisterRESTRoutes(client.Context, *mux.Router) {} + // NewAppModule creates a new AppModule object func NewAppModule(telemetryOpts types.TelemetryOptions) AppModule { return AppModule{