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: ...