Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): add metrics/observability with prometheus #1518

Merged
merged 22 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
981853f
wip
fborello-lambda Dec 16, 2024
0f42c9b
test with L2 node
fborello-lambda Dec 16, 2024
7e5ba04
refactor: Makefile
fborello-lambda Dec 16, 2024
b69f76d
docs
fborello-lambda Dec 17, 2024
e59cb38
refactor: add metrics macro and features
fborello-lambda Dec 17, 2024
a212dc2
refactor: rm unwraps
fborello-lambda Dec 17, 2024
ea8a867
refactor: Metrics struct to have a complex dashboard
fborello-lambda Dec 17, 2024
1d45ecd
pr_comments: remove cfg_if for metrics
fborello-lambda Dec 18, 2024
d1eb417
chore: lint
fborello-lambda Dec 18, 2024
6b72066
test: ci_test
fborello-lambda Dec 18, 2024
0538e18
Merge branch 'main' into core/prometheus_grafana
fborello-lambda Dec 18, 2024
83d203e
test: ci_test change ports
fborello-lambda Dec 18, 2024
728b79e
Merge branch 'core/prometheus_grafana' of github.com:lambdaclass/ethr…
fborello-lambda Dec 18, 2024
3603da2
fix: block_producer
fborello-lambda Dec 18, 2024
13777f3
Merge branch 'core/fix_block_producer' into core/prometheus_grafana
fborello-lambda Dec 18, 2024
4a66505
refactor: rename files so it's easier to add new metrics
fborello-lambda Dec 19, 2024
3635e2d
Merge branch 'main' into core/prometheus_grafana
fborello-lambda Dec 23, 2024
1e808d3
Merge branch 'main' into core/prometheus_grafana
fborello-lambda Dec 30, 2024
45fecad
Merge branch 'main' into core/prometheus_grafana
fborello-lambda Jan 2, 2025
d3bd684
Update cmd/ethrex/ethrex.rs
fborello-lambda Jan 3, 2025
ed26ea2
fix: lint
fborello-lambda Jan 3, 2025
a33eacf
Merge branch 'main' into core/prometheus_grafana
ilitteri Jan 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions cmd/ethrex/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ redb = { workspace = true, optional = true }
cfg-if = "1.0.0"

ethrex-dev = { path = "../../crates/blockchain/dev", optional = true }
ethrex-metrics = { path = "../../crates/blockchain/metrics" }

[[bin]]
name = "ethrex"
Expand All @@ -42,6 +43,7 @@ path = "./ethrex.rs"
[features]
default = ["dep:ethrex-storage", "libmdbx"]
dev = ["dep:ethrex-dev"]
metrics = ["ethrex-blockchain/metrics"]
libmdbx = ["dep:libmdbx", "ethrex-storage/libmdbx"]
redb = ["dep:redb", "ethrex-storage/redb"]
l2 = ["dep:ethrex-l2", "ethrex-vm/l2"]
Expand Down
6 changes: 6 additions & 0 deletions cmd/ethrex/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ pub fn cli() -> Command {
.required(false)
.value_name("BLOCKS_DIR_PATH"),
)
.arg(
Arg::new("metrics.port")
.long("metrics.port")
.required(false)
.value_name("PROMETHEUS_METRICS_PORT"),
)
.subcommand(
Command::new("removedb").about("Remove the database").arg(
Arg::new("datadir")
Expand Down
11 changes: 11 additions & 0 deletions cmd/ethrex/ethrex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,17 @@ async fn main() {

tracker.spawn(rpc_api);

// Check if the metrics.port is present, else set it to 0
let metrics_port = matches
.get_one::<String>("metrics.port")
.map_or("0".to_string(), |v| v.clone());

// Start the metrics_api with the given metrics.port if it's != 0
if metrics_port != *"0" {
let metrics_api = ethrex_metrics::api::start_prometheus_metrics_api(metrics_port);
tracker.spawn(metrics_api);
}
fborello-lambda marked this conversation as resolved.
Show resolved Hide resolved

// We do not want to start the networking module if the l2 feature is enabled.
cfg_if::cfg_if! {
if #[cfg(feature = "l2")] {
Expand Down
14 changes: 9 additions & 5 deletions cmd/ethrex_l2/src/commands/test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::config::EthrexL2Config;
use bytes::Bytes;
use clap::Subcommand;
use ethereum_types::{Address, H160, H256, U256};
use ethereum_types::{Address, H256, U256};
use ethrex_blockchain::constants::TX_GAS_COST;
use ethrex_l2_sdk::eth_client::{eth_sender::Overrides, EthClient};
use keccak_hash::keccak;
Expand Down Expand Up @@ -72,11 +72,15 @@ async fn transfer_from(
let client = EthClient::new(&cfg.network.l2_rpc_url);
let private_key = SecretKey::from_slice(pk.parse::<H256>().unwrap().as_bytes()).unwrap();

let mut buffer = [0u8; 32];
let public_key = private_key.public_key(secp256k1::SECP256K1).serialize();
buffer.copy_from_slice(&public_key[1..]);
let public_key = private_key
.public_key(secp256k1::SECP256K1)
.serialize_uncompressed();
let hash = keccak(&public_key[1..]);

let address = H160::from(keccak(buffer));
// Get the last 20 bytes of the hash
let address_bytes: [u8; 20] = hash.as_ref().get(12..32).unwrap().try_into().unwrap();

let address = Address::from(address_bytes);
let nonce = client.get_nonce(address).await.unwrap();

let mut retries = 0;
Expand Down
3 changes: 3 additions & 0 deletions crates/blockchain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ ethrex-vm = { path = "../vm", default-features = false }

k256 = { version = "0.13.3", features = ["ecdh"] }

ethrex-metrics = { path = "./metrics", default-features = false }

[dev-dependencies]
serde_json.workspace = true
hex = "0.4.3"
Expand All @@ -35,3 +37,4 @@ libmdbx = [
"ethrex-vm/libmdbx",
]
c-kzg =["ethrex-core/c-kzg"]
metrics = ["ethrex-metrics/api"]
2 changes: 1 addition & 1 deletion crates/blockchain/dev/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ COPY --from=planner /ethrex/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json

COPY . .
RUN cargo build --release --features dev
RUN cargo build --release --features "dev,metrics"

FROM ubuntu:24.04
WORKDIR /usr/local/bin
Expand Down
8 changes: 7 additions & 1 deletion crates/blockchain/dev/docker-compose-dev.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# If this dev container is run in the same machine as the L2 node
# we have to run this docker-compose with the .overrides file too
# example: docker compose -f docker-compose-dev.yaml -f docker-compose-metrics-l1.override.yaml up
include:
- ../metrics/docker-compose-metrics.yaml

services:
ethrex:
restart: always
Expand All @@ -10,4 +16,4 @@ services:
- 127.0.0.1:8545:8545
volumes:
- ../../../test_data/genesis-l1.json:/genesis-l1.json
command: --network /genesis-l1.json --http.addr 0.0.0.0 --http.port 8545
command: --network /genesis-l1.json --http.addr 0.0.0.0 --http.port 8545 --metrics.port 3701
28 changes: 28 additions & 0 deletions crates/blockchain/metrics/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "ethrex-metrics"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tokio.workspace = true
tracing.workspace = true
thiserror.workspace = true
serde_json.workspace = true
serde.workspace = true

ethrex-core = { path = "../../common", default-features = false }

prometheus = "0.13.4"

# TODO: remove?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should we do about this TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left that TODO in case we want an api made by ourselves, do you think we can remove the comment?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not removed, but updated with this context

axum = "0.7.9"


[lib]
path = "./mod.rs"

[features]
default = ["api"]
api = []
37 changes: 37 additions & 0 deletions crates/blockchain/metrics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Metrics

A `docker-compose` is used to bundle prometheus and grafana services, the `*overrides` files define the ports and mounts the prometheus' configuration file.
If a new dashboard is designed just for the L1 or L2, it can be mounted only in that `*overrides` file.

To run the node with metrics, the next steps should be followed:
1. Build the `ethrex` binary with the `metrics` feature enabled.
2. Set the `--metrics.port` cli arg of the ethrex binary to match the port defined in `metrics/provisioning/prometheus/prometheus*.yaml`
3. Run the docker containers, example with the L2:

```sh
docker compose -f docker-compose-metrics.yaml -f docker-compose-metrics-l2.override.yaml up
```

>[!NOTE]
> The L2's Makefile automatically starts the prometheus and grafana services with `make init`. For the L1 used in dev mode and the L2.


- For the L2 we use the following files in conjunction:
- `docker-compose-metrics.yaml`
- `docker-compose-metrics-l2.overrides.yaml`
- The defaults are:
- PORT `3702` &rarr; metrics API (used by prometheus)
- PORT `3802` &rarr; Grafana
- usr: `admin`
- pwd: `admin`
- PORT `9092` &rarr; Prometheus

- For the L1 dev we use the following files in conjunction:
- `docker-compose-metrics.yaml`
- `docker-compose-metrics-l1-dev.overrides.yaml`
- The defaults are:
- PORT `3701` &rarr; metrics API (used by prometheus)
- PORT `3801` &rarr; Grafana
- usr: `admin`
- pwd: `admin`
- PORT `9091` &rarr; Prometheus
19 changes: 19 additions & 0 deletions crates/blockchain/metrics/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use axum::{routing::get, Router};

use crate::{metrics_transactions::METRICS_TX, MetricsApiError};

pub async fn start_prometheus_metrics_api(port: String) -> Result<(), MetricsApiError> {
let app = Router::new()
.route("/metrics", get(get_metrics))
.route("/health", get("Service Up"));

// Start the axum app
let listener = tokio::net::TcpListener::bind(&format!("0.0.0.0:{port}")).await?;
axum::serve(listener, app).await?;

Ok(())
}

async fn get_metrics() -> String {
METRICS_TX.gather_metrics()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
prometheus:
volumes:
- ../metrics/provisioning/prometheus/prometheus_l1_dev.yaml:/etc/prometheus/prometheus.yaml
ports:
- "9091:9090"
grafana:
ports:
- "3801:3000"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
prometheus:
volumes:
- ../metrics/provisioning/prometheus/prometheus_l2.yaml:/etc/prometheus/prometheus.yaml
ports:
- "9092:9090"
grafana:
ports:
- "3802:3000"
15 changes: 15 additions & 0 deletions crates/blockchain/metrics/docker-compose-metrics.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# example: docker compose -f docker-compose-metrics.yaml -f docker-compose-metrics-l2.override.yaml up
services:
prometheus:
image: prom/prometheus
command: --config.file=/etc/prometheus/prometheus.yaml
#volumes: defined in the .overrides file
#ports: defined in the .overrides file
grafana:
image: grafana/grafana
volumes:
- ./provisioning/grafana_provisioning/dashboards:/etc/grafana/provisioning/dashboards
- ./provisioning/grafana_provisioning/datasources:/etc/grafana/provisioning/datasources
#ports: defined in the .overrides file
depends_on:
- prometheus
Loading
Loading