From 8291a493c735d56f2f81d69c544fffea0bb8088f Mon Sep 17 00:00:00 2001 From: Noah Markert Date: Fri, 3 Apr 2026 11:21:23 +0200 Subject: [PATCH] resolves #19403 Report the rust compiler version used in the prometheus metrics (#19643) # What is done? - resolves #19403 - Adds build-time Rust compiler detection and captures the rustc --version value during the build. - Exposes the captured compiler version from the Rust extension via a new Python-callable function. - Exports a new Prometheus metric for rustc version. # How to test? - compile `poetry install` - add `enable_metrics: true` and ```yaml resources: - compress: false names: - client - federation - metrics ``` to homeserver.yaml - start synapse - find the rustc version at `http://localhost:8008/_synapse/metrics` ### Pull Request Checklist * [x] Pull request is based on the develop branch * [x] Pull request includes a [changelog file](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#changelog). The entry should: - Be a short description of your change which makes sense to users. "Fixed a bug that prevented receiving messages from other servers." instead of "Moved X method from `EventStore` to `EventWorkerStore`.". - Use markdown where necessary, mostly for `code blocks`. - End with either a period (.) or an exclamation mark (!). - Start with a capital letter. - Feel free to credit yourself, by adding a sentence "Contributed by @github_username." or "Contributed by [Your Name]." to the end of the entry. * [x] [Code style](https://element-hq.github.io/synapse/latest/code_style.html) is correct (run the [linters](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#run-the-linters)) --------- Co-authored-by: Quentin Gliech --- Cargo.lock | 16 ++++++++++++++++ changelog.d/19643.feature | 1 + rust/Cargo.toml | 1 + rust/build.rs | 6 ++++++ rust/src/lib.rs | 9 +++++++++ synapse/metrics/__init__.py | 10 ++++++++-- synapse/synapse_rust/__init__.pyi | 1 + 7 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 changelog.d/19643.feature diff --git a/Cargo.lock b/Cargo.lock index 5cb2ab58af..e1747182e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1078,6 +1078,15 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustls" version = "0.23.31" @@ -1169,6 +1178,12 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.228" @@ -1330,6 +1345,7 @@ dependencies = [ "pythonize", "regex", "reqwest", + "rustc_version", "serde", "serde_json", "sha2", diff --git a/changelog.d/19643.feature b/changelog.d/19643.feature new file mode 100644 index 0000000000..0851623fbf --- /dev/null +++ b/changelog.d/19643.feature @@ -0,0 +1 @@ +Report the Rust compiler version used in the Prometheus metrics. Contributed by Noah Markert. \ No newline at end of file diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 8199a4e02b..bca2f6ed70 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -64,3 +64,4 @@ default = ["extension-module"] [build-dependencies] blake2 = "0.10.4" hex = "0.4.3" +rustc_version = "0.4.1" diff --git a/rust/build.rs b/rust/build.rs index 8755f3bfa3..2a99a9b95d 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -8,6 +8,7 @@ use std::path::PathBuf; use blake2::{Blake2b512, Digest}; +use rustc_version::version_meta; fn main() -> Result<(), std::io::Error> { let mut dirs = vec![PathBuf::from("src")]; @@ -48,6 +49,11 @@ fn main() -> Result<(), std::io::Error> { let hex_digest = hex::encode(hasher.finalize()); println!("cargo:rustc-env=SYNAPSE_RUST_DIGEST={hex_digest}"); + let rustc_version = version_meta() + .map(|v| v.short_version_string) + .unwrap_or_else(|_| "unknown".to_string()); + println!("cargo:rustc-env=SYNAPSE_RUSTC_VERSION={}", rustc_version,); + // The default rules don't pick up trivial changes to the workspace config // files, but we need to rebuild if those change to pick up the changed // hashes. diff --git a/rust/src/lib.rs b/rust/src/lib.rs index a6e01fce64..3b049a51b7 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -30,6 +30,14 @@ fn get_rust_file_digest() -> &'static str { env!("SYNAPSE_RUST_DIGEST") } +/// Returns the `rustc` version used when this native module was built. +/// +/// This value is embedded at build time, so it can be exported as a prometheus metrics. +#[pyfunction] +pub fn get_rustc_version() -> &'static str { + env!("SYNAPSE_RUSTC_VERSION") +} + /// Formats the sum of two numbers as string. #[pyfunction] #[pyo3(text_signature = "(a, b, /)")] @@ -50,6 +58,7 @@ fn reset_logging_config() { fn synapse_rust(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(sum_as_string, m)?)?; m.add_function(wrap_pyfunction!(get_rust_file_digest, m)?)?; + m.add_function(wrap_pyfunction!(get_rustc_version, m)?)?; m.add_function(wrap_pyfunction!(reset_logging_config, m)?)?; acl::register_module(py, m)?; diff --git a/synapse/metrics/__init__.py b/synapse/metrics/__init__.py index ba4334e372..cf9aaa7f2d 100644 --- a/synapse/metrics/__init__.py +++ b/synapse/metrics/__init__.py @@ -62,6 +62,7 @@ from twisted.web.server import Request import synapse.metrics._reactor_metrics # noqa: F401 from synapse.metrics._gc import MIN_TIME_BETWEEN_GCS, install_gc_manager from synapse.metrics._types import Collector +from synapse.synapse_rust import get_rustc_version from synapse.types import StrSequence from synapse.util import SYNAPSE_VERSION @@ -69,6 +70,9 @@ logger = logging.getLogger(__name__) METRICS_PREFIX = "/_synapse/metrics" +# Rust version used for compilation +RUSTC_VERSION = get_rustc_version() + HAVE_PROC_SELF_STAT = os.path.exists("/proc/self/stat") SERVER_NAME_LABEL = "server_name" @@ -672,15 +676,17 @@ event_processing_lag_by_event = Histogram( # consider this process-level because all Synapse homeservers running in the process # will use the same Synapse version. build_info = Gauge( # type: ignore[missing-server-name-label] - "synapse_build_info", "Build information", ["pythonversion", "version", "osversion"] + "synapse_build_info", + "Build information", + ["pythonversion", "version", "osversion", "rustcversion"], ) build_info.labels( " ".join([platform.python_implementation(), platform.python_version()]), SYNAPSE_VERSION, " ".join([platform.system(), platform.release()]), + RUSTC_VERSION, ).set(1) - synapse_server_name_info = Gauge( "synapse_server_name_info", "Maps Synapse `server_name`s to the `instance`s they're hosted on", diff --git a/synapse/synapse_rust/__init__.pyi b/synapse/synapse_rust/__init__.pyi index d25c609106..cb3eb7df07 100644 --- a/synapse/synapse_rust/__init__.pyi +++ b/synapse/synapse_rust/__init__.pyi @@ -1,3 +1,4 @@ def sum_as_string(a: int, b: int) -> str: ... def get_rust_file_digest() -> str: ... def reset_logging_config() -> None: ... +def get_rustc_version() -> str: ...