diff --git a/contrib/local/02-contracts.sh b/contrib/local/02-contracts.sh index 8d33f8eeaf..4b4cc84d7f 100755 --- a/contrib/local/02-contracts.sh +++ b/contrib/local/02-contracts.sh @@ -6,7 +6,7 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" echo "-----------------------" echo "## Add new CosmWasm contract" RESP=$(wasmd tx wasm store "$DIR/../../x/wasm/internal/keeper/testdata/hackatom.wasm" \ - --from validator --gas 1000000 -y --chain-id=testing --node=http://localhost:26657 -b block) + --from validator --gas 1500000 -y --chain-id=testing --node=http://localhost:26657 -b block) CODE_ID=$(echo "$RESP" | jq -r '.logs[0].events[0].attributes[-1].value') echo "* Code id: $CODE_ID" diff --git a/contrib/local/03-grpc-queries.sh b/contrib/local/03-grpc-queries.sh index 23e78e6f44..f4bdf8f97f 100755 --- a/contrib/local/03-grpc-queries.sh +++ b/contrib/local/03-grpc-queries.sh @@ -7,12 +7,14 @@ echo "-----------------------" COSMOS_SDK_DIR=${COSMOS_SDK_DIR:-$(go list -f "{{ .Dir }}" -m github.com/cosmos/cosmos-sdk)} echo "### List all codes" -grpcurl -plaintext -import-path $COSMOS_SDK_DIR/third_party/proto -import-path $COSMOS_SDK_DIR/proto -import-path . -proto ./x/wasm/internal/types/query.proto \ - localhost:9090 cosmwasm.wasm.v1beta1.Query/Codes | jq +RESP=$(grpcurl -plaintext -import-path $COSMOS_SDK_DIR/third_party/proto -import-path $COSMOS_SDK_DIR/proto -import-path . -proto ./x/wasm/internal/types/query.proto \ + localhost:9090 cosmwasm.wasm.v1beta1.Query/Codes) +echo "$RESP" | jq +CODE_ID=$(echo "$RESP" | jq -r '.codeInfos[-1].codeId') echo "### List contract by code" RESP=$(grpcurl -plaintext -import-path $COSMOS_SDK_DIR/third_party/proto -import-path $COSMOS_SDK_DIR/proto -import-path . -proto ./x/wasm/internal/types/query.proto \ - -d '{"codeId":2}' localhost:9090 cosmwasm.wasm.v1beta1.Query/ContractsByCode ) + -d "{\"codeId\": $CODE_ID}" localhost:9090 cosmwasm.wasm.v1beta1.Query/ContractsByCode ) echo $RESP | jq echo "### Show history for contract" diff --git a/contrib/prometheus/README.md b/contrib/prometheus/README.md new file mode 100644 index 0000000000..7c8d36ea3a --- /dev/null +++ b/contrib/prometheus/README.md @@ -0,0 +1,47 @@ +# Setup +Enable prometheus metrics in wasmd: + +* Edit `$HOME/config/app.toml` +```toml +[telemetry] + +# Enabled enables the application telemetry functionality. When enabled, +# an in-memory sink is also enabled by default. Operators may also enabled +# other sinks such as Prometheus. +enabled =true +# ... + +# PrometheusRetentionTime, when positive, enables a Prometheus metrics sink. +prometheus-retention-time = 15 +``` + +`retention-time` must be >0 (see prometheus scrape config) + + + +* Edit `$HOME/config/config.toml` +```toml +[instrumentation] + +# When true, Prometheus metrics are served under /metrics on +# PrometheusListenAddr. +# Check out the documentation for the list of available metrics. +prometheus = true +``` +# Local testing +## Run Prometheus +```sh +# port 9090 is used by wasmd already +docker run -it -v $(pwd)/contrib/prometheus:/prometheus -p9091:9090 prom/prometheus --config.file=/prometheus/prometheus.yaml +``` +* Open [console](http://localhost:9091) and find `wasm_`service metrics + +## Run Grafana + +```shell +docker run -it -p 3000:3000 grafana/grafana +``` +* Add Prometheus data source +`http://host.docker.internal:9091` +### Labels +* `wasm_contract_create` = nanosec \ No newline at end of file diff --git a/contrib/prometheus/prometheus.yaml b/contrib/prometheus/prometheus.yaml new file mode 100644 index 0000000000..0f6d245287 --- /dev/null +++ b/contrib/prometheus/prometheus.yaml @@ -0,0 +1,11 @@ +global: + scrape_interval: 15s # By default, scrape targets every 15 seconds. + evaluation_interval: 15s # By default, scrape targets every 15 seconds. +rule_files: + +scrape_configs: +- job_name: wasmd + + scrape_interval: 5s + static_configs: + - targets: ['host.docker.internal:26660'] \ No newline at end of file diff --git a/x/wasm/internal/keeper/keeper.go b/x/wasm/internal/keeper/keeper.go index 206ab65545..9c46232317 100644 --- a/x/wasm/internal/keeper/keeper.go +++ b/x/wasm/internal/keeper/keeper.go @@ -4,20 +4,21 @@ import ( "bytes" "encoding/binary" "fmt" - abci "github.com/tendermint/tendermint/abci/types" - "path/filepath" - "github.com/CosmWasm/wasmd/x/wasm/internal/types" wasmvm "github.com/CosmWasm/wasmvm" wasmvmtypes "github.com/CosmWasm/wasmvm/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/log" + "path/filepath" + "time" ) // GasMultiplier is how many cosmwasm gas points = 1 sdk gas point @@ -228,6 +229,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A } func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins, authZ AuthorizationPolicy) (sdk.AccAddress, []byte, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "instantiate") if !k.IsPinnedCode(ctx, codeID) { ctx.GasMeter().ConsumeGas(InstanceCost, "Loading CosmWasm module: instantiate") } @@ -322,6 +324,7 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A // Execute executes the contract instance func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "execute") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) if err != nil { return nil, err @@ -371,6 +374,7 @@ func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller } func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, authZ AuthorizationPolicy) (*sdk.Result, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "migrate") if !k.IsPinnedCode(ctx, newCodeID) { ctx.GasMeter().ConsumeGas(InstanceCost, "Loading CosmWasm module: migrate") } @@ -444,6 +448,7 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller // another native Go module directly. Thus, the keeper doesn't place any access controls on it, that is the // responsibility or the app developer (who passes the wasm.Keeper in app.go) func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) (*sdk.Result, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "sudo") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) if err != nil { return nil, err @@ -578,6 +583,7 @@ func (k Keeper) GetContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress) // QuerySmart queries the smart contract itself. func (k Keeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "query-smart") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return nil, err @@ -600,6 +606,7 @@ func (k Keeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []b // QueryRaw returns the contract's state for give key. Returns `nil` when key is `nil`. func (k Keeper) QueryRaw(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "query-raw") if key == nil { return nil } diff --git a/x/wasm/internal/keeper/relay.go b/x/wasm/internal/keeper/relay.go index 0bdcd0d8c3..862e8ce5cb 100644 --- a/x/wasm/internal/keeper/relay.go +++ b/x/wasm/internal/keeper/relay.go @@ -3,8 +3,10 @@ package keeper import ( "github.com/CosmWasm/wasmd/x/wasm/internal/types" wasmvmtypes "github.com/CosmWasm/wasmvm/types" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "time" ) // OnOpenChannel calls the contract to participate in the IBC channel handshake step. @@ -17,6 +19,8 @@ func (k Keeper) OnOpenChannel( contractAddr sdk.AccAddress, channel wasmvmtypes.IBCChannel, ) error { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-open-channel") + _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return err @@ -47,6 +51,7 @@ func (k Keeper) OnConnectChannel( contractAddr sdk.AccAddress, channel wasmvmtypes.IBCChannel, ) error { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-connect-channel") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return err @@ -83,6 +88,8 @@ func (k Keeper) OnCloseChannel( contractAddr sdk.AccAddress, channel wasmvmtypes.IBCChannel, ) error { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-close-channel") + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return err @@ -119,6 +126,7 @@ func (k Keeper) OnRecvPacket( contractAddr sdk.AccAddress, packet wasmvmtypes.IBCPacket, ) ([]byte, error) { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-recv-packet") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return nil, err @@ -156,6 +164,7 @@ func (k Keeper) OnAckPacket( contractAddr sdk.AccAddress, acknowledgement wasmvmtypes.IBCAcknowledgement, ) error { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-ack-packet") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return err @@ -189,6 +198,8 @@ func (k Keeper) OnTimeoutPacket( contractAddr sdk.AccAddress, packet wasmvmtypes.IBCPacket, ) error { + defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-timeout-packet") + contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return err