diff --git a/contrib/images/evmd-env/wrapper.sh b/contrib/images/evmd-env/wrapper.sh index 9562acc7..5b03044f 100755 --- a/contrib/images/evmd-env/wrapper.sh +++ b/contrib/images/evmd-env/wrapper.sh @@ -12,6 +12,19 @@ fi export EVMDHOME="/data/node${ID}/evmd" +# Enable Prometheus metrics in CometBFT config +CONFIG_TOML="${EVMDHOME}/config/config.toml" +if [ -f "${CONFIG_TOML}" ]; then + sed -i 's/prometheus = false/prometheus = true/' "${CONFIG_TOML}" +fi + +# Enable SDK telemetry and set OTel instance ID +APP_TOML="${EVMDHOME}/config/app.toml" +if [ -f "${APP_TOML}" ]; then + sed -i '/^\[telemetry\]/,/^\[/ s/enabled = false/enabled = true/' "${APP_TOML}" + sed -i "s/instance-id = \"\"/instance-id = \"validator-${ID}\"/" "${APP_TOML}" +fi + if [ -d "$(dirname "${EVMDHOME}"/"${LOG}")" ]; then "${BINARY}" --home "${EVMDHOME}" "$@" | tee "${EVMDHOME}/${LOG}" else diff --git a/docker-compose.yml b/docker-compose.yml index c8372325..e44c4b69 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,7 +5,7 @@ services: container_name: evmdnode0 image: "cosmos/evmd" entrypoint: ["/usr/bin/wrapper.sh"] - command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3"] + command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3", "--metrics", "--otel.enable", "--otel.endpoint", "host.docker.internal:4317", "--otel.insecure"] environment: - DEBUG=0 - ID=0 @@ -16,10 +16,12 @@ services: - seccomp:unconfined ports: - "26656-26657:26656-26657" + - "26660:26660" - "1317:1317" - "9090:9090" - "2345:2345" - "6065:6065" + - "8100:8100" - "8545-8546:8545-8546" volumes: - ./.testnets:/data:Z @@ -31,7 +33,7 @@ services: container_name: evmdnode1 image: "cosmos/evmd" entrypoint: ["/usr/bin/wrapper.sh"] - command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3"] + command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3", "--metrics", "--otel.enable", "--otel.endpoint", "host.docker.internal:4317", "--otel.insecure"] environment: - DEBUG=0 - ID=1 @@ -42,10 +44,12 @@ services: - seccomp:unconfined ports: - "26666-26667:26656-26657" + - "26661:26660" - "1318:1317" - "9091:9090" - "2346:2345" - "6075:6065" + - "8101:8100" - "8555-8556:8545-8546" volumes: - ./.testnets:/data:Z @@ -57,7 +61,7 @@ services: container_name: evmdnode2 image: "cosmos/evmd" entrypoint: ["/usr/bin/wrapper.sh"] - command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3"] + command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3", "--metrics", "--otel.enable", "--otel.endpoint", "host.docker.internal:4317", "--otel.insecure"] environment: - DEBUG=0 - ID=2 @@ -68,10 +72,12 @@ services: - seccomp:unconfined ports: - "26676-26677:26656-26657" + - "26662:26660" - "1319:1317" - "9092:9090" - "2347:2345" - "6085:6065" + - "8102:8100" - "8565-8566:8545-8546" volumes: - ./.testnets:/data:Z @@ -83,7 +89,7 @@ services: container_name: evmdnode3 image: "cosmos/evmd" entrypoint: ["/usr/bin/wrapper.sh"] - command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3"] + command: ["start", "--chain-id", "local-4221", "--json-rpc.api", "eth,txpool,personal,net,debug,web3", "--metrics", "--otel.enable", "--otel.endpoint", "host.docker.internal:4317", "--otel.insecure"] environment: - DEBUG=0 - ID=3 @@ -94,10 +100,12 @@ services: - seccomp:unconfined ports: - "26686-26687:26656-26657" + - "26663:26660" - "1320:1317" - "9093:9090" - "2348:2345" - "6095:6065" + - "8103:8100" - "8575-8576:8545-8546" volumes: - ./.testnets:/data:Z diff --git a/evmd/config/config.go b/evmd/config/config.go index 37161612..5d471b06 100644 --- a/evmd/config/config.go +++ b/evmd/config/config.go @@ -42,6 +42,7 @@ func InitAppConfig(denom string, evmChainID uint64) (string, interface{}) { EVM: *evmCfg, JSONRPC: *cosmosevmserverconfig.DefaultJSONRPCConfig(), TLS: *cosmosevmserverconfig.DefaultTLSConfig(), + OTel: *cosmosevmserverconfig.DefaultOTelConfig(), } return EVMAppTemplate, customAppConfig @@ -53,6 +54,7 @@ type EVMAppConfig struct { EVM cosmosevmserverconfig.EVMConfig JSONRPC cosmosevmserverconfig.JSONRPCConfig TLS cosmosevmserverconfig.TLSConfig + OTel cosmosevmserverconfig.OTelConfig } const EVMAppTemplate = serverconfig.DefaultConfigTemplate + cosmosevmserverconfig.DefaultEVMConfigTemplate diff --git a/evmd/go.mod b/evmd/go.mod index 5cccc0d6..6d378a74 100644 --- a/evmd/go.mod +++ b/evmd/go.mod @@ -30,11 +30,11 @@ require ( github.com/stretchr/testify v1.11.1 github.com/xrplevm/node/v10 v10.0.3 golang.org/x/sync v0.19.0 - google.golang.org/grpc v1.78.0 + google.golang.org/grpc v1.79.2 ) require ( - cel.dev/expr v0.24.0 // indirect + cel.dev/expr v0.25.1 // indirect cloud.google.com/go v0.123.0 // indirect cloud.google.com/go/auth v0.17.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect @@ -91,7 +91,7 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cloudwego/base64x v0.1.6 // indirect - github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f // indirect + github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/errors v1.12.0 // indirect github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 // indirect @@ -125,8 +125,8 @@ require ( github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/ebitengine/purego v0.9.1 // indirect github.com/emicklei/dot v1.8.0 // indirect - github.com/envoyproxy/go-control-plane/envoy v1.35.0 // indirect - github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect + github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect + github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect github.com/ethereum/go-verkle v0.2.2 // indirect github.com/fatih/color v1.18.0 // indirect @@ -165,7 +165,7 @@ require ( github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.70 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -259,7 +259,7 @@ require ( github.com/zondax/ledger-go v1.0.1 // indirect go.etcd.io/bbolt v1.4.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/detectors/gcp v1.38.0 // indirect + go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 // indirect go.opentelemetry.io/contrib/instrumentation/host v0.64.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect @@ -267,24 +267,24 @@ require ( go.opentelemetry.io/contrib/otelconf v0.19.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.39.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.39.0 // indirect - go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.61.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 // indirect go.opentelemetry.io/otel/log v0.15.0 // indirect - go.opentelemetry.io/otel/metric v1.39.0 // indirect - go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect go.opentelemetry.io/otel/sdk/log v0.15.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect - go.opentelemetry.io/otel/trace v1.39.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/mock v0.6.0 // indirect @@ -293,19 +293,19 @@ require ( go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.21.0 // indirect - golang.org/x/crypto v0.47.0 // indirect + golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect - golang.org/x/net v0.48.0 // indirect - golang.org/x/oauth2 v0.34.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/term v0.39.0 // indirect - golang.org/x/text v0.33.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/oauth2 v0.35.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/term v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.40.0 // indirect + golang.org/x/tools v0.41.0 // indirect google.golang.org/api v0.256.0 // indirect google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/evmd/go.sum b/evmd/go.sum index d303a32f..a586b875 100644 --- a/evmd/go.sum +++ b/evmd/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= @@ -236,8 +236,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0= -github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -372,15 +372,15 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM= -github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329/go.mod h1:Alz8LEClvR7xKsrq3qzoc4N0guvVNSS8KmSChGYr9hs= -github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo= -github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= +github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= +github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= +github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= -github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4= +github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= @@ -561,8 +561,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.70 h1:0HADrxxqaQkGycO1JoUUA+B4FnIkuo8d2bz/hSaTFFQ= @@ -1044,8 +1044,8 @@ go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY6LiIY9I8cUfm+pJs= -go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70= go.opentelemetry.io/contrib/instrumentation/host v0.64.0 h1:/o7fG3CXOlVK8fUzK+p8CyHU9Opha3IL4DZR3UXGZ1w= @@ -1060,8 +1060,8 @@ go.opentelemetry.io/contrib/propagators/b3 v1.39.0 h1:PI7pt9pkSnimWcp5sQhUA9OzLb go.opentelemetry.io/contrib/propagators/b3 v1.39.0/go.mod h1:5gV/EzPnfYIwjzj+6y8tbGW2PKWhcsz5e/7twptRVQY= go.opentelemetry.io/contrib/propagators/jaeger v1.39.0 h1:Gz3yKzfMSEFzF0Vy5eIpu9ndpo4DhXMCxsLMF0OOApo= go.opentelemetry.io/contrib/propagators/jaeger v1.39.0/go.mod h1:2D/cxxCqTlrday0rZrPujjg5aoAdqk1NaNyoXn8FJn8= -go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= -go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0 h1:W+m0g+/6v3pa5PgVf2xoFMi5YtNR06WtS7ve5pcvLtM= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0/go.mod h1:JM31r0GGZ/GU94mX8hN4D8v6e40aFlUECSQ48HaLgHM= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0 h1:EKpiGphOYq3CYnIe2eX9ftUkyU+Y8Dtte8OaWyHJ4+I= @@ -1070,10 +1070,10 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 h1:cEf go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0/go.mod h1:k1lzV5n5U3HkGvTCJHraTAGJ7MqsgL1wrGwTj1Isfiw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 h1:nKP4Z2ejtHn3yShBb+2KawiXgpn8In5cT7aO2wXuOTE= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0/go.mod h1:NwjeBbNigsO4Aj9WgM0C+cKIrxsZUaRmZUO7A8I7u8o= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= go.opentelemetry.io/otel/exporters/prometheus v0.61.0 h1:cCyZS4dr67d30uDyh8etKM2QyDsQ4zC9ds3bdbrVoD0= @@ -1086,18 +1086,18 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 h1:8UPA4IbVZxpsD76 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0/go.mod h1:MZ1T/+51uIVKlRzGw1Fo46KEWThjlCBZKl2LzY5nv4g= go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY= go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4= -go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= -go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= go.opentelemetry.io/otel/sdk/log/logtest v0.15.0 h1:O+dZyt9riqVDKZwFRFn9zVdUKam3uwLMud+poHRssd4= go.opentelemetry.io/otel/sdk/log/logtest v0.15.0/go.mod h1:j7aD3tWSt3KlzWz5G+9loktEng6udEY868Kc2XDzdII= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= -go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= -go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= @@ -1145,8 +1145,8 @@ golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= @@ -1201,13 +1201,13 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= -golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1284,8 +1284,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -1293,8 +1293,8 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= -golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1306,8 +1306,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= @@ -1333,8 +1333,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= -golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1360,10 +1360,10 @@ google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9 h1:LvZVVaPE0JSqL+ZWb6ErZfnEOKIqqFWUJE2D0fObSmc= google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9/go.mod h1:QFOrLhdAe2PsTp3vQY4quuLKTi9j3XG3r6JPPaw7MSc= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1381,8 +1381,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= -google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= +google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/go.mod b/go.mod index 114891fd..c0c1edc9 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,6 @@ require ( github.com/gorilla/mux v1.8.1 github.com/gorilla/websocket v1.5.3 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/hashicorp/go-metrics v0.5.4 github.com/holiman/uint256 v1.3.2 github.com/improbable-eng/grpc-web v0.15.0 github.com/linxGnu/grocksdb v1.10.3 @@ -50,21 +49,26 @@ require ( github.com/xrplevm/node/v10 v10.0.3 github.com/zondax/hid v0.9.2 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 - go.opentelemetry.io/otel v1.39.0 - go.opentelemetry.io/otel/trace v1.39.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 + go.opentelemetry.io/otel/metric v1.42.0 + go.opentelemetry.io/otel/sdk v1.42.0 + go.opentelemetry.io/otel/sdk/metric v1.42.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/mock v0.6.0 - golang.org/x/crypto v0.47.0 - golang.org/x/net v0.48.0 + golang.org/x/crypto v0.48.0 + golang.org/x/net v0.51.0 golang.org/x/sync v0.19.0 - golang.org/x/text v0.33.0 - google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 - google.golang.org/grpc v1.78.0 + golang.org/x/text v0.34.0 + google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 + google.golang.org/grpc v1.79.2 google.golang.org/protobuf v1.36.11 sigs.k8s.io/yaml v1.6.0 ) require ( - cel.dev/expr v0.24.0 // indirect + cel.dev/expr v0.25.1 // indirect cloud.google.com/go v0.123.0 // indirect cloud.google.com/go/auth v0.17.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect @@ -119,7 +123,7 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cloudwego/base64x v0.1.6 // indirect - github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f // indirect + github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect github.com/cockroachdb/errors v1.12.0 // indirect github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 // indirect github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 // indirect @@ -145,8 +149,8 @@ require ( github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/ebitengine/purego v0.9.1 // indirect github.com/emicklei/dot v1.8.0 // indirect - github.com/envoyproxy/go-control-plane/envoy v1.35.0 // indirect - github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect + github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect + github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect github.com/ethereum/go-verkle v0.2.2 // indirect github.com/fatih/color v1.18.0 // indirect @@ -178,13 +182,14 @@ require ( github.com/googleapis/gax-go/v2 v2.15.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.70 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-getter v1.8.4 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-metrics v0.5.4 // indirect github.com/hashicorp/go-plugin v1.7.0 // indirect github.com/hashicorp/go-version v1.8.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -263,7 +268,7 @@ require ( github.com/zondax/ledger-go v1.0.1 // indirect go.etcd.io/bbolt v1.4.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/detectors/gcp v1.38.0 // indirect + go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect go.opentelemetry.io/contrib/instrumentation/host v0.64.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect go.opentelemetry.io/contrib/instrumentation/runtime v0.64.0 // indirect @@ -272,20 +277,15 @@ require ( go.opentelemetry.io/contrib/propagators/jaeger v1.39.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.61.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 // indirect go.opentelemetry.io/otel/log v0.15.0 // indirect - go.opentelemetry.io/otel/metric v1.39.0 // indirect - go.opentelemetry.io/otel/sdk v1.39.0 // indirect go.opentelemetry.io/otel/sdk/log v0.15.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -294,14 +294,14 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.21.0 // indirect golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect - golang.org/x/oauth2 v0.34.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/term v0.39.0 // indirect + golang.org/x/oauth2 v0.35.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/term v0.40.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.40.0 // indirect + golang.org/x/tools v0.41.0 // indirect google.golang.org/api v0.256.0 // indirect google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.2 // indirect diff --git a/go.sum b/go.sum index 3b72ff3f..795133dd 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= @@ -231,8 +231,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0= -github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -359,15 +359,15 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM= -github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329/go.mod h1:Alz8LEClvR7xKsrq3qzoc4N0guvVNSS8KmSChGYr9hs= -github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo= -github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= +github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= +github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= +github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= -github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4= +github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= @@ -545,8 +545,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.70 h1:0HADrxxqaQkGycO1JoUUA+B4FnIkuo8d2bz/hSaTFFQ= @@ -1024,8 +1024,8 @@ go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY6LiIY9I8cUfm+pJs= -go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70= go.opentelemetry.io/contrib/instrumentation/host v0.64.0 h1:/o7fG3CXOlVK8fUzK+p8CyHU9Opha3IL4DZR3UXGZ1w= @@ -1040,8 +1040,8 @@ go.opentelemetry.io/contrib/propagators/b3 v1.39.0 h1:PI7pt9pkSnimWcp5sQhUA9OzLb go.opentelemetry.io/contrib/propagators/b3 v1.39.0/go.mod h1:5gV/EzPnfYIwjzj+6y8tbGW2PKWhcsz5e/7twptRVQY= go.opentelemetry.io/contrib/propagators/jaeger v1.39.0 h1:Gz3yKzfMSEFzF0Vy5eIpu9ndpo4DhXMCxsLMF0OOApo= go.opentelemetry.io/contrib/propagators/jaeger v1.39.0/go.mod h1:2D/cxxCqTlrday0rZrPujjg5aoAdqk1NaNyoXn8FJn8= -go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= -go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0 h1:W+m0g+/6v3pa5PgVf2xoFMi5YtNR06WtS7ve5pcvLtM= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0/go.mod h1:JM31r0GGZ/GU94mX8hN4D8v6e40aFlUECSQ48HaLgHM= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0 h1:EKpiGphOYq3CYnIe2eX9ftUkyU+Y8Dtte8OaWyHJ4+I= @@ -1050,10 +1050,10 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 h1:cEf go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0/go.mod h1:k1lzV5n5U3HkGvTCJHraTAGJ7MqsgL1wrGwTj1Isfiw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 h1:nKP4Z2ejtHn3yShBb+2KawiXgpn8In5cT7aO2wXuOTE= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0/go.mod h1:NwjeBbNigsO4Aj9WgM0C+cKIrxsZUaRmZUO7A8I7u8o= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= go.opentelemetry.io/otel/exporters/prometheus v0.61.0 h1:cCyZS4dr67d30uDyh8etKM2QyDsQ4zC9ds3bdbrVoD0= @@ -1066,18 +1066,18 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 h1:8UPA4IbVZxpsD76 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0/go.mod h1:MZ1T/+51uIVKlRzGw1Fo46KEWThjlCBZKl2LzY5nv4g= go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY= go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4= -go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= -go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= go.opentelemetry.io/otel/sdk/log/logtest v0.15.0 h1:O+dZyt9riqVDKZwFRFn9zVdUKam3uwLMud+poHRssd4= go.opentelemetry.io/otel/sdk/log/logtest v0.15.0/go.mod h1:j7aD3tWSt3KlzWz5G+9loktEng6udEY868Kc2XDzdII= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= -go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= -go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= @@ -1125,8 +1125,8 @@ golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= @@ -1181,13 +1181,13 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= -golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1264,8 +1264,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -1273,8 +1273,8 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= -golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1286,8 +1286,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= @@ -1313,8 +1313,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= -golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1340,10 +1340,10 @@ google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9 h1:LvZVVaPE0JSqL+ZWb6ErZfnEOKIqqFWUJE2D0fObSmc= google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9/go.mod h1:QFOrLhdAe2PsTp3vQY4quuLKTi9j3XG3r6JPPaw7MSc= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1361,8 +1361,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= -google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= +google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/local_node.sh b/local_node.sh index 1f4d4c32..1ae247e2 100755 --- a/local_node.sh +++ b/local_node.sh @@ -338,6 +338,11 @@ jq '.app_state["evm"]["params"]["active_static_precompiles"]=["0x000000000000000 fi # Start the node +OTEL_ARGS="" +if [[ "${OTEL_ENABLE:-false}" == "true" ]]; then + OTEL_ARGS="--otel.enable --otel.endpoint ${OTEL_ENDPOINT:-localhost:4317} --otel.insecure" +fi + evmd start "$TRACE" \ --pruning nothing \ --log_level $LOGLEVEL \ @@ -345,4 +350,5 @@ evmd start "$TRACE" \ --evm.min-tip=0 \ --home "$CHAINDIR" \ --json-rpc.api eth,txpool,personal,net,debug,web3 \ - --chain-id "$CHAINID" + --chain-id "$CHAINID" \ + $OTEL_ARGS diff --git a/monitoring/README.md b/monitoring/README.md new file mode 100644 index 00000000..c15ef172 --- /dev/null +++ b/monitoring/README.md @@ -0,0 +1,277 @@ +# og-evm Observability + +Production-grade monitoring and tracing for og-evm validator and full nodes using Prometheus, Grafana, Tempo, and OpenTelemetry. + +## Architecture + +``` +og-evm node(s) + ├── :26660/metrics ──→ Prometheus (scrape) ──→ Grafana dashboards + alerts + ├── :8100/metrics ──→ Prometheus (scrape) ──→ Grafana dashboards + alerts + ├── :6065/debug/metrics ──→ Prometheus (scrape) + └── OTel SDK ──→ :4317 OTel Collector ──┬→ Tempo (traces) + └→ Prometheus (metrics via remote write) +node-exporter (:9100) ──→ Prometheus (scrape) ──→ Infrastructure metrics +``` + +Two pillars of observability: +- **Metrics** — Prometheus scrapes CometBFT, Geth, JSON-RPC, and node-exporter metrics. OTel custom metrics and Cosmos SDK telemetry flow through the OTel Collector +- **Traces** — OpenTelemetry SDK exports spans (EthereumTx, BeginBlock, etc.) via OTLP gRPC to Tempo + +## Prerequisites + +- Docker and Docker Compose +- A running `evmd` node (built with OTel support) + +## Deployment + +### 1. Start the monitoring stack + +```bash +cd monitoring +docker compose up -d +``` + +### 2. Configure your node + +Enable the following in your node's `config.toml`: + +```toml +[instrumentation] +prometheus = true +prometheus_listen_addr = ":26660" +``` + +Enable OpenTelemetry in `app.toml`: + +```toml +[otel] +enable = true +endpoint = ":4317" +insecure = true +``` + +Or pass as CLI flags when starting the node: + +```bash +evmd start \ + --otel.enable \ + --otel.endpoint :4317 \ + --otel.insecure \ + --otel.chain-id \ + --otel.instance-id \ + --metrics +``` + +### 3. Register your node as a Prometheus target + +Add your node to `prometheus/targets/og-evm-nodes.json`: + +```json +[ + { + "targets": [":26660"], + "labels": { + "chain_id": "og-evm-mainnet", + "instance": "validator-0" + } + } +] +``` + +Prometheus reloads target files every 30s — no restart needed. Add additional nodes as separate entries. + +### 4. Access Grafana + +Open `http://:3000` (default credentials: `admin` / `admin`). + +Change the admin password on first login for production deployments. + +## Services + +| Service | Port | Purpose | +|---------|------|---------| +| Prometheus | 9099 | Metrics storage, alerting, and PromQL queries | +| Grafana | 3000 | Dashboards, trace exploration, and alert management | +| OTel Collector | 4317 (gRPC) / 4318 (HTTP) | Receives OTLP traces and metrics from nodes | +| Tempo | 3200 | Distributed trace storage with span metrics generation | +| node-exporter | 9100 | Host infrastructure metrics (CPU, memory, disk, network) | + +## Metrics Collected + +### CometBFT (port 26660) + +Consensus, P2P, mempool, and block production metrics. Key metrics: + +| Metric | Description | +|--------|-------------| +| `cometbft_consensus_height` | Current block height | +| `cometbft_consensus_validators` | Active / missing / byzantine validator counts | +| `cometbft_consensus_block_interval_seconds` | Time between blocks (histogram) | +| `cometbft_consensus_rounds` | Consensus rounds per height | +| `cometbft_p2p_peers` | Connected peer count | +| `cometbft_consensus_total_txs` | Cumulative transaction count | + +### Geth / EVM (port 8100) + +Go-Ethereum internals — state reads, cache hits, and EVM execution metrics. + +### OTel span-derived metrics (via Tempo metrics generator) + +Tempo automatically generates RED (Rate, Error, Duration) metrics from ingested traces: + +| Metric | Description | +|--------|-------------| +| `traces_spanmetrics_calls_total` | Request rate per span name | +| `traces_spanmetrics_latency_bucket` | Latency histogram per span name | +| `traces_service_graph_*` | Service-to-service dependency metrics | + +## OTel Configuration Reference + +| Flag | `app.toml` key | Default | Description | +|------|----------------|---------|-------------| +| `--otel.enable` | `otel.enable` | `false` | Enable trace and metric export | +| `--otel.endpoint` | `otel.endpoint` | `localhost:4317` | OTLP gRPC collector endpoint | +| `--otel.insecure` | `otel.insecure` | `true` | Use non-TLS gRPC connection | +| `--otel.sample-rate` | `otel.sample-rate` | `0.1` | Trace sampling rate (0.0 = none, 1.0 = all) | +| `--otel.chain-id` | `otel.chain-id` | `""` | Chain ID attached as resource attribute on all telemetry | +| `--otel.instance-id` | `otel.instance-id` | `""` (hostname) | Node instance ID attached as resource attribute | + +### Sampling + +For high-throughput chains, reduce `sample-rate` to control trace volume. A rate of `0.1` samples 10% of traces. Metrics are always exported regardless of sampling rate. + +## Grafana Dashboards + +| Dashboard | Location | Description | +|-----------|----------|-------------| +| OG-EVM Chain Overview | og-evm folder | Block production, consensus, mempool, validators, P2P, ABCI timing | +| OG-EVM EVM & Application Metrics | og-evm folder | EVM transactions, gas, base fee, ERC20 conversions, IBC transfers | +| OG-EVM Geth Internals | og-evm folder | TxPool, RPC, P2P, state DB, chain head | +| OG-EVM Infrastructure | og-evm folder | CPU, memory, disk, network (node-exporter) | + +Dashboard variables: +- **Chain ID** — filters CometBFT panels to a specific chain +- **Instance** — filters to a specific validator/node + +Trace waterfalls are available under Explore → Tempo. + +## Alerting + +12 alert rules are provisioned automatically via `grafana/provisioning/alerting/`: + +| Alert | Condition | Severity | +|-------|-----------|----------| +| Chain Halted | No blocks in 5 min | Critical | +| No Peers | Peer count = 0 | Critical | +| Byzantine Validator | Byzantine count > 0 | Critical | +| Low Peer Count | Peers < 3 | Warning | +| High Consensus Rounds | Rounds > 2 | Warning | +| Slow Block Time | Avg > 10s | Warning | +| Missing Validators | Missing > 0 | Warning | +| Mempool Congestion | Size > 500 | Warning | +| IBC Errors Spike | Error rate > 0.1/s | Warning | +| Disk Usage High | > 85% | Warning | +| CPU Usage High | > 90% | Warning | +| Memory Usage High | > 90% | Warning | + +Configure notification channels (Slack, PagerDuty, email) under Alerting → Contact points in the Grafana UI. Without a contact point, alerts are visible in the Grafana UI only. + +## Retention + +| Store | Default | Configuration | +|-------|---------|---------------| +| Prometheus (metrics) | 30 days | `--storage.tsdb.retention.time` in `docker-compose.yml` | +| Tempo (traces) | 14 days | `compactor.compaction.block_retention` in `tempo/config.yml` | + +## Production Considerations + +- **Change Grafana admin password** on first login +- **Use TLS** for the OTel endpoint (`otel.insecure = false`) when the collector is on a different host +- **Tune sampling rate** — `1.0` exports every trace; lower this on high-throughput chains +- **Persistent volumes** — the `docker-compose.yml` uses named Docker volumes; back these up or mount to host paths for durability +- **Resource limits** — consider setting memory/CPU limits on Tempo and Prometheus for production workloads +- **Network security** — restrict access to Grafana (3000), Prometheus (9099), and Tempo (3200) ports +- **Alert notifications** — configure Slack, PagerDuty, or email contact points under Alerting → Contact points in Grafana. Without a contact point, alerts fire in the Grafana UI only + +## Remote Deployment (Separate Monitoring Server) + +By default, the monitoring stack runs co-located with the validator node (`insecure=true`). For production mainnet with a dedicated monitoring server, enable TLS on the OTel endpoint. + +### 1. Generate TLS certificates + +```bash +# Self-signed (for testing) +openssl req -x509 -newkey rsa:4096 \ + -keyout server.key -out server.crt \ + -days 365 -nodes -subj "/CN=og-evm-otel-collector" + +# For production, use CA-signed certificates +``` + +### 2. Configure the OTel Collector + +Create `monitoring/otel-collector/config-tls.yml` with TLS receivers: + +```yaml +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + tls: + cert_file: /certs/server.crt + key_file: /certs/server.key + http: + endpoint: 0.0.0.0:4318 + tls: + cert_file: /certs/server.crt + key_file: /certs/server.key +# ... rest of config same as config.yml +``` + +Mount certs in docker-compose override: + +```yaml + otel-collector: + volumes: + - ./otel-collector/config-tls.yml:/etc/otelcol-contrib/config.yaml:ro + - ./certs:/certs:ro +``` + +### 3. Configure validator nodes + +In each validator's `app.toml`: + +```toml +[otel] +enable = true +endpoint = ":4317" +insecure = false +sample-rate = 0.1 +chain-id = "og-evm-mainnet" +instance-id = "validator-0" +``` + +--- + +## Local Development / Testnet + +For local testing, convenience scripts are provided: + +```bash +# Single-node local devnet with OTel +OTEL_ENABLE=true ./local_node.sh -y --no-install + +# 4-node Docker testnet (prometheus + OTel enabled automatically by wrapper.sh) +make localnet-start +``` + +Local testnet port mapping: + +| Node | CometBFT metrics | Geth metrics | JSON-RPC | P2P | +|------|------------------|-------------|----------|-----| +| node0 | 26660 | 8100 | 8545 | 26656 | +| node1 | 26661 | 8101 | 8555 | 26666 | +| node2 | 26662 | 8102 | 8565 | 26676 | +| node3 | 26663 | 8103 | 8575 | 26686 | diff --git a/monitoring/docker-compose.yml b/monitoring/docker-compose.yml new file mode 100644 index 00000000..b317f44e --- /dev/null +++ b/monitoring/docker-compose.yml @@ -0,0 +1,83 @@ +version: "3.8" + +services: + prometheus: + image: prom/prometheus:latest + container_name: og-evm-prometheus + volumes: + - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro + - ./prometheus/targets:/etc/prometheus/targets:ro + - ./prometheus/rules:/etc/prometheus/rules:ro + - prometheus_data:/prometheus + command: + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.retention.time=30d" + - "--web.enable-lifecycle" + - "--web.enable-remote-write-receiver" + ports: + - "9099:9090" + extra_hosts: + - "host.docker.internal:host-gateway" + restart: unless-stopped + + grafana: + image: grafana/grafana:latest + container_name: og-evm-grafana + volumes: + - grafana_data:/var/lib/grafana + - ./grafana/provisioning:/etc/grafana/provisioning:ro + environment: + - GF_SECURITY_ADMIN_USER=admin + - GF_SECURITY_ADMIN_PASSWORD=admin + - GF_USERS_ALLOW_SIGN_UP=false + - GF_AUTH_ANONYMOUS_ENABLED=false + ports: + - "3000:3000" + depends_on: + - prometheus + restart: unless-stopped + + otel-collector: + image: otel/opentelemetry-collector-contrib:latest + container_name: og-evm-otel-collector + volumes: + - ./otel-collector/config.yml:/etc/otelcol-contrib/config.yaml:ro + ports: + - "4317:4317" # OTLP gRPC + - "4318:4318" # OTLP HTTP + depends_on: + - tempo + restart: unless-stopped + + tempo: + image: grafana/tempo:2.6.1 + container_name: og-evm-tempo + volumes: + - ./tempo/config.yml:/etc/tempo/config.yaml:ro + - tempo_data:/var/tempo + command: ["-config.file=/etc/tempo/config.yaml"] + ports: + - "3200:3200" # Tempo query frontend + restart: unless-stopped + + node-exporter: + image: prom/node-exporter:latest + container_name: og-evm-node-exporter + pid: host + volumes: + - /proc:/host/proc:ro + - /sys:/host/sys:ro + - /:/rootfs:ro + command: + - "--path.procfs=/host/proc" + - "--path.sysfs=/host/sys" + - "--path.rootfs=/rootfs" + - "--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)" + ports: + - "9100:9100" + restart: unless-stopped + +volumes: + prometheus_data: + grafana_data: + tempo_data: diff --git a/monitoring/grafana/provisioning/alerting/alerts.yml b/monitoring/grafana/provisioning/alerting/alerts.yml new file mode 100644 index 00000000..cf994690 --- /dev/null +++ b/monitoring/grafana/provisioning/alerting/alerts.yml @@ -0,0 +1,464 @@ +apiVersion: 1 + +groups: + - orgId: 1 + name: og-evm-critical + folder: og-evm + interval: 1m + rules: + - uid: chain-halted + title: Chain Halted + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: increase(cometbft_consensus_height[5m]) + instant: false + intervalMs: 1000 + maxDataPoints: 43200 + refId: A + - refId: B + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: lt + params: [1] + refId: C + for: 5m + labels: + severity: critical + annotations: + summary: "Chain has not produced blocks in 5+ minutes" + + - uid: no-peers + title: No Peers Connected + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: cometbft_p2p_peers + instant: true + refId: A + - refId: B + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: lt + params: [1] + refId: C + for: 2m + labels: + severity: critical + annotations: + summary: "Node has zero peers - isolated from network" + + - uid: byzantine-validator + title: Byzantine Validator Detected + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: cometbft_consensus_byzantine_validators + instant: true + refId: A + - refId: B + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: gt + params: [0] + refId: C + for: 1m + labels: + severity: critical + annotations: + summary: "Byzantine validator detected in consensus" + + - orgId: 1 + name: og-evm-warning + folder: og-evm + interval: 1m + rules: + - uid: low-peer-count + title: Low Peer Count + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: cometbft_p2p_peers + instant: true + refId: A + - refId: B + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: lt + params: [3] + refId: C + for: 5m + labels: + severity: warning + annotations: + summary: "Node has fewer than 3 peers" + + - uid: high-consensus-rounds + title: High Consensus Rounds + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: cometbft_consensus_rounds + instant: true + refId: A + - refId: B + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: gt + params: [2] + refId: C + for: 5m + labels: + severity: warning + annotations: + summary: "Consensus requiring more than 2 rounds" + + - uid: slow-block-time + title: Slow Block Time + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: ogevm:block_interval:avg_5m + instant: true + refId: A + - refId: B + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: gt + params: [10] + refId: C + for: 5m + labels: + severity: warning + annotations: + summary: "Average block time exceeds 10 seconds" + + - uid: missing-validators + title: Missing Validators + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: cometbft_consensus_missing_validators + instant: true + refId: A + - refId: B + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: gt + params: [0] + refId: C + for: 5m + labels: + severity: warning + annotations: + summary: "Validators missing from consensus" + + - uid: mempool-congestion + title: Mempool Congestion + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: cometbft_mempool_size + instant: true + refId: A + - refId: B + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: gt + params: [500] + refId: C + for: 5m + labels: + severity: warning + annotations: + summary: "Mempool has more than 500 pending transactions" + + - uid: ibc-errors-spike + title: IBC Error Rate High + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: rate(evm_erc20_ibc_error_total[5m]) + instant: true + refId: A + - refId: B + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: gt + params: [0.1] + refId: C + for: 5m + labels: + severity: warning + annotations: + summary: "IBC ERC20 conversion errors exceeding threshold" + + - uid: disk-usage-high + title: Disk Usage High + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: (1 - node_filesystem_avail_bytes{mountpoint=~"/|/host_mnt/Users"} / node_filesystem_size_bytes{mountpoint=~"/|/host_mnt/Users"}) * 100 + instant: true + refId: A + - refId: B + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: gt + params: [85] + refId: C + for: 10m + labels: + severity: warning + annotations: + summary: "Disk usage exceeds 85%" + + - uid: cpu-usage-high + title: CPU Usage High + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) + instant: true + refId: A + - refId: B + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: gt + params: [90] + refId: C + for: 10m + labels: + severity: warning + annotations: + summary: "CPU usage exceeds 90%" + + - uid: memory-usage-high + title: Memory Usage High + condition: C + data: + - refId: A + relativeTimeRange: + from: 600 + to: 0 + datasourceUid: prometheus + model: + expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 + instant: true + refId: A + - refId: B + datasourceUid: __expr__ + model: + type: reduce + expression: A + reducer: last + refId: B + - refId: C + datasourceUid: __expr__ + model: + type: threshold + expression: B + conditions: + - evaluator: + type: gt + params: [90] + refId: C + for: 10m + labels: + severity: warning + annotations: + summary: "Memory usage exceeds 90%" diff --git a/monitoring/grafana/provisioning/dashboards/dashboards.yml b/monitoring/grafana/provisioning/dashboards/dashboards.yml new file mode 100644 index 00000000..692dcc9f --- /dev/null +++ b/monitoring/grafana/provisioning/dashboards/dashboards.yml @@ -0,0 +1,12 @@ +apiVersion: 1 + +providers: + - name: og-evm + orgId: 1 + folder: "og-evm" + type: file + disableDeletion: true + updateIntervalSeconds: 30 + options: + path: /etc/grafana/provisioning/dashboards + foldersFromFilesStructure: false diff --git a/monitoring/grafana/provisioning/dashboards/og-evm-chain-overview.json b/monitoring/grafana/provisioning/dashboards/og-evm-chain-overview.json new file mode 100644 index 00000000..a9b1e056 --- /dev/null +++ b/monitoring/grafana/provisioning/dashboards/og-evm-chain-overview.json @@ -0,0 +1,1537 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "title": "Overview", + "type": "row", + "panels": [] + }, + { + "id": 2, + "title": "Block Height", + "type": "stat", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 1 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_consensus_height{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 3, + "title": "Total Transactions", + "type": "stat", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 1 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_consensus_total_txs{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 4, + "title": "Connected Peers", + "type": "stat", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 12, + "y": 1 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 2 + }, + { + "color": "green", + "value": 4 + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_p2p_peers{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 5, + "title": "Active Validators", + "type": "stat", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 1 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_consensus_validators{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 5 + }, + "id": 6, + "title": "Block Production", + "type": "row", + "panels": [] + }, + { + "id": 7, + "title": "Avg Block Time", + "type": "stat", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 6 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "unit": "s", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "ogevm:block_interval:avg_5m{instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 8, + "title": "Block Rate", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 6, + "y": 6 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "ogevm:block_rate:per_minute{instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 9, + "title": "Block Size", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 6 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "unit": "bytes", + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_consensus_block_size_bytes{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 10, + "title": "Consensus Rounds", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 6 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_consensus_rounds{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 11, + "title": "Mempool", + "type": "row", + "panels": [] + }, + { + "id": 12, + "title": "Mempool Size", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 15 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_mempool_size{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 13, + "title": "Mempool Size Bytes", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 15 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "unit": "bytes", + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_mempool_size_bytes{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 23 + }, + "id": 14, + "title": "Validators", + "type": "row", + "panels": [] + }, + { + "id": 15, + "title": "Missing Validators", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 24 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_consensus_missing_validators{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 16, + "title": "Byzantine Validators", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 24 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_consensus_byzantine_validators{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 17, + "title": "Voting Power", + "type": "stat", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 4, + "w": 8, + "x": 16, + "y": 24 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_consensus_validators_power{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 32 + }, + "id": 18, + "title": "ABCI Timing", + "type": "row", + "panels": [] + }, + { + "id": 19, + "title": "FinalizeBlock Time", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 33 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "unit": "s", + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "rate(cometbft_abci_connection_method_timing_seconds_sum{chain_id=\"$chain_id\",method=\"finalize_block\"}[5m]) / rate(cometbft_abci_connection_method_timing_seconds_count{chain_id=\"$chain_id\",method=\"finalize_block\"}[5m])", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 20, + "title": "Commit Time", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 33 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "unit": "s", + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "rate(cometbft_abci_connection_method_timing_seconds_sum{chain_id=\"$chain_id\",method=\"commit\"}[5m]) / rate(cometbft_abci_connection_method_timing_seconds_count{chain_id=\"$chain_id\",method=\"commit\"}[5m])", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 21, + "title": "Consensus Health", + "type": "row", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 41 + }, + "collapsed": false, + "panels": [] + }, + { + "id": 22, + "title": "Block Processing p99", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 42 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "unit": "s" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "histogram_quantile(0.99, rate(cometbft_state_block_processing_time_bucket{chain_id=\"$chain_id\",instance=~\"$instance\"}[5m]))", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 23, + "title": "Round Duration p99", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 6, + "y": 42 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "unit": "s" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single", + "sort": "none" + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showValues": "auto", + "calcs": [] + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "histogram_quantile(0.99, rate(cometbft_consensus_round_duration_seconds_bucket{chain_id=\"$chain_id\",instance=~\"$instance\"}[5m]))", + "refId": "A", + "legendFormat": "{{instance}}" + } + ] + }, + { + "id": 24, + "title": "Sync Status", + "type": "stat", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 42 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "text": "Synced" + }, + "1": { + "text": "Syncing" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 1 + } + ] + } + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_blocksync_syncing{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A" + } + ] + }, + { + "id": 25, + "title": "Validator Last Signed Height", + "type": "stat", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 42 + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + }, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "cometbft_consensus_validator_last_signed_height{chain_id=\"$chain_id\",instance=~\"$instance\"}", + "refId": "A" + } + ] + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "og-evm", + "Blockchain", + "Cosmos" + ], + "templating": { + "list": [ + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "definition": "label_values(cometbft_consensus_height, chain_id)", + "hide": 0, + "includeAll": false, + "label": "Chain ID", + "multi": false, + "name": "chain_id", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(cometbft_consensus_height, chain_id)" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "type": "query" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "definition": "label_values(up{job=\"cometbft\"}, instance)", + "hide": 0, + "includeAll": true, + "label": "Instance", + "multi": false, + "name": "instance", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(up{job=\"cometbft\"}, instance)" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "OG-EVM Chain Overview", + "uid": "og-evm-chain-overview", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/monitoring/grafana/provisioning/dashboards/og-evm-evm-metrics.json b/monitoring/grafana/provisioning/dashboards/og-evm-evm-metrics.json new file mode 100644 index 00000000..d984b1ca --- /dev/null +++ b/monitoring/grafana/provisioning/dashboards/og-evm-evm-metrics.json @@ -0,0 +1,884 @@ +{ + "id": null, + "uid": "og-evm-evm-metrics", + "title": "OG-EVM EVM & Application Metrics", + "tags": [ + "og-evm", + "EVM", + "OTel" + ], + "schemaVersion": 39, + "version": 1, + "editable": true, + "refresh": "10s", + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "browser", + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "templating": { + "list": [ + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "definition": "label_values(up{job=\"cometbft\"}, instance)", + "hide": 0, + "includeAll": false, + "label": "Instance", + "multi": false, + "name": "instance", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(up{job=\"cometbft\"}, instance)" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "type": "query" + } + ] + }, + "panels": [ + { + "id": 1, + "title": "EVM Transactions", + "type": "row", + "gridPos": { + "x": 0, + "y": 0, + "w": 24, + "h": 1 + }, + "collapsed": false, + "panels": [] + }, + { + "id": 2, + "title": "Tx Rate", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 0, + "y": 0, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "ops" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(evm_tx_ethereum_tx_total{instance=~\"$instance\"}[5m]))", + "legendFormat": "tx/s" + } + ] + }, + { + "id": 3, + "title": "Tx by Type", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 8, + "y": 0, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "ops" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum by (tx_type) (rate(evm_tx_ethereum_tx_total{instance=~\"$instance\"}[5m]))", + "legendFormat": "{{tx_type}}" + } + ] + }, + { + "id": 4, + "title": "Create vs Call", + "type": "piechart", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 16, + "y": 0, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "pieType": "pie", + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum by (execution) (increase(evm_tx_ethereum_tx_total{instance=~\"$instance\"}[1h]))", + "legendFormat": "{{execution}}" + } + ] + }, + { + "id": 5, + "title": "Gas", + "type": "row", + "gridPos": { + "x": 0, + "y": 9, + "w": 24, + "h": 1 + }, + "collapsed": false, + "panels": [] + }, + { + "id": 6, + "title": "Gas Used Rate", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 0, + "y": 9, + "w": 6, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "none" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(evm_tx_ethereum_tx_gas_used_total{instance=~\"$instance\"}[5m]))", + "legendFormat": "gas/s" + } + ] + }, + { + "id": 7, + "title": "Gas Ratio", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 6, + "y": 9, + "w": 6, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "avg(evm_tx_ethereum_tx_gas_ratio{instance=~\"$instance\"})", + "legendFormat": "ratio" + } + ] + }, + { + "id": 8, + "title": "Base Fee", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 12, + "y": 9, + "w": 6, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "none" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "avg(evm_feemarket_base_fee{instance=~\"$instance\"})", + "legendFormat": "base fee" + } + ] + }, + { + "id": 9, + "title": "Block Gas", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 18, + "y": 9, + "w": 6, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "none" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(evm_feemarket_block_gas{instance=~\"$instance\"})", + "legendFormat": "block gas" + } + ] + }, + { + "id": 10, + "title": "ERC20", + "type": "row", + "gridPos": { + "x": 0, + "y": 18, + "w": 24, + "h": 1 + }, + "collapsed": false, + "panels": [] + }, + { + "id": 11, + "title": "Conversions Rate", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 0, + "y": 18, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "ops" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(evm_erc20_convert_erc20_total{instance=~\"$instance\"}[5m]))", + "legendFormat": "conversions/s" + } + ] + }, + { + "id": 12, + "title": "Conversion Amount", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 8, + "y": 18, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "none" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(evm_erc20_convert_erc20_amount_total{instance=~\"$instance\"}[5m]))", + "legendFormat": "amount/s" + } + ] + }, + { + "id": 13, + "title": "By Denom", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 16, + "y": 18, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "none" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum by (denom) (increase(evm_erc20_convert_erc20_total{instance=~\"$instance\"}[1h]))", + "legendFormat": "{{denom}}" + } + ] + }, + { + "id": 14, + "title": "IBC", + "type": "row", + "gridPos": { + "x": 0, + "y": 27, + "w": 24, + "h": 1 + }, + "collapsed": false, + "panels": [] + }, + { + "id": 15, + "title": "IBC Receives", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 0, + "y": 27, + "w": 6, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "ops" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(evm_erc20_ibc_on_recv_total{instance=~\"$instance\"}[5m]))", + "legendFormat": "receives/s" + } + ] + }, + { + "id": 16, + "title": "IBC Transfers", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 6, + "y": 27, + "w": 6, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "ops" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(evm_erc20_ibc_transfer_total{instance=~\"$instance\"}[5m]))", + "legendFormat": "transfers/s" + } + ] + }, + { + "id": 17, + "title": "IBC Errors", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 12, + "y": 27, + "w": 6, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "ops", + "color": { + "mode": "fixed", + "fixedColor": "red" + } + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "color", + "value": { + "mode": "fixed", + "fixedColor": "red" + } + } + ] + } + ] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum(rate(evm_erc20_ibc_error_total{instance=~\"$instance\"}[5m]))", + "legendFormat": "errors/s" + } + ] + }, + { + "id": 18, + "title": "By Channel", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 18, + "y": 27, + "w": 6, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "none" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum by (source_channel) (increase(evm_erc20_ibc_on_recv_total{instance=~\"$instance\"}[1h]))", + "legendFormat": "{{source_channel}}" + } + ] + }, + { + "id": 19, + "title": "Bank", + "type": "row", + "gridPos": { + "x": 0, + "y": 36, + "w": 24, + "h": 1 + }, + "collapsed": false, + "panels": [] + }, + { + "id": 20, + "title": "Send Amounts", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "x": 0, + "y": 36, + "w": 24, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth", + "fillOpacity": 10, + "gradientMode": "scheme", + "showPoints": "auto", + "pointSize": 5, + "lineWidth": 2 + }, + "unit": "none" + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "single" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "expr": "sum by (denom) (evm_tx_msg_send{instance=~\"$instance\"})", + "legendFormat": "{{denom}}" + } + ] + } + ] +} \ No newline at end of file diff --git a/monitoring/grafana/provisioning/dashboards/og-evm-geth-metrics.json b/monitoring/grafana/provisioning/dashboards/og-evm-geth-metrics.json new file mode 100644 index 00000000..0f98b52e --- /dev/null +++ b/monitoring/grafana/provisioning/dashboards/og-evm-geth-metrics.json @@ -0,0 +1,981 @@ +{ + "annotations": { + "list": [] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 100, + "title": "Chain", + "type": "row" + }, + { + "id": 1, + "title": "Head Block", + "type": "stat", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 0 + }, + "targets": [ + { + "expr": "chain_head_block{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "textMode": "auto" + } + }, + { + "id": 2, + "title": "Head Header", + "type": "stat", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 0 + }, + "targets": [ + { + "expr": "chain_head_header{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "textMode": "auto" + } + }, + { + "id": 3, + "title": "Reorgs", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "targets": [ + { + "expr": "chain_reorg_executes{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 101, + "title": "TxPool", + "type": "row" + }, + { + "id": 4, + "title": "Pending", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 9 + }, + "targets": [ + { + "expr": "txpool_pending{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 5, + "title": "Queued", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 6, + "y": 9 + }, + "targets": [ + { + "expr": "txpool_queued{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 6, + "title": "Valid", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 9 + }, + "targets": [ + { + "expr": "txpool_valid{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 7, + "title": "Invalid", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 9 + }, + "targets": [ + { + "expr": "txpool_invalid{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 102, + "title": "RPC", + "type": "row" + }, + { + "id": 8, + "title": "Requests", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 18 + }, + "targets": [ + { + "expr": "rpc_requests{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 9, + "title": "Success", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 18 + }, + "targets": [ + { + "expr": "rpc_success{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 10, + "title": "Failures", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 18 + }, + "targets": [ + { + "expr": "rpc_failure{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 27 + }, + "id": 103, + "title": "P2P", + "type": "row" + }, + { + "id": 11, + "title": "Peers", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 27 + }, + "targets": [ + { + "expr": "p2p_peers{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 12, + "title": "Ingress / Egress", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 27 + }, + "targets": [ + { + "expr": "p2p_ingress{instance=~\"$instance\"}", + "legendFormat": "ingress", + "refId": "A" + }, + { + "expr": "p2p_egress{instance=~\"$instance\"}", + "legendFormat": "egress", + "refId": "B" + } + ], + "fieldConfig": { + "defaults": { + "unit": "bytes", + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 13, + "title": "Dials", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 27 + }, + "targets": [ + { + "expr": "p2p_dials{instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 36 + }, + "id": 104, + "title": "State DB", + "type": "row" + }, + { + "id": 14, + "title": "PathDB Clean Hit / Miss", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 36 + }, + "targets": [ + { + "expr": "pathdb_clean_node_hit{instance=~\"$instance\"}", + "legendFormat": "clean hit", + "refId": "A" + }, + { + "expr": "pathdb_clean_node_miss{instance=~\"$instance\"}", + "legendFormat": "clean miss", + "refId": "B" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 15, + "title": "PathDB Dirty Hit / Miss", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 36 + }, + "targets": [ + { + "expr": "pathdb_dirty_node_hit{instance=~\"$instance\"}", + "legendFormat": "dirty hit", + "refId": "A" + }, + { + "expr": "pathdb_dirty_node_miss{instance=~\"$instance\"}", + "legendFormat": "dirty miss", + "refId": "B" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 44 + }, + "id": 105, + "title": "TxPool Quality", + "type": "row" + }, + { + "id": 16, + "title": "TxPool Slots", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 45 + }, + "targets": [ + { + "expr": "txpool_slots{job=\"geth-metrics\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 17, + "title": "TxPool Underpriced", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 45 + }, + "targets": [ + { + "expr": "txpool_underpriced{job=\"geth-metrics\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 18, + "title": "State Cache Hit Rate", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 45 + }, + "targets": [ + { + "expr": "100 * chain_account_reads_cache_process_hit{job=\"geth-metrics\",instance=~\"$instance\"} / clamp_min(chain_account_reads_cache_process_hit{job=\"geth-metrics\",instance=~\"$instance\"} + chain_account_reads_cache_process_miss{job=\"geth-metrics\",instance=~\"$instance\"}, 1)", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "percent", + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "og-evm", + "Geth", + "EVM" + ], + "templating": { + "list": [ + { + "current": {}, + "definition": "label_values(up{job=\"geth-metrics\"}, instance)", + "hide": 0, + "includeAll": true, + "multi": true, + "name": "instance", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(up{job=\"geth-metrics\"}, instance)" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "OG-EVM Geth Internals", + "uid": "og-evm-geth-metrics", + "version": 1 +} \ No newline at end of file diff --git a/monitoring/grafana/provisioning/dashboards/og-evm-infrastructure.json b/monitoring/grafana/provisioning/dashboards/og-evm-infrastructure.json new file mode 100644 index 00000000..c30a4547 --- /dev/null +++ b/monitoring/grafana/provisioning/dashboards/og-evm-infrastructure.json @@ -0,0 +1,666 @@ +{ + "annotations": { + "list": [] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 100, + "title": "CPU", + "type": "row" + }, + { + "id": 1, + "title": "CPU Usage %", + "type": "gauge", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 0 + }, + "targets": [ + { + "expr": "100 - (avg(rate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)", + "legendFormat": "CPU %", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "percent", + "min": 0, + "max": 100, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 70 + }, + { + "color": "red", + "value": 90 + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + } + }, + { + "id": 2, + "title": "Load Average", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 18, + "x": 6, + "y": 0 + }, + "targets": [ + { + "expr": "node_load1", + "legendFormat": "load1", + "refId": "A" + }, + { + "expr": "node_load5", + "legendFormat": "load5", + "refId": "B" + }, + { + "expr": "node_load15", + "legendFormat": "load15", + "refId": "C" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 101, + "title": "Memory", + "type": "row" + }, + { + "id": 3, + "title": "Memory Usage %", + "type": "gauge", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 9 + }, + "targets": [ + { + "expr": "(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100", + "legendFormat": "Memory %", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "percent", + "min": 0, + "max": 100, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 70 + }, + { + "color": "red", + "value": 90 + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + } + }, + { + "id": 4, + "title": "Memory Over Time", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 18, + "x": 6, + "y": 9 + }, + "targets": [ + { + "expr": "node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes", + "legendFormat": "used", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "bytes", + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 102, + "title": "Disk", + "type": "row" + }, + { + "id": 5, + "title": "Disk Usage %", + "type": "gauge", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 18 + }, + "targets": [ + { + "expr": "(1 - node_filesystem_avail_bytes{mountpoint=~\"/|/host_mnt/Users\"} / node_filesystem_size_bytes{mountpoint=~\"/|/host_mnt/Users\"}) * 100", + "legendFormat": "Disk %", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "percent", + "min": 0, + "max": 100, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 70 + }, + { + "color": "red", + "value": 85 + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + } + }, + { + "id": 6, + "title": "Disk I/O", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 18, + "x": 6, + "y": 18 + }, + "targets": [ + { + "expr": "rate(node_disk_read_bytes_total[5m])", + "legendFormat": "read", + "refId": "A" + }, + { + "expr": "rate(node_disk_written_bytes_total[5m])", + "legendFormat": "written", + "refId": "B" + } + ], + "fieldConfig": { + "defaults": { + "unit": "Bps", + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 27 + }, + "id": 103, + "title": "Network", + "type": "row" + }, + { + "id": 7, + "title": "Network Traffic", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 27 + }, + "targets": [ + { + "expr": "rate(node_network_receive_bytes_total{device!=\"lo\"}[5m])", + "legendFormat": "receive {{device}}", + "refId": "A" + }, + { + "expr": "rate(node_network_transmit_bytes_total{device!=\"lo\"}[5m])", + "legendFormat": "transmit {{device}}", + "refId": "B" + } + ], + "fieldConfig": { + "defaults": { + "unit": "Bps", + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "auto", + "spanNulls": false + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 104, + "title": "Node Process Health", + "type": "row" + }, + { + "id": 8, + "title": "Goroutines", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 36 + }, + "targets": [ + { + "expr": "go_goroutines{job=\"cometbft\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 9, + "title": "Heap In Use", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 6, + "y": 36 + }, + "targets": [ + { + "expr": "go_memstats_heap_inuse_bytes{job=\"cometbft\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "bytes", + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 10, + "title": "Process RSS", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 36 + }, + "targets": [ + { + "expr": "process_resident_memory_bytes{job=\"cometbft\",instance=~\"$instance\"}", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "bytes", + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + }, + { + "id": 11, + "title": "Process CPU (5m)", + "type": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 36 + }, + "targets": [ + { + "expr": "rate(process_cpu_seconds_total{job=\"cometbft\",instance=~\"$instance\"}[5m])", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + }, + "legend": { + "displayMode": "list", + "placement": "bottom" + } + } + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "og-evm", + "Infrastructure" + ], + "templating": { + "list": [ + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "definition": "label_values(up{job=\"cometbft\"}, instance)", + "hide": 0, + "includeAll": true, + "label": "Instance", + "multi": false, + "name": "instance", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(up{job=\"cometbft\"}, instance)" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "OG-EVM Infrastructure", + "uid": "og-evm-infrastructure", + "version": 1 +} \ No newline at end of file diff --git a/monitoring/grafana/provisioning/datasources/datasources.yml b/monitoring/grafana/provisioning/datasources/datasources.yml new file mode 100644 index 00000000..77b0afaf --- /dev/null +++ b/monitoring/grafana/provisioning/datasources/datasources.yml @@ -0,0 +1,20 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + uid: prometheus + type: prometheus + access: proxy + url: http://prometheus:9090 + isDefault: true + editable: true + + - name: Tempo + uid: tempo + type: tempo + access: proxy + url: http://tempo:3200 + editable: true + jsonData: + nodeGraph: + enabled: true diff --git a/monitoring/otel-collector/config.yml b/monitoring/otel-collector/config.yml new file mode 100644 index 00000000..a3185b4b --- /dev/null +++ b/monitoring/otel-collector/config.yml @@ -0,0 +1,34 @@ +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + +processors: + batch: + timeout: 5s + send_batch_size: 1024 + +exporters: + otlp/tempo: + endpoint: tempo:4317 + tls: + insecure: true + + prometheusremotewrite: + endpoint: "http://prometheus:9090/api/v1/write" + resource_to_telemetry_conversion: + enabled: true + +service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [otlp/tempo] + metrics: + receivers: [otlp] + processors: [batch] + exporters: [prometheusremotewrite] diff --git a/monitoring/prometheus/prometheus.yml b/monitoring/prometheus/prometheus.yml new file mode 100644 index 00000000..d18a5af7 --- /dev/null +++ b/monitoring/prometheus/prometheus.yml @@ -0,0 +1,43 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s + +rule_files: + - /etc/prometheus/rules/*.yml + +scrape_configs: + - job_name: "prometheus" + static_configs: + - targets: ["localhost:9090"] + + - job_name: "cometbft" + metrics_path: /metrics + file_sd_configs: + - files: + - /etc/prometheus/targets/og-evm-nodes.json + refresh_interval: 30s + relabel_configs: + - source_labels: [__address__] + regex: "(.+):.*" + target_label: __address__ + replacement: "${1}:26660" + + - job_name: "geth-metrics" + metrics_path: /metrics + file_sd_configs: + - files: + - /etc/prometheus/targets/geth-metrics.json + refresh_interval: 30s + + - job_name: "json-rpc-metrics" + metrics_path: /debug/metrics/prometheus + file_sd_configs: + - files: + - /etc/prometheus/targets/json-rpc-metrics.json + refresh_interval: 30s + + - job_name: "node-exporter" + file_sd_configs: + - files: + - /etc/prometheus/targets/node-exporters.json + refresh_interval: 30s diff --git a/monitoring/prometheus/rules/og-evm-recording.yml b/monitoring/prometheus/rules/og-evm-recording.yml new file mode 100644 index 00000000..7e19cea2 --- /dev/null +++ b/monitoring/prometheus/rules/og-evm-recording.yml @@ -0,0 +1,23 @@ +groups: + - name: og-evm-recording-rules + interval: 30s + rules: + - record: ogevm:block_rate:per_minute + expr: rate(cometbft_consensus_height[5m]) * 60 + + - record: ogevm:block_interval:avg_5m + expr: | + rate(cometbft_consensus_block_interval_seconds_sum[5m]) + / rate(cometbft_consensus_block_interval_seconds_count[5m]) + + - record: ogevm:evm_tx_rate:per_second + expr: rate(evm_tx_ethereum_tx_total[5m]) + + - record: ogevm:evm_gas_rate:per_second + expr: rate(evm_tx_ethereum_tx_gas_used_total[5m]) + + - record: ogevm:ibc_recv_rate:per_minute + expr: rate(evm_erc20_ibc_on_recv_total[5m]) * 60 + + - record: ogevm:ibc_error_rate:per_minute + expr: rate(evm_erc20_ibc_error_total[5m]) * 60 diff --git a/monitoring/prometheus/targets/geth-metrics.json b/monitoring/prometheus/targets/geth-metrics.json new file mode 100644 index 00000000..123d5da0 --- /dev/null +++ b/monitoring/prometheus/targets/geth-metrics.json @@ -0,0 +1,18 @@ +[ + { + "targets": ["host.docker.internal:8100"], + "labels": { "chain_id": "local-4221", "instance": "validator-0" } + }, + { + "targets": ["host.docker.internal:8101"], + "labels": { "chain_id": "local-4221", "instance": "validator-1" } + }, + { + "targets": ["host.docker.internal:8102"], + "labels": { "chain_id": "local-4221", "instance": "validator-2" } + }, + { + "targets": ["host.docker.internal:8103"], + "labels": { "chain_id": "local-4221", "instance": "validator-3" } + } +] diff --git a/monitoring/prometheus/targets/json-rpc-metrics.json b/monitoring/prometheus/targets/json-rpc-metrics.json new file mode 100644 index 00000000..0e4af4bf --- /dev/null +++ b/monitoring/prometheus/targets/json-rpc-metrics.json @@ -0,0 +1,18 @@ +[ + { + "targets": ["host.docker.internal:6065"], + "labels": { "chain_id": "local-4221", "instance": "validator-0" } + }, + { + "targets": ["host.docker.internal:6075"], + "labels": { "chain_id": "local-4221", "instance": "validator-1" } + }, + { + "targets": ["host.docker.internal:6085"], + "labels": { "chain_id": "local-4221", "instance": "validator-2" } + }, + { + "targets": ["host.docker.internal:6095"], + "labels": { "chain_id": "local-4221", "instance": "validator-3" } + } +] diff --git a/monitoring/prometheus/targets/node-exporters.json b/monitoring/prometheus/targets/node-exporters.json new file mode 100644 index 00000000..9a2b334a --- /dev/null +++ b/monitoring/prometheus/targets/node-exporters.json @@ -0,0 +1,8 @@ +[ + { + "targets": ["host.docker.internal:9100"], + "labels": { + "instance": "monitoring-host" + } + } +] diff --git a/monitoring/prometheus/targets/og-evm-nodes.json b/monitoring/prometheus/targets/og-evm-nodes.json new file mode 100644 index 00000000..4a74d2d5 --- /dev/null +++ b/monitoring/prometheus/targets/og-evm-nodes.json @@ -0,0 +1,18 @@ +[ + { + "targets": ["host.docker.internal:26660"], + "labels": { "chain_id": "local-4221", "instance": "validator-0" } + }, + { + "targets": ["host.docker.internal:26661"], + "labels": { "chain_id": "local-4221", "instance": "validator-1" } + }, + { + "targets": ["host.docker.internal:26662"], + "labels": { "chain_id": "local-4221", "instance": "validator-2" } + }, + { + "targets": ["host.docker.internal:26663"], + "labels": { "chain_id": "local-4221", "instance": "validator-3" } + } +] diff --git a/monitoring/tempo/config.yml b/monitoring/tempo/config.yml new file mode 100644 index 00000000..4f6d662d --- /dev/null +++ b/monitoring/tempo/config.yml @@ -0,0 +1,45 @@ +server: + http_listen_port: 3200 + +distributor: + receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + +storage: + trace: + backend: local + local: + path: /var/tempo/traces + wal: + path: /var/tempo/wal + +metrics_generator: + storage: + path: /var/tempo/generator/wal + remote_write: + - url: http://prometheus:9090/api/v1/write + send_exemplars: true + registry: + external_labels: + source: tempo + processor: + service_graphs: + wait: 10s + max_items: 10000 + span_metrics: {} + local_blocks: + flush_to_storage: true + traces_storage: + path: /var/tempo/generator/traces + +compactor: + compaction: + block_retention: 336h + +overrides: + defaults: + metrics_generator: + processors: [service-graphs, span-metrics, local-blocks] diff --git a/multi_node_startup.sh b/multi_node_startup.sh index 211c84c4..26209d96 100755 --- a/multi_node_startup.sh +++ b/multi_node_startup.sh @@ -11,6 +11,7 @@ BASEDIR="${BASEDIR:-"$HOME/.og-evm-devnet"}" NODE_NUMBER="${NODE_NUMBER:-}" START_VALIDATOR="${START_VALIDATOR:-false}" GENERATE_GENESIS="${GENERATE_GENESIS:-false}" +OTEL_ENABLE="${OTEL_ENABLE:-false}" VAL0_MNEMONIC="" VAL1_MNEMONIC="" @@ -42,6 +43,8 @@ usage() { echo " GENERATE_GENESIS=true Generate genesis for all 3 validators" echo " START_VALIDATOR=true Start a validator" echo " NODE_NUMBER=0|1|2 Which validator to start" + echo " OTEL_ENABLE=true Enable OpenTelemetry tracing" + echo " OTEL_ENDPOINT=host:port OTel collector endpoint (default: localhost:4317)" echo " BASEDIR=path Base directory (default: ~/.og-evm-devnet)" echo "" echo "Options:" @@ -222,9 +225,13 @@ generate_genesis() { evmd config set client chain-id "$CHAINID" --home "$HOME_DIR" evmd config set client keyring-backend "$KEYRING" --home "$HOME_DIR" - echo "$MNEMONIC" | evmd keys add "$VALKEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$HOME_DIR" - - echo "$MNEMONIC" | evmd init "${MONIKER}-val${i}" -o --chain-id "$CHAINID" --home "$HOME_DIR" --recover + if [[ -n "$MNEMONIC" ]]; then + echo "$MNEMONIC" | evmd keys add "$VALKEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$HOME_DIR" + echo "$MNEMONIC" | evmd init "${MONIKER}-val${i}" -o --chain-id "$CHAINID" --home "$HOME_DIR" --recover + else + evmd keys add "$VALKEY" --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$HOME_DIR" + evmd init "${MONIKER}-val${i}" -o --chain-id "$CHAINID" --home "$HOME_DIR" + fi NODE_ID=$(evmd comet show-node-id --home "$HOME_DIR") NODE_IDS+=("$NODE_ID") @@ -371,8 +378,17 @@ start_validator() { --home "$HOME_DIR" --json-rpc.api eth,txpool,personal,net,debug,web3 --chain-id "$CHAINID" + --metrics ) + if [[ "$OTEL_ENABLE" == "true" ]]; then + START_ARGS+=( + --otel.enable + --otel.endpoint "${OTEL_ENDPOINT:-localhost:4317}" + --otel.insecure + ) + fi + exec evmd start "${START_ARGS[@]}" } diff --git a/server/config/config.go b/server/config/config.go index 186ee91a..f9e9fb32 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -134,6 +134,7 @@ type Config struct { EVM EVMConfig `mapstructure:"evm"` JSONRPC JSONRPCConfig `mapstructure:"json-rpc"` TLS TLSConfig `mapstructure:"tls"` + OTel OTelConfig `mapstructure:"otel"` } // EVMConfig defines the application configuration values for the EVM. @@ -402,6 +403,45 @@ func (c JSONRPCConfig) Validate() error { return nil } +// OTelConfig defines the OpenTelemetry configuration for exporting traces and metrics. +type OTelConfig struct { + // Enable defines if the OpenTelemetry exporter should be enabled. + Enable bool `mapstructure:"enable"` + // Endpoint defines the OTLP gRPC endpoint to export traces to (e.g., "localhost:4317"). + Endpoint string `mapstructure:"endpoint"` + // Insecure defines if the OTLP exporter should use an insecure (non-TLS) connection. + Insecure bool `mapstructure:"insecure"` + // SampleRate controls the fraction of traces sampled (0.0 to 1.0). + SampleRate float64 `mapstructure:"sample-rate"` + // ChainID identifies this chain in traces. Attached as chain_id resource attribute. + ChainID string `mapstructure:"chain-id"` + // InstanceID identifies this node instance in metrics and traces (e.g., "validator-0"). + // Defaults to os.Hostname() if empty. + InstanceID string `mapstructure:"instance-id"` +} + +// DefaultOTelConfig returns the default OpenTelemetry configuration (disabled). +func DefaultOTelConfig() *OTelConfig { + return &OTelConfig{ + Enable: false, + Endpoint: "localhost:4317", + Insecure: true, + SampleRate: 0.1, + ChainID: "", + } +} + +// Validate returns an error if the OTel configuration is invalid. +func (c OTelConfig) Validate() error { + if c.Enable && c.Endpoint == "" { + return errors.New("OTel endpoint must be set when OTel is enabled") + } + if c.SampleRate < 0 || c.SampleRate > 1 { + return fmt.Errorf("OTel sample-rate must be between 0.0 and 1.0, got %f", c.SampleRate) + } + return nil +} + // DefaultTLSConfig returns the default TLS configuration func DefaultTLSConfig() *TLSConfig { return &TLSConfig{ @@ -440,6 +480,7 @@ func DefaultConfig() *Config { EVM: *DefaultEVMConfig(), JSONRPC: *DefaultJSONRPCConfig(), TLS: *DefaultTLSConfig(), + OTel: *DefaultOTelConfig(), } } @@ -471,5 +512,9 @@ func (c Config) ValidateBasic() error { return errorsmod.Wrapf(errortypes.ErrAppConfig, "invalid tls config value: %s", err.Error()) } + if err := c.OTel.Validate(); err != nil { + return errorsmod.Wrapf(errortypes.ErrAppConfig, "invalid otel config value: %s", err.Error()) + } + return c.Config.ValidateBasic() } diff --git a/server/config/toml.go b/server/config/toml.go index 60bd3402..c2756057 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -140,4 +140,30 @@ certificate-path = "{{ .TLS.CertificatePath }}" # Key path defines the key.pem file path for the TLS configuration. key-path = "{{ .TLS.KeyPath }}" + +############################################################################### +### OpenTelemetry Configuration ### +############################################################################### + +[otel] + +# Enable defines if the OpenTelemetry exporter should be enabled. +enable = {{ .OTel.Enable }} + +# Endpoint defines the OTLP gRPC endpoint to export traces and metrics to. +# Example: "localhost:4317" for a local OTel Collector. +endpoint = "{{ .OTel.Endpoint }}" + +# Insecure defines if the exporter should use an insecure (non-TLS) connection. +insecure = {{ .OTel.Insecure }} + +# SampleRate controls the fraction of traces sampled (0.0 to 1.0). Default: 0.1 (10%). +sample-rate = {{ .OTel.SampleRate }} + +# ChainID identifies this chain in traces. Attached as chain_id resource attribute. +chain-id = "{{ .OTel.ChainID }}" + +# InstanceID identifies this node in metrics and traces (e.g., "validator-0"). +# Defaults to os.Hostname() if empty. +instance-id = "{{ .OTel.InstanceID }}" ` diff --git a/server/flags/flags.go b/server/flags/flags.go index 9550a774..e3dc4739 100644 --- a/server/flags/flags.go +++ b/server/flags/flags.go @@ -87,6 +87,16 @@ const ( TLSKeyPath = "tls.key-path" ) +// OpenTelemetry flags +const ( + OTelEnable = "otel.enable" + OTelEndpoint = "otel.endpoint" + OTelInsecure = "otel.insecure" + OTelSampleRate = "otel.sample-rate" + OTelChainID = "otel.chain-id" + OTelInstanceID = "otel.instance-id" +) + // AddTxFlags adds common flags for commands to post tx func AddTxFlags(cmd *cobra.Command) (*cobra.Command, error) { cmd.PersistentFlags().String(flags.FlagChainID, "", "Specify Chain ID for sending Tx") diff --git a/server/otel.go b/server/otel.go new file mode 100644 index 00000000..cf2b2e4b --- /dev/null +++ b/server/otel.go @@ -0,0 +1,123 @@ +package server + +import ( + "context" + "errors" + "os" + "strings" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.26.0" + "google.golang.org/grpc/credentials/insecure" + + "cosmossdk.io/log" + + cosmosevmserverconfig "github.com/cosmos/evm/server/config" + "github.com/cosmos/evm/version" +) + +// InitOTel initializes both the TracerProvider and MeterProvider with OTLP gRPC exporters. +// Returns a shutdown function that must be called on application exit. +func InitOTel(ctx context.Context, cfg cosmosevmserverconfig.OTelConfig, logger log.Logger) (func(context.Context) error, error) { + noop := func(context.Context) error { return nil } + + logger.Info("InitOTel called", "enable", cfg.Enable, "endpoint", cfg.Endpoint, "insecure", cfg.Insecure) + if !cfg.Enable { + logger.Info("OpenTelemetry is DISABLED, skipping initialization") + return noop, nil + } + + instanceID := strings.TrimSpace(cfg.InstanceID) + if instanceID == "" { + instanceID, _ = os.Hostname() + } + + res, err := resource.New(ctx, + resource.WithAttributes( + semconv.ServiceNameKey.String("og-evm"), + semconv.ServiceVersionKey.String(version.AppVersion), + semconv.ServiceInstanceIDKey.String(instanceID), + attribute.String("chain_id", cfg.ChainID), + ), + ) + if err != nil { + return noop, err + } + + traceOpts := []otlptracegrpc.Option{ + otlptracegrpc.WithEndpoint(cfg.Endpoint), + } + metricOpts := []otlpmetricgrpc.Option{ + otlpmetricgrpc.WithEndpoint(cfg.Endpoint), + } + if cfg.Insecure { + creds := insecure.NewCredentials() + traceOpts = append(traceOpts, otlptracegrpc.WithTLSCredentials(creds)) + metricOpts = append(metricOpts, otlpmetricgrpc.WithTLSCredentials(creds)) + } + + traceExporter, err := otlptracegrpc.New(ctx, traceOpts...) + if err != nil { + return noop, err + } + + tp := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(traceExporter), + sdktrace.WithResource(res), + sdktrace.WithSampler(sdktrace.ParentBased(sdktrace.TraceIDRatioBased(cfg.SampleRate))), + ) + otel.SetTracerProvider(tp) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator( + propagation.TraceContext{}, + propagation.Baggage{}, + )) + + metricExporter, err := otlpmetricgrpc.New(ctx, metricOpts...) + if err != nil { + logger.Error("failed to create OTel metric exporter", "error", err.Error()) + return tp.Shutdown, nil + } + + mp := metric.NewMeterProvider( + metric.WithReader(metric.NewPeriodicReader(metricExporter)), + metric.WithResource(res), + ) + otel.SetMeterProvider(mp) + + logger.Info("OpenTelemetry tracing and metrics enabled", + "endpoint", cfg.Endpoint, + "insecure", cfg.Insecure, + "sample_rate", cfg.SampleRate, + "chain_id", cfg.ChainID, + ) + + shutdown := func(ctx context.Context) error { + return errors.Join(tp.Shutdown(ctx), mp.Shutdown(ctx)) + } + + return shutdown, nil +} + +// initOTelWithCleanup initializes OTel and returns a cleanup function safe to defer. +// Logs errors rather than returning them — the node should start even if OTel fails. +func initOTelWithCleanup(ctx context.Context, cfg cosmosevmserverconfig.OTelConfig, logger log.Logger) func() { + shutdown, err := InitOTel(ctx, cfg, logger) + if err != nil { + logger.Error("failed to init OpenTelemetry", "error", err.Error()) + } + return func() { + if shutdown == nil { + return + } + if err := shutdown(context.Background()); err != nil { + logger.Error("failed to shutdown OpenTelemetry", "error", err.Error()) + } + } +} diff --git a/server/start.go b/server/start.go index 0ebf5b1b..a7a3fad0 100644 --- a/server/start.go +++ b/server/start.go @@ -8,6 +8,7 @@ import ( "path/filepath" "runtime/pprof" + gethmetrics "github.com/ethereum/go-ethereum/metrics" ethmetricsexp "github.com/ethereum/go-ethereum/metrics/exp" "github.com/spf13/cobra" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" @@ -235,6 +236,13 @@ which accepts a path for the resulting pprof file. cmd.Flags().String(srvflags.TLSCertPath, "", "the cert.pem file path for the server TLS configuration") cmd.Flags().String(srvflags.TLSKeyPath, "", "the key.pem file path for the server TLS configuration") + cmd.Flags().Bool(srvflags.OTelEnable, false, "enable OpenTelemetry trace and metric export") + cmd.Flags().String(srvflags.OTelEndpoint, cosmosevmserverconfig.DefaultOTelConfig().Endpoint, "OTLP gRPC endpoint for trace export") + cmd.Flags().Bool(srvflags.OTelInsecure, true, "use insecure (non-TLS) connection for OTLP export") + cmd.Flags().Float64(srvflags.OTelSampleRate, cosmosevmserverconfig.DefaultOTelConfig().SampleRate, "trace sampling rate (0.0 to 1.0)") + cmd.Flags().String(srvflags.OTelChainID, cosmosevmserverconfig.DefaultOTelConfig().ChainID, "chain ID for trace identification") + cmd.Flags().String(srvflags.OTelInstanceID, "", "instance ID for trace identification (defaults to hostname)") + cmd.Flags().Uint64(server.FlagStateSyncSnapshotInterval, 0, "State sync snapshot interval") cmd.Flags().Uint32(server.FlagStateSyncSnapshotKeepRecent, 2, "State sync snapshot to keep") @@ -290,6 +298,8 @@ func startStandAlone(svrCtx *server.Context, opts StartOptions) error { return err } + defer initOTelWithCleanup(context.Background(), config.OTel, svrCtx.Logger)() + _, err = startTelemetry(config) if err != nil { return err @@ -464,6 +474,8 @@ func startInProcess(svrCtx *server.Context, clientCtx client.Context, opts Start } } + defer initOTelWithCleanup(ctx, config.OTel, logger)() + metrics, err := startTelemetry(config) if err != nil { return err @@ -472,6 +484,7 @@ func startInProcess(svrCtx *server.Context, clientCtx client.Context, opts Start // Enable metrics if JSONRPC is enabled and --metrics is passed // Flag not added in config to avoid user enabling in config without passing in CLI if config.JSONRPC.Enable && svrCtx.Viper.GetBool(srvflags.JSONRPCEnableMetrics) { + gethmetrics.Enable() ethmetricsexp.Setup(config.JSONRPC.MetricsAddress) } diff --git a/trace/metric.go b/trace/metric.go new file mode 100644 index 00000000..0be4c28d --- /dev/null +++ b/trace/metric.go @@ -0,0 +1,34 @@ +package trace + +import ( + "fmt" + + "go.opentelemetry.io/otel/metric" +) + +// MustInt64Counter creates an Int64Counter and panics on error. +func MustInt64Counter(m metric.Meter, name string, opts ...metric.Int64CounterOption) metric.Int64Counter { + c, err := m.Int64Counter(name, opts...) + if err != nil { + panic(fmt.Sprintf("failed to create OTel counter %s: %v", name, err)) + } + return c +} + +// MustFloat64Counter creates a Float64Counter and panics on error. +func MustFloat64Counter(m metric.Meter, name string, opts ...metric.Float64CounterOption) metric.Float64Counter { + c, err := m.Float64Counter(name, opts...) + if err != nil { + panic(fmt.Sprintf("failed to create OTel counter %s: %v", name, err)) + } + return c +} + +// MustFloat64Gauge creates a Float64Gauge and panics on error. +func MustFloat64Gauge(m metric.Meter, name string, opts ...metric.Float64GaugeOption) metric.Float64Gauge { + g, err := m.Float64Gauge(name, opts...) + if err != nil { + panic(fmt.Sprintf("failed to create OTel gauge %s: %v", name, err)) + } + return g +} diff --git a/x/erc20/keeper/ibc_callbacks.go b/x/erc20/keeper/ibc_callbacks.go index ebf80b80..dc012b43 100644 --- a/x/erc20/keeper/ibc_callbacks.go +++ b/x/erc20/keeper/ibc_callbacks.go @@ -4,8 +4,10 @@ import ( "strings" "github.com/ethereum/go-ethereum/common" - "github.com/hashicorp/go-metrics" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + evmtrace "github.com/cosmos/evm/trace" "github.com/cosmos/evm/ibc" "github.com/cosmos/evm/x/erc20/types" transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" @@ -15,11 +17,22 @@ import ( errorsmod "cosmossdk.io/errors" storetypes "cosmossdk.io/store/types" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" ) +var ( + ibcOnRecvCounter metric.Int64Counter + ibcErrorCounter metric.Int64Counter +) + +func init() { + ibcOnRecvCounter = evmtrace.MustInt64Counter(erc20Meter, "evm.erc20.ibc.on_recv", + metric.WithDescription("Total successful IBC ERC20 conversions on receive")) + ibcErrorCounter = evmtrace.MustInt64Counter(erc20Meter, "evm.erc20.ibc.error", + metric.WithDescription("Total failed IBC ERC20 conversions")) +} + // OnRecvPacket performs the ICS20 middleware receive callback for automatically // converting an IBC Coin to their ERC20 representation. // For the conversion to succeed, the IBC denomination must have previously been @@ -140,14 +153,12 @@ func (k Keeper) OnRecvPacket( } // For now the only case we are interested in adding telemetry is a successful conversion. - telemetry.IncrCounterWithLabels( //nolint:staticcheck // TODO: fix - []string{types.ModuleName, "ibc", "on_recv", "total"}, - 1, - []metrics.Label{ - telemetry.NewLabel("denom", coin.Denom), //nolint:staticcheck // TODO: fix - telemetry.NewLabel("source_channel", packet.SourceChannel), //nolint:staticcheck // TODO: fix - telemetry.NewLabel("source_port", packet.SourcePort), //nolint:staticcheck // TODO: fix - }, + ibcOnRecvCounter.Add(ctx, 1, + metric.WithAttributes( + attribute.String("denom", coin.Denom), + attribute.String("source_channel", packet.SourceChannel), + attribute.String("source_port", packet.SourcePort), + ), ) } @@ -238,7 +249,7 @@ func (k Keeper) ConvertCoinToERC20FromPacket(ctx sdk.Context, data transfertypes if err := k.ConvertCoinNativeERC20(ctx, pair, coin.Amount, common.BytesToAddress(sender), sender); err != nil { // We want to record only the failed attempt to reconvert the coins during IBC. defer func() { - telemetry.IncrCounter(1, types.ModuleName, "ibc", "error", "total") //nolint:staticcheck // TODO: fix + ibcErrorCounter.Add(ctx, 1) }() ctx.EventManager().EmitEvents( sdk.Events{ diff --git a/x/erc20/keeper/msg_server.go b/x/erc20/keeper/msg_server.go index b0859b8d..c01809d1 100644 --- a/x/erc20/keeper/msg_server.go +++ b/x/erc20/keeper/msg_server.go @@ -5,20 +5,35 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/hashicorp/go-metrics" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" "github.com/cosmos/evm/contracts" + evmtrace "github.com/cosmos/evm/trace" "github.com/cosmos/evm/x/erc20/types" sdkerrors "cosmossdk.io/errors" "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) +var ( + erc20Meter = otel.Meter("evm/x/erc20/keeper") + convertERC20Counter metric.Int64Counter + convertERC20Amount metric.Float64Counter +) + +func init() { + convertERC20Counter = evmtrace.MustInt64Counter(erc20Meter, "evm.erc20.convert_erc20", + metric.WithDescription("Total ERC20 to coin conversions")) + convertERC20Amount = evmtrace.MustFloat64Counter(erc20Meter, "evm.erc20.convert_erc20.amount", + metric.WithDescription("Total ERC20 conversion amounts")) +} + var _ types.MsgServer = &Keeper{} // ConvertERC20 converts ERC20 tokens into native Cosmos coins for both @@ -152,21 +167,13 @@ func (k Keeper) convertERC20IntoCoinsForNativeToken( } defer func() { - telemetry.IncrCounterWithLabels( //nolint:staticcheck // TODO: fix - []string{"tx", "msg", "convert", "erc20", "total"}, - 1, - []metrics.Label{ - telemetry.NewLabel("coin", pair.Denom), //nolint:staticcheck // TODO: fix - }, + convertERC20Counter.Add(ctx, 1, + metric.WithAttributes(attribute.String("denom", pair.Denom)), ) if msg.Amount.IsInt64() { - telemetry.IncrCounterWithLabels( //nolint:staticcheck // TODO: fix - []string{"tx", "msg", "convert", "erc20", "amount", "total"}, - float32(msg.Amount.Int64()), - []metrics.Label{ - telemetry.NewLabel("denom", pair.Denom), //nolint:staticcheck // TODO: fix - }, + convertERC20Amount.Add(ctx, float64(msg.Amount.Int64()), + metric.WithAttributes(attribute.String("denom", pair.Denom)), ) } }() diff --git a/x/feemarket/keeper/abci.go b/x/feemarket/keeper/abci.go index 2c89b6e9..965ffcb5 100644 --- a/x/feemarket/keeper/abci.go +++ b/x/feemarket/keeper/abci.go @@ -5,16 +5,40 @@ import ( "fmt" gomath "math" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/trace" + + evmtrace "github.com/cosmos/evm/trace" "github.com/cosmos/evm/x/feemarket/types" "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" ) +var ( + feemarketTracer = otel.Tracer("evm/x/feemarket/keeper") + feemarketMeter = otel.Meter("evm/x/feemarket/keeper") + baseFeeGauge metric.Float64Gauge + blockGasGauge metric.Float64Gauge +) + +func init() { + baseFeeGauge = evmtrace.MustFloat64Gauge(feemarketMeter, "evm.feemarket.base_fee", + metric.WithDescription("Current base fee")) + blockGasGauge = evmtrace.MustFloat64Gauge(feemarketMeter, "evm.feemarket.block_gas", + metric.WithDescription("Block gas wanted")) +} + // BeginBlock updates base fee func (k *Keeper) BeginBlock(ctx sdk.Context) error { + _, span := feemarketTracer.Start(ctx.Context(), "feemarket.BeginBlock", + trace.WithAttributes(attribute.Int64("block_height", ctx.BlockHeight())), + ) + defer span.End() + baseFee := k.CalculateBaseFee(ctx) // return immediately if base fee is nil @@ -30,8 +54,7 @@ func (k *Keeper) BeginBlock(ctx sdk.Context) error { ctx.Logger().Error("error converting base fee to float64", "error", err.Error()) return } - // there'll be no panic if fails to convert to float32. Will only loose precision - telemetry.SetGauge(float32(floatBaseFee), "feemarket", "base_fee") //nolint:staticcheck // TODO: fix + baseFeeGauge.Record(ctx, floatBaseFee) }() // Store current base fee in event @@ -79,9 +102,7 @@ func (k *Keeper) EndBlock(ctx sdk.Context) error { updatedGasWanted := math.LegacyMaxDec(limitedGasWanted, math.LegacyNewDec(int64(gasUsed))).TruncateInt().Uint64() k.SetBlockGasWanted(ctx, updatedGasWanted) - defer func() { - telemetry.SetGauge(float32(updatedGasWanted), "feemarket", "block_gas") //nolint:staticcheck // TODO: fix - }() + defer blockGasGauge.Record(ctx, float64(updatedGasWanted)) ctx.EventManager().EmitEvent(sdk.NewEvent( "block_gas", diff --git a/x/ibc/transfer/keeper/msg_server.go b/x/ibc/transfer/keeper/msg_server.go index 3242e28b..d1e3e823 100644 --- a/x/ibc/transfer/keeper/msg_server.go +++ b/x/ibc/transfer/keeper/msg_server.go @@ -5,17 +5,29 @@ import ( "strings" "github.com/ethereum/go-ethereum/common" - "github.com/hashicorp/go-metrics" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + evmtrace "github.com/cosmos/evm/trace" erc20types "github.com/cosmos/evm/x/erc20/types" "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" storetypes "cosmossdk.io/store/types" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" ) +var ( + ibcTransferMeter = otel.Meter("evm/x/ibc/transfer/keeper") + ibcTransferCounter metric.Int64Counter +) + +func init() { + ibcTransferCounter = evmtrace.MustInt64Counter(ibcTransferMeter, "evm.erc20.ibc.transfer", + metric.WithDescription("Total ERC20 IBC transfers")) +} + var _ types.MsgServer = Keeper{} // Transfer defines a gRPC msg server method for the MsgTransfer message. @@ -75,12 +87,8 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types. if balance.Amount.GTE(msg.Token.Amount) { defer func() { - telemetry.IncrCounterWithLabels( //nolint:staticcheck // TODO: fix - []string{"erc20", "ibc", "transfer", "total"}, - 1, - []metrics.Label{ - telemetry.NewLabel("denom", pair.Denom), //nolint:staticcheck // TODO: fix - }, + ibcTransferCounter.Add(goCtx, 1, + metric.WithAttributes(attribute.String("denom", pair.Denom)), ) }() @@ -104,12 +112,8 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types. } defer func() { - telemetry.IncrCounterWithLabels( //nolint:staticcheck // TODO: fix - []string{"erc20", "ibc", "transfer", "total"}, - 1, - []metrics.Label{ - telemetry.NewLabel("denom", pair.Denom), //nolint:staticcheck // TODO: fix - }, + ibcTransferCounter.Add(goCtx, 1, + metric.WithAttributes(attribute.String("denom", pair.Denom)), ) }() diff --git a/x/precisebank/keeper/send.go b/x/precisebank/keeper/send.go index 7eb37bbe..f70ce082 100644 --- a/x/precisebank/keeper/send.go +++ b/x/precisebank/keeper/send.go @@ -5,20 +5,32 @@ import ( "errors" "fmt" - "github.com/hashicorp/go-metrics" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + evmtrace "github.com/cosmos/evm/trace" "github.com/cosmos/evm/x/precisebank/types" evmtypes "github.com/cosmos/evm/x/vm/types" errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) +var ( + precisebankMeter = otel.Meter("evm/x/precisebank/keeper") + sendGauge metric.Float64Gauge +) + +func init() { + sendGauge = evmtrace.MustFloat64Gauge(precisebankMeter, "evm.tx.msg.send", + metric.WithDescription("Send transaction amount")) +} + // IsSendEnabledCoins uses the parent x/bank keeper to check the coins provided // and returns an ErrSendDisabled if any of the coins are not configured for // sending. Returns nil if sending is enabled for all provided coin. @@ -471,10 +483,8 @@ func (k Keeper) Send(goCtx context.Context, msg *banktypes.MsgSend) (*banktypes. defer func() { for _, a := range msg.Amount { if a.Amount.IsInt64() { - telemetry.SetGaugeWithLabels( //nolint:staticcheck // TODO: fix - []string{"tx", "msg", "send"}, - float32(a.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, //nolint:staticcheck // TODO: fix + sendGauge.Record(goCtx, float64(a.Amount.Int64()), + metric.WithAttributes(attribute.String("denom", a.Denom)), ) } } diff --git a/x/vm/keeper/msg_server.go b/x/vm/keeper/msg_server.go index e1fac779..39b790e2 100644 --- a/x/vm/keeper/msg_server.go +++ b/x/vm/keeper/msg_server.go @@ -3,11 +3,11 @@ package keeper import ( "context" "encoding/hex" - "fmt" "strconv" - "github.com/hashicorp/go-metrics" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/trace" cmttypes "github.com/cometbft/cometbft/types" @@ -16,13 +16,27 @@ import ( "github.com/cosmos/evm/x/vm/types" errorsmod "cosmossdk.io/errors" - "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) +var ( + vmMeter = otel.Meter("evm/x/vm/keeper") + ethTxCounter metric.Int64Counter + ethGasCounter metric.Float64Counter + ethGasRatio metric.Float64Gauge +) + +func init() { + ethTxCounter = evmtrace.MustInt64Counter(vmMeter, "evm.tx.ethereum_tx", + metric.WithDescription("Total number of Ethereum transactions")) + ethGasCounter = evmtrace.MustFloat64Counter(vmMeter, "evm.tx.ethereum_tx.gas_used", + metric.WithDescription("Total gas used by Ethereum transactions")) + ethGasRatio = evmtrace.MustFloat64Gauge(vmMeter, "evm.tx.ethereum_tx.gas_ratio", + metric.WithDescription("Gas limit to gas used ratio")) +} + var _ types.MsgServer = &Keeper{} // EthereumTx implements the gRPC MsgServer interface. It receives a transaction which is then @@ -38,13 +52,10 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (_ tx := msg.AsTransaction() - labels := []metrics.Label{ - telemetry.NewLabel("tx_type", fmt.Sprintf("%d", tx.Type())), //nolint:staticcheck // TODO: fix - } + txType := strconv.FormatUint(uint64(tx.Type()), 10) + execution := "call" if tx.To() == nil { - labels = append(labels, telemetry.NewLabel("execution", "create")) //nolint:staticcheck // TODO: fix - } else { - labels = append(labels, telemetry.NewLabel("execution", "call")) //nolint:staticcheck // TODO: fix + execution = "create" } response, err := k.ApplyTransaction(ctx, msg.AsTransaction()) @@ -53,30 +64,19 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (_ } defer func() { - telemetry.IncrCounterWithLabels( //nolint:staticcheck // TODO: fix - []string{"tx", "msg", "ethereum_tx", "total"}, - 1, - labels, + attrs := metric.WithAttributes( + attribute.String("tx_type", txType), + attribute.String("execution", execution), ) + ethTxCounter.Add(goCtx, 1, attrs) + if response.GasUsed != 0 { - telemetry.IncrCounterWithLabels( //nolint:staticcheck // TODO: fix - []string{"tx", "msg", "ethereum_tx", "gas_used", "total"}, - float32(response.GasUsed), - labels, - ) - - // Observe which users define a gas limit >> gas used. Note, that - // gas_limit and gas_used are always > 0 - gasLimit := math.LegacyNewDec(int64(tx.Gas())) //#nosec G115 -- int overflow is not a concern here -- tx gas is not going to exceed int64 max value - gasRatio, err := gasLimit.QuoInt64(int64(response.GasUsed)).Float64() //#nosec G115 -- int overflow is not a concern here -- gas used is not going to exceed int64 max value - if err == nil { - telemetry.SetGaugeWithLabels( //nolint:staticcheck // TODO: fix - []string{"tx", "msg", "ethereum_tx", "gas_limit", "per", "gas_used"}, - float32(gasRatio), - labels, - ) - } + ethGasCounter.Add(goCtx, float64(response.GasUsed), attrs) + + // Observe which users define a gas limit >> gas used + gasRatioVal := float64(tx.Gas()) / float64(response.GasUsed) + ethGasRatio.Record(goCtx, gasRatioVal, attrs) } }() @@ -112,7 +112,7 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (_ sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), sdk.NewAttribute(sdk.AttributeKeySender, types.HexAddress(msg.From)), - sdk.NewAttribute(types.AttributeKeyTxType, fmt.Sprintf("%d", tx.Type())), + sdk.NewAttribute(types.AttributeKeyTxType, txType), ), })