rust: Add a Prometheus metrics exporter

The -prometheusmetrics=host_name:port config option enables the metrics
exporter.
This commit is contained in:
Jack Grigg 2020-10-17 00:54:04 +01:00
parent 8482ed6356
commit a79ffa3b50
5 changed files with 490 additions and 5 deletions

444
Cargo.lock generated
View File

@ -61,6 +61,15 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "atomic-shim"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d20fdac7156779a1a30d970e838195558b4810dd06aa69e7c7461bdc518edf9b"
dependencies = [
"crossbeam",
]
[[package]]
name = "autocfg"
version = "1.0.1"
@ -103,6 +112,12 @@ dependencies = [
"crunchy",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bitvec"
version = "0.18.5"
@ -181,6 +196,12 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]]
name = "cfg-if"
version = "0.1.10"
@ -236,7 +257,7 @@ dependencies = [
"cfg-if 0.1.10",
"crossbeam-channel 0.4.4",
"crossbeam-deque",
"crossbeam-epoch",
"crossbeam-epoch 0.8.2",
"crossbeam-queue",
"crossbeam-utils 0.7.2",
]
@ -267,7 +288,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
dependencies = [
"crossbeam-epoch",
"crossbeam-epoch 0.8.2",
"crossbeam-utils 0.7.2",
"maybe-uninit",
]
@ -283,7 +304,20 @@ dependencies = [
"crossbeam-utils 0.7.2",
"lazy_static",
"maybe-uninit",
"memoffset",
"memoffset 0.5.6",
"scopeguard",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils 0.8.3",
"lazy_static",
"memoffset 0.6.3",
"scopeguard",
]
@ -341,6 +375,16 @@ dependencies = [
"crypto_api",
]
[[package]]
name = "ctor"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "curve25519-dalek"
version = "3.0.2"
@ -354,6 +398,16 @@ dependencies = [
"zeroize",
]
[[package]]
name = "dashmap"
version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
dependencies = [
"cfg-if 1.0.0",
"num_cpus",
]
[[package]]
name = "digest"
version = "0.9.0"
@ -418,6 +472,12 @@ dependencies = [
"subtle",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "fpe"
version = "0.4.0"
@ -443,6 +503,21 @@ version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
[[package]]
name = "futures-channel"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94"
[[package]]
name = "futures-cpupool"
version = "0.1.8"
@ -453,6 +528,24 @@ dependencies = [
"num_cpus",
]
[[package]]
name = "futures-task"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80"
[[package]]
name = "futures-util"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1"
dependencies = [
"futures-core",
"futures-task",
"pin-project-lite",
"pin-utils",
]
[[package]]
name = "generic-array"
version = "0.14.4"
@ -486,6 +579,12 @@ dependencies = [
"subtle",
]
[[package]]
name = "hashbrown"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
[[package]]
name = "hermit-abi"
version = "0.1.18"
@ -501,6 +600,88 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "http"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dfb77c123b4e2f72a2069aeae0b4b4949cc7e966df277813fc16347e7549737"
dependencies = [
"bytes",
"http",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691"
[[package]]
name = "httpdate"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
[[package]]
name = "hyper"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bf09f61b52cfcf4c00de50df88ae423d6c02354e385a86341133b5338630ad1"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project",
"socket2",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "indexmap"
version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "instant"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "jubjub"
version = "0.5.1"
@ -541,6 +722,7 @@ dependencies = [
"jubjub",
"libc",
"metrics",
"metrics-exporter-prometheus",
"rand_core",
"subtle",
"tracing",
@ -552,6 +734,15 @@ dependencies = [
"zcash_proofs",
]
[[package]]
name = "lock_api"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.14"
@ -561,6 +752,15 @@ dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "mach"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
dependencies = [
"libc",
]
[[package]]
name = "matchers"
version = "0.0.1"
@ -591,6 +791,15 @@ dependencies = [
"autocfg",
]
[[package]]
name = "memoffset"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d"
dependencies = [
"autocfg",
]
[[package]]
name = "metrics"
version = "0.14.2"
@ -601,6 +810,21 @@ dependencies = [
"proc-macro-hack",
]
[[package]]
name = "metrics-exporter-prometheus"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d23bb354bd7dd5d244f2e9a389a0c3249bb6b994aca71bd6c2f7cd6fa2657fc"
dependencies = [
"hyper",
"metrics",
"metrics-util",
"parking_lot",
"quanta",
"thiserror",
"tokio",
]
[[package]]
name = "metrics-macros"
version = "0.2.0"
@ -615,6 +839,56 @@ dependencies = [
"syn",
]
[[package]]
name = "metrics-util"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ace44e2c64f785c3c37605ecf7504e5fc4efbb2936a49cc56c1084d79657a4d"
dependencies = [
"aho-corasick",
"atomic-shim",
"crossbeam-epoch 0.9.3",
"crossbeam-utils 0.8.3",
"dashmap",
"indexmap",
"metrics",
"ordered-float",
"parking_lot",
"quanta",
"sketches-ddsketch",
]
[[package]]
name = "mio"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
dependencies = [
"libc",
"log",
"miow",
"ntapi",
"winapi",
]
[[package]]
name = "miow"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
"winapi",
]
[[package]]
name = "ntapi"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
dependencies = [
"winapi",
]
[[package]]
name = "num-bigint"
version = "0.3.2"
@ -667,6 +941,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "ordered-float"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "766f840da25490628d8e63e529cd21c014f6600c6b8517add12a6fa6167a6218"
dependencies = [
"num-traits",
]
[[package]]
name = "pairing"
version = "0.18.0"
@ -677,12 +960,63 @@ dependencies = [
"group",
]
[[package]]
name = "parking_lot"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
dependencies = [
"instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
dependencies = [
"cfg-if 1.0.0",
"instant",
"libc",
"redox_syscall 0.2.5",
"smallvec",
"winapi",
]
[[package]]
name = "pin-project"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc174859768806e91ae575187ada95c91a29e96a98dc5d2cd9a1fed039501ba6"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a490329918e856ed1b083f244e3bfe2d8c4f336407e4ea9e1a9f479ff09049e5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pin-project-lite"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "ppv-lite86"
version = "0.2.10"
@ -704,6 +1038,21 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "quanta"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e76a3afdefd0ce2c0363bf3146271e947782240ea617885dd64e56c4de9fb3c9"
dependencies = [
"atomic-shim",
"ctor",
"libc",
"mach",
"once_cell",
"raw-cpuid",
"winapi",
]
[[package]]
name = "quote"
version = "1.0.9"
@ -760,12 +1109,30 @@ dependencies = [
"rand_core",
]
[[package]]
name = "raw-cpuid"
version = "9.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c27cb5785b85bd05d4eb171556c9a1a514552e26123aeae6bb7d811353148026"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_syscall"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.3.5"
@ -773,7 +1140,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [
"getrandom",
"redox_syscall",
"redox_syscall 0.1.57",
"rust-argon2",
]
@ -786,7 +1153,6 @@ dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
@ -865,6 +1231,28 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "sketches-ddsketch"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76a77a8fd93886010f05e7ea0720e569d6d16c65329dbe3ec033bbbccccb017b"
[[package]]
name = "smallvec"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
[[package]]
name = "socket2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "subtle"
version = "2.4.0"
@ -922,6 +1310,36 @@ dependencies = [
"winapi",
]
[[package]]
name = "tokio"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134af885d758d645f0f0505c9a8b3f9bf8a348fd822e112ab5248138348f1722"
dependencies = [
"autocfg",
"libc",
"mio",
"pin-project-lite",
"tokio-macros",
]
[[package]]
name = "tokio-macros"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tower-service"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
[[package]]
name = "tracing"
version = "0.1.25"
@ -982,6 +1400,12 @@ dependencies = [
"tracing-core",
]
[[package]]
name = "try-lock"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]]
name = "typenum"
version = "1.13.0"
@ -1000,6 +1424,16 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "want"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
dependencies = [
"log",
"try-lock",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"

View File

@ -39,6 +39,7 @@ ed25519-zebra = "2.0.0"
# Metrics
metrics = "0.14.2"
metrics-exporter-prometheus = "0.3"
# Temporary workaround for https://github.com/myrrlyn/funty/issues/3
funty = "=1.1.0"

View File

@ -64,6 +64,8 @@
#include "zmq/zmqnotificationinterface.h"
#endif
#include <rust/metrics.h>
#include "librustzcash.h"
using namespace std;
@ -351,6 +353,8 @@ std::string HelpMessage(HelpMessageMode mode)
#ifndef WIN32
strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), BITCOIN_PID_FILENAME));
#endif
strUsage += HelpMessageOpt("-prometheusmetrics=<host_name>:<port>", _("Expose node metrics in the Prometheus exposition format. "
"An HTTP listener will be started on the configured hostname and port, which responds to GET requests on any request path."));
strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. "
"Warning: Reverting this setting requires re-downloading the entire blockchain. "
"(default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)"), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
@ -1221,6 +1225,17 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Count uptime
MarkStartTime();
std::string prometheusMetricsArg = GetArg("-prometheusmetrics", "");
if (prometheusMetricsArg != "") {
// Start up the metrics runtime. This spins off a Rust thread that runs
// the Prometheus exporter. We just let this thread die at process end
// ¯\_(ツ)_/¯
LogPrintf("metrics thread start");
if (!metrics_run(prometheusMetricsArg.c_str())) {
return InitError(strprintf(_("Failed to start Prometheus metrics exporter on '%s'"), prometheusMetricsArg));
}
}
if ((chainparams.NetworkIDString() != "regtest") &&
GetBoolArg("-showmetrics", isatty(STDOUT_FILENO)) &&
!fPrintToConsole && !GetBoolArg("-daemon", false)) {

View File

@ -11,6 +11,14 @@
extern "C" {
#endif
/// Initializes the metrics runtime and runs the Prometheus exporter in a new
/// thread.
///
/// listen_address is a string like <host_name>:<port>.
///
/// Returns false if listen_address was not a valid SocketAddr.
bool metrics_run(const char* listen_address);
struct MetricsCallsite;
typedef struct MetricsCallsite MetricsCallsite;

View File

@ -1,6 +1,33 @@
use libc::{c_char, c_double};
use metrics::{try_recorder, GaugeValue, Key, KeyData};
use metrics_exporter_prometheus::PrometheusBuilder;
use std::ffi::CStr;
use std::net::SocketAddr;
use tracing::error;
#[no_mangle]
pub extern "C" fn metrics_run(listen_address: *const c_char) -> bool {
let listen_address = unsafe { CStr::from_ptr(listen_address) }.to_str().unwrap();
listen_address
.parse::<SocketAddr>()
.map_err(|e| {
error!(
"Invalid Prometheus metrics address '{}': {}",
listen_address, e
);
()
})
.and_then(|addr| {
PrometheusBuilder::new()
.listen_address(addr)
.install()
.map_err(|e| {
error!("Failed to start Prometheus metrics exporter: {:?}", e);
()
})
})
.is_ok()
}
pub struct FfiCallsite {
key_data: KeyData,