Skip to content

Commit 90259b5

Browse files
committed
Merge #1414: New API endpoint with extendable metrics
e3b84a4 feat: [#1403] rename field update_at to recorded_at in metrics Sample (Jose Celano) 5099e90 refactor: [#1403] extract Measurement strcut (Jose Celano) 017d977 refactor: [#1403] remove unused code (Jose Celano) af8dbfa feat: [#1403] expose udp-tracker-server metrics expose in REST API (Jose Celano) 786f6f0 feat: [#1403] add extendable-labeled metrics to udp-tracker-server (Jose Celano) 3f51afc feat: [#1403] expose udp-tracker-core metrics expose in REST API (Jose Celano) 9d09337 feat: [#1403] add extendable-labeled metrics to udp-tracker-core (Jose Celano) d717818 feat: [#1403] add extendable-labeled metrics to http-tracker-core and expose in REST API (Jose Celano) 730de9f feat: [#1403] add new package for extendable labeled metrics (Jose Celano) 8a169b1 feat: add protocol method to ServiceBinding (Jose Celano) Pull request description: Relates to: #1263 (comment) It adds a new REST API endpoint with a new extendable format for metrics. In this PR I will only add the metrics for: - Performance - Announce requests - Scrape requests See the complete list [here](#1263 (comment)). It requires emitting the new metrics from the: - HTTP Tracker Core package - UDP Tracker Core package - UDP Tracker Server package The remaining metrics (`torrents` and `peers`) require adding metrics to the tracker core package. ### JSON format **URL:** http://0.0.0.0:1212/api/v1/metrics?token=MyAccessToken **Sample response:** ```json { "metrics":[ { "kind":"counter", "name":"http_tracker_core_announce_requests_received_total", "samples":[ { "value":1, "recorded_at":"2025-04-02T00:00:00+00:00", "labels":[ { "name":"server_binding_ip", "value":"0.0.0.0" }, { "name":"server_binding_port", "value":"7070" }, { "name":"server_binding_protocol", "value":"http" } ] } ] }, { "kind":"gauge", "name":"udp_tracker_server_performance_avg_announce_processing_time_ns", "samples":[ { "value":1.0, "recorded_at":"2025-04-02T00:00:00+00:00", "labels":[ { "name":"server_binding_ip", "value":"0.0.0.0" }, { "name":"server_binding_port", "value":"7070" }, { "name":"server_binding_protocol", "value":"http" } ] } ] } ] } ``` ### Prometheus format **URL:** http://0.0.0.0:1212/api/v1/metrics?token=MyAccessToken&format=prometheus ``` http_tracker_core_announce_requests_received_total{server_binding_ip="0.0.0.0",server_binding_port="7070",server_binding_protocol="http"} 1 udp_tracker_server_performance_avg_announce_processing_time_ns{server_binding_ip="0.0.0.0",server_binding_port="7070",server_binding_protocol="http"} 1 ``` ### Manual Tests You can increase the number of `announce` or `scrape` requests by using the console tracker client. HTTP: ```console cargo run -p torrust-tracker-client --bin http_tracker_client announce http://127.0.0.1:7070 443c7602b4fde83d1154d6d9da48808418b181b6 | jq ``` ```console cargo run -p torrust-tracker-client --bin http_tracker_client scrape http://127.0.0.1:7070 443c7602b4fde83d1154d6d9da48808418b181b6 | jq ``` UDP: ```console cargo run -p torrust-tracker-client --bin udp_tracker_client announce udp://127.0.0.1:6969 443c7602b4fde83d1154d6d9da48808418b181b6 | jq ``` ```console cargo run -p torrust-tracker-client --bin udp_tracker_client scrape udp://127.0.0.1:6969 443c7602b4fde83d1154d6d9da48808418b181b6 | jq ``` ### TODO - [x] Move labeled metrics to `metrics` package. - [x] The metric name and label set must be unique in the array of labeled metrics. Enforce constraint. - [x] Replace primitive types in the new labeled metrics with new tpyes to enforce constraints. For example, metrics names, labels, metric types, etc. - [x] Serialize to Prometheus format. - [x] Serialize/Deserialize from JSON. Needed in the Index. - [x] Inject the rigth URL scheme. It's hardcoded now. - [x] Review what labels we include per metric. For example the "protocol" label can be derived from the URL but it requires parsing the URL and it makes harder to build graphs in Grafana. I guess we should include labels for the type of aggregate data we want to get. - [x] Implement versioning. A given API version must contain a set of labeled metrics. Clients expect some labeled metrics to be included in a API version. We need to initialize the array of metrics with all the expected labeled metrics with the initial value. - [x] Write more tests. - [x] Implement for UDP metrics. It's only implemented for HTTP tracker metrics. This would require merging labeled metrics. - [x] Emit metrics from UDP tracker core. - [x] Emit metrics from UDP tracker server. Discarded: - [ ] ~~Use a f64 for metric values instead of u64.~~. Using `u64` for counter and `f64` for gauge. - [ ] ~~Add a new `namespace` label to avoid conflict for packages using the same metric name.~~ The metric would not be the same with different context, it would be a different source even if they might represent the same thing. For example, a counter for announce requests can be added at the server level, HTTP core level and tracker core level. I think it's better to use a different metric for them. - In Grafana for example you should explicitly exclude labels otherwise you could get duplicate values if two metrics from two different packages have the same name. Notes: - Regarding what I called "versioning", you can describe metrics so they appear in the JSON response even if there are no samples yet. However, for the Prometheus format, they will not be included in the export. A line without a metric value would be an error. We could set the initial value, but it makes sense only for counters. ### Future work - We will probably need some methods for the `MetricCollection` to search for metrics, apply aggregated functions, etc. For example: - Sum all the samples values for a given counter metric (total). For example: total number of requests regardless what label values they have. - We can't deprecate the current `http://0.0.0.0:1212/api/v1/stats` API endpoint until we have the same information in the new endpoint `http://0.0.0.0:1212/api/v1/metrics`. We need to add this type of metrics to the tracker core package too because it's the package we can get `torrents` and `peers` metrics from. See #1263 (comment) - Add tests for the new endpoint. - Deploy to the demo tracker and build a new dashboard in Grafana and compare it with the current dashboard to check if metrics are being collected ok. ACKs for top commit: josecelano: ACK e3b84a4 Tree-SHA512: 5f9fcaca6008b44cda6221fd6dccc486ee512825621d533d510a4a9d0e146982e073a766f290006ffecc1bb7e5478fb81639bf39f2b5b201e91ec45e7885c16a
2 parents 3816446 + e3b84a4 commit 90259b5

File tree

57 files changed

+4358
-128
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+4358
-128
lines changed

.github/workflows/deployment.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ jobs:
7474
cargo publish -p torrust-tracker-configuration
7575
cargo publish -p torrust-tracker-contrib-bencode
7676
cargo publish -p torrust-tracker-located-error
77+
cargo publish -p torrust-tracker-metrics
7778
cargo publish -p torrust-tracker-primitives
7879
cargo publish -p torrust-tracker-test-helpers
7980
cargo publish -p torrust-tracker-torrent-repository

Cargo.lock

Lines changed: 174 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cSpell.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,11 @@
5959
"Eray",
6060
"filesd",
6161
"flamegraph",
62+
"formatjson",
6263
"Freebox",
6364
"Frostegård",
6465
"gecos",
66+
"Gibibytes",
6567
"Grcov",
6668
"hasher",
6769
"healthcheck",
@@ -86,6 +88,7 @@
8688
"kcachegrind",
8789
"kexec",
8890
"keyout",
91+
"Kibibytes",
8992
"kptr",
9093
"lcov",
9194
"leecher",
@@ -96,12 +99,14 @@
9699
"LOGNAME",
97100
"Lphant",
98101
"matchmakes",
102+
"Mebibytes",
99103
"metainfo",
100104
"middlewares",
101105
"misresolved",
102106
"mockall",
103107
"multimap",
104108
"myacicontext",
109+
"ñaca",
105110
"Naim",
106111
"nanos",
107112
"newkey",
@@ -157,6 +162,7 @@
157162
"Swiftbit",
158163
"taiki",
159164
"tdyne",
165+
"Tebibytes",
160166
"tempfile",
161167
"testcontainers",
162168
"thiserror",

packages/axum-rest-tracker-api-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ torrust-rest-tracker-api-core = { version = "3.0.0-develop", path = "../rest-tra
3737
torrust-server-lib = { version = "3.0.0-develop", path = "../server-lib" }
3838
torrust-tracker-clock = { version = "3.0.0-develop", path = "../clock" }
3939
torrust-tracker-configuration = { version = "3.0.0-develop", path = "../configuration" }
40+
torrust-tracker-metrics = { version = "3.0.0-develop", path = "../metrics" }
4041
torrust-tracker-primitives = { version = "3.0.0-develop", path = "../primitives" }
4142
torrust-udp-tracker-server = { version = "3.0.0-develop", path = "../udp-tracker-server" }
4243
tower = { version = "0", features = ["timeout"] }

0 commit comments

Comments
 (0)