diff --git a/Cargo.lock b/Cargo.lock index 1aa8892..ada7064 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -319,6 +319,29 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "aws-lc-rs" +version = "1.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dabb68eb3a7aa08b46fddfd59a3d55c978243557a90ab804769f7e20e67d2b01" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77926887776171ced7d662120a75998e444d3750c951abfe07f90da130514b1f" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -418,6 +441,29 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.8.0", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease 0.2.31", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.98", + "which", +] + [[package]] name = "bip21" version = "0.5.0" @@ -586,9 +632,20 @@ version = "1.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9" dependencies = [ + "jobserver", + "libc", "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -624,6 +681,17 @@ dependencies = [ "inout", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.30" @@ -663,6 +731,15 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "cms" version = "0.2.3" @@ -706,6 +783,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -721,6 +808,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -833,6 +929,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.13.0" @@ -970,6 +1072,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -979,6 +1087,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures" version = "0.3.31" @@ -1135,6 +1249,12 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + [[package]] name = "h2" version = "0.3.26" @@ -1154,6 +1274,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.2.0", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.13.2" @@ -1175,6 +1314,9 @@ name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", +] [[package]] name = "hashlink" @@ -1332,7 +1474,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -1355,6 +1497,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2 0.4.8", "http 1.2.0", "http-body 1.0.1", "httparse", @@ -1363,6 +1506,7 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", + "want", ] [[package]] @@ -1376,7 +1520,25 @@ dependencies = [ "hyper 0.14.32", "rustls 0.21.12", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +dependencies = [ + "futures-util", + "http 1.2.0", + "hyper 1.6.0", + "hyper-util", + "rustls 0.23.25", + "rustls-native-certs 0.8.1", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.2", + "tower-service", ] [[package]] @@ -1386,12 +1548,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", + "futures-channel", "futures-util", "http 1.2.0", "http-body 1.0.1", "hyper 1.6.0", "pin-project-lite", + "socket2 0.5.8", "tokio", + "tower-service", + "tracing", ] [[package]] @@ -1617,6 +1783,15 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.77" @@ -1655,6 +1830,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "ldk-node" version = "0.5.0+git" @@ -1706,6 +1887,8 @@ dependencies = [ "lapin", "ldk-node", "ldk-server-protos", + "metrics", + "metrics-exporter-prometheus", "prost", "rand 0.8.5", "rusqlite", @@ -1747,6 +1930,16 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + [[package]] name = "libm" version = "0.2.11" @@ -1940,6 +2133,53 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "metrics" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a7deb012b3b2767169ff203fadb4c6b0b82b947512e5eb9e0b78c2e186ad9e3" +dependencies = [ + "ahash", + "portable-atomic", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7399781913e5393588a8d8c6a2867bf85fb38eaf2502fdce465aad2dc6f034" +dependencies = [ + "base64 0.22.1", + "http-body-util", + "hyper 1.6.0", + "hyper-rustls 0.27.5", + "hyper-util", + "indexmap", + "ipnet", + "metrics", + "metrics-util", + "quanta", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "metrics-util" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd4884b1dd24f7d6628274a2f5ae22465c337c5ba065ec9b6edccddf8acc673" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.15.2", + "metrics", + "quanta", + "rand 0.8.5", + "rand_xoshiro", + "sketches-ddsketch", +] + [[package]] name = "mime" version = "0.3.17" @@ -2257,6 +2497,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + [[package]] name = "possiblyrandom" version = "0.2.0" @@ -2291,6 +2537,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "prettyplease" +version = "0.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" +dependencies = [ + "proc-macro2", + "syn 2.0.98", +] + [[package]] name = "proc-macro2" version = "1.0.93" @@ -2323,7 +2579,7 @@ dependencies = [ "log", "multimap", "petgraph", - "prettyplease", + "prettyplease 0.1.25", "prost", "prost-types", "regex", @@ -2354,6 +2610,21 @@ dependencies = [ "prost", ] +[[package]] +name = "quanta" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quote" version = "1.0.38" @@ -2423,6 +2694,24 @@ dependencies = [ "getrandom 0.3.1", ] +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "raw-cpuid" +version = "11.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +dependencies = [ + "bitflags 2.8.0", +] + [[package]] name = "rc2" version = "0.8.1" @@ -2492,11 +2781,11 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.32", - "hyper-rustls", + "hyper-rustls 0.24.2", "ipnet", "js-sys", "log", @@ -2512,7 +2801,7 @@ dependencies = [ "sync_wrapper", "system-configuration", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tokio-socks", "tower-service", "url", @@ -2557,6 +2846,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rusticata-macros" version = "4.1.0" @@ -2611,6 +2906,7 @@ version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ + "aws-lc-rs", "once_cell", "ring", "rustls-pki-types", @@ -2627,7 +2923,7 @@ checksum = "2a980454b497c439c274f2feae2523ed8138bbd3d323684e1435fec62f800481" dependencies = [ "log", "rustls 0.23.25", - "rustls-native-certs", + "rustls-native-certs 0.7.3", "rustls-pki-types", "rustls-webpki 0.102.8", ] @@ -2642,7 +2938,19 @@ dependencies = [ "rustls-pemfile 2.2.0", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 2.11.1", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework 3.2.0", ] [[package]] @@ -2696,6 +3004,7 @@ version = "0.103.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -2786,7 +3095,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.8.0", - "core-foundation", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +dependencies = [ + "bitflags 2.8.0", + "core-foundation 0.10.0", "core-foundation-sys", "libc", "security-framework-sys", @@ -2892,6 +3214,12 @@ dependencies = [ "libc", ] +[[package]] +name = "sketches-ddsketch" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" + [[package]] name = "slab" version = "0.4.9" @@ -3010,7 +3338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -3184,6 +3512,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls 0.23.25", + "tokio", +] + [[package]] name = "tokio-socks" version = "0.5.2" diff --git a/ldk-server/Cargo.toml b/ldk-server/Cargo.toml index ded2046..b27977a 100644 --- a/ldk-server/Cargo.toml +++ b/ldk-server/Cargo.toml @@ -18,6 +18,8 @@ rusqlite = { version = "0.31.0", features = ["bundled"] } rand = { version = "0.8.5", default-features = false } async-trait = { version = "0.1.85", default-features = false } toml = { version = "0.8.9", default-features = false, features = ["parse"] } +metrics = "0.24.1" +metrics-exporter-prometheus = "0.16.2" # Required for RabittMQ based EventPublisher. Only enabled for `events-rabbitmq` feature. lapin = { version = "2.4.0", features = ["rustls"], default-features = false, optional = true } diff --git a/ldk-server/src/api/metrics.rs b/ldk-server/src/api/metrics.rs new file mode 100644 index 0000000..382fcd0 --- /dev/null +++ b/ldk-server/src/api/metrics.rs @@ -0,0 +1,14 @@ +use hyper::body::Incoming; +use hyper::Request; + +use crate::api::error::LdkServerError; +use crate::service::Context; + +pub(crate) const GET_METRICS: &str = "metrics"; + +pub(crate) fn handle_metrics_request( + context: Context, _request: Request, +) -> Result { + let metrics = context.prometheus_handle.render(); + Ok(metrics) +} diff --git a/ldk-server/src/api/mod.rs b/ldk-server/src/api/mod.rs index c1b0fa2..05b99cd 100644 --- a/ldk-server/src/api/mod.rs +++ b/ldk-server/src/api/mod.rs @@ -10,6 +10,7 @@ pub(crate) mod get_payment_details; pub(crate) mod list_channels; pub(crate) mod list_forwarded_payments; pub(crate) mod list_payments; +pub(crate) mod metrics; pub(crate) mod onchain_receive; pub(crate) mod onchain_send; pub(crate) mod open_channel; diff --git a/ldk-server/src/main.rs b/ldk-server/src/main.rs index 3f8fe06..1e116bc 100644 --- a/ldk-server/src/main.rs +++ b/ldk-server/src/main.rs @@ -1,12 +1,14 @@ mod api; mod io; mod service; +mod telemetry; mod util; use crate::service::NodeService; use ldk_node::{Builder, Event, Node}; +use telemetry::setup_prometheus; use tokio::net::TcpListener; use tokio::signal::unix::SignalKind; @@ -108,6 +110,8 @@ fn main() { let event_publisher: Arc = Arc::new(NoopEventPublisher); + let prometheus_handle = setup_prometheus(); + #[cfg(feature = "events-rabbitmq")] let event_publisher: Arc = { let rabbitmq_config = RabbitMqConfig { @@ -219,7 +223,6 @@ fn main() { claim_from_onchain_tx, outbound_amount_forwarded_msat } => { - println!("PAYMENT_FORWARDED: with outbound_amount_forwarded_msat {}, total_fee_earned_msat: {}, inbound channel: {}, outbound channel: {}", outbound_amount_forwarded_msat.unwrap_or(0), total_fee_earned_msat.unwrap_or(0), prev_channel_id, next_channel_id ); @@ -279,7 +282,7 @@ fn main() { match res { Ok((stream, _)) => { let io_stream = TokioIo::new(stream); - let node_service = NodeService::new(Arc::clone(&node), Arc::clone(&paginated_store)); + let node_service = NodeService::new(Arc::clone(&node), Arc::clone(&paginated_store), Arc::new(prometheus_handle.clone())); runtime.spawn(async move { if let Err(err) = http1::Builder::new().serve_connection(io_stream, node_service).await { eprintln!("Failed to serve connection: {}", err); diff --git a/ldk-server/src/service.rs b/ldk-server/src/service.rs index 328ded0..4c7d7d1 100644 --- a/ldk-server/src/service.rs +++ b/ldk-server/src/service.rs @@ -5,6 +5,7 @@ use hyper::body::{Bytes, Incoming}; use hyper::service::Service; use hyper::{Request, Response, StatusCode}; +use metrics_exporter_prometheus::PrometheusHandle; use prost::Message; use crate::api::bolt11_receive::{handle_bolt11_receive_request, BOLT11_RECEIVE_PATH}; @@ -24,6 +25,7 @@ use crate::api::list_forwarded_payments::{ handle_list_forwarded_payments_request, LIST_FORWARDED_PAYMENTS_PATH, }; use crate::api::list_payments::{handle_list_payments_request, LIST_PAYMENTS_PATH}; +use crate::api::metrics::{handle_metrics_request, GET_METRICS}; use crate::api::onchain_receive::{handle_onchain_receive_request, ONCHAIN_RECEIVE_PATH}; use crate::api::onchain_send::{handle_onchain_send_request, ONCHAIN_SEND_PATH}; use crate::api::open_channel::{handle_open_channel, OPEN_CHANNEL_PATH}; @@ -40,17 +42,22 @@ use std::sync::Arc; pub struct NodeService { node: Arc, paginated_kv_store: Arc, + prometheus_handle: Arc, } impl NodeService { - pub(crate) fn new(node: Arc, paginated_kv_store: Arc) -> Self { - Self { node, paginated_kv_store } + pub(crate) fn new( + node: Arc, paginated_kv_store: Arc, + prometheus_handle: Arc, + ) -> Self { + Self { node, paginated_kv_store, prometheus_handle } } } pub(crate) struct Context { pub(crate) node: Arc, pub(crate) paginated_kv_store: Arc, + pub(crate) prometheus_handle: Arc, } impl Service> for NodeService { @@ -62,6 +69,7 @@ impl Service> for NodeService { let context = Context { node: Arc::clone(&self.node), paginated_kv_store: Arc::clone(&self.paginated_kv_store), + prometheus_handle: Arc::clone(&self.prometheus_handle), }; // Exclude '/' from path pattern matching. match &req.uri().path()[1..] { @@ -100,6 +108,21 @@ impl Service> for NodeService { LIST_FORWARDED_PAYMENTS_PATH => { Box::pin(handle_request(context, req, handle_list_forwarded_payments_request)) }, + GET_METRICS => Box::pin(async { + match handle_metrics_request(context, req) { + Ok(metrics) => Ok(Response::builder() + .header("Content-Type", "text/plain") + .body(Full::new(Bytes::from(metrics))) + .unwrap()), + Err(e) => { + let (error_response, status_code) = to_error_response(e); + Ok(Response::builder() + .status(status_code) + .body(Full::new(Bytes::from(error_response.encode_to_vec()))) + .unwrap()) + }, + } + }), path => { let error = format!("Unknown request: {}", path).into_bytes(); Box::pin(async { diff --git a/ldk-server/src/telemetry.rs b/ldk-server/src/telemetry.rs new file mode 100644 index 0000000..397dbd1 --- /dev/null +++ b/ldk-server/src/telemetry.rs @@ -0,0 +1,8 @@ +use metrics_exporter_prometheus::{PrometheusBuilder, PrometheusHandle}; + +pub fn setup_prometheus() -> PrometheusHandle { + let prometheus_builder = PrometheusBuilder::new(); + let handler = + prometheus_builder.install_recorder().expect("failed to install Prometheus recorder"); + handler +}