Skip to content

Commit

Permalink
add command line options to rust servers (#363)
Browse files Browse the repository at this point in the history
Adds CLI arguments to Rust Pelikan Backends to display usage,
version, and stats information.

Partially addresses #361
  • Loading branch information
brayniac authored Nov 4, 2021
1 parent ce36601 commit fc8e451
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 5 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/rust/core/server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ mod process;
mod threads;

pub use process::{Process, ProcessBuilder};
pub use threads::PERCENTILES;

use metrics::{static_metrics, Counter};

Expand Down
2 changes: 1 addition & 1 deletion src/rust/core/server/src/threads/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub struct Admin {
log_drain: Box<dyn Drain>,
}

static PERCENTILES: &[(&str, f64)] = &[
pub static PERCENTILES: &[(&str, f64)] = &[
("p25", 25.0),
("p50", 50.0),
("p75", 75.0),
Expand Down
2 changes: 1 addition & 1 deletion src/rust/core/server/src/threads/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod listener;
mod traits;
mod worker;

pub use admin::Admin;
pub use admin::{Admin, PERCENTILES};
pub use listener::Listener;
pub use traits::EventLoop;
pub use worker::{MultiWorker, SingleWorker, StorageWorker};
1 change: 1 addition & 0 deletions src/rust/server/pingserver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ harness = false

[dependencies]
backtrace = "0.3.56"
clap = "2.33.3"
config = { path = "../../config" }
entrystore = { path = "../../entrystore" }
logger = { path = "../../logger" }
Expand Down
66 changes: 65 additions & 1 deletion src/rust/server/pingserver/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
extern crate logger;

use backtrace::Backtrace;
use clap::{App, Arg};
use config::PingserverConfig;
use metrics::*;
use pelikan_pingserver_rs::Pingserver;
use server::PERCENTILES;

fn main() {
// custom panic hook to terminate whole process after unwinding
Expand All @@ -17,8 +20,69 @@ fn main() {
std::process::exit(101);
}));

// parse command line options
let matches = App::new(env!("CARGO_BIN_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.version_short("v")
.long_about(
"A rust implementation of, arguably, the most over-engineered ping \
server.\n\n\
The purpose is to demonstrate how to create an otherwise minimal \
service with the libraries and modules provied by Pelikan, which \
meets stringent requirements on latencies, observability, \
configurability, and other valuable traits in a typical production \
environment.",
)
.arg(
Arg::with_name("stats")
.short("s")
.long("stats")
.help("List all metrics in stats")
.takes_value(false),
)
.arg(
Arg::with_name("CONFIG")
.help("Server configuration file")
.index(1),
)
.get_matches();

if matches.is_present("stats") {
println!("{:<31} {:<15} DESCRIPTION", "NAME", "TYPE");

let mut metrics = Vec::new();

for metric in &metrics::rustcommon_metrics::metrics() {
let any = match metric.as_any() {
Some(any) => any,
None => {
continue;
}
};

if any.downcast_ref::<Counter>().is_some() {
metrics.push(format!("{:<31} counter", metric.name()));
} else if any.downcast_ref::<Gauge>().is_some() {
metrics.push(format!("{:<31} gauge", metric.name()));
} else if any.downcast_ref::<Heatmap>().is_some() {
for (label, _) in PERCENTILES {
let name = format!("{}_{}", metric.name(), label);
metrics.push(format!("{:<31} percentile", name));
}
} else {
continue;
}
}

metrics.sort();
for metric in metrics {
println!("{}", metric);
}
std::process::exit(0);
}

// load config from file
let config = if let Some(file) = std::env::args().nth(1) {
let config = if let Some(file) = matches.value_of("CONFIG") {
debug!("loading config: {}", file);
match PingserverConfig::load(&file) {
Ok(c) => c,
Expand Down
1 change: 1 addition & 0 deletions src/rust/server/segcache/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ debug = ["entrystore/debug"]

[dependencies]
backtrace = "0.3.56"
clap = "2.33.3"
config = { path = "../../config" }
entrystore = { path = "../../entrystore" }
logger = { path = "../../logger" }
Expand Down
65 changes: 63 additions & 2 deletions src/rust/server/segcache/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
extern crate logger;

use backtrace::Backtrace;
use clap::{App, Arg};
use config::SegcacheConfig;
use metrics::*;
use pelikan_segcache_rs::Segcache;
use server::PERCENTILES;

fn main() {
// custom panic hook to terminate whole process after unwinding
Expand All @@ -17,10 +20,68 @@ fn main() {
std::process::exit(101);
}));

// parse command line options
let matches = App::new(env!("CARGO_BIN_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.version_short("v")
.long_about(
"One of the unified cache backends implemented in Rust. It \
uses segment-based storage to cache key/val pairs. It speaks the \
memcached ASCII protocol and supports some ASCII memcached \
commands.",
)
.arg(
Arg::with_name("stats")
.short("s")
.long("stats")
.help("List all metrics in stats")
.takes_value(false),
)
.arg(
Arg::with_name("CONFIG")
.help("Server configuration file")
.index(1),
)
.get_matches();

if matches.is_present("stats") {
println!("{:<31} {:<15} DESCRIPTION", "NAME", "TYPE");

let mut metrics = Vec::new();

for metric in &metrics::rustcommon_metrics::metrics() {
let any = match metric.as_any() {
Some(any) => any,
None => {
continue;
}
};

if any.downcast_ref::<Counter>().is_some() {
metrics.push(format!("{:<31} counter", metric.name()));
} else if any.downcast_ref::<Gauge>().is_some() {
metrics.push(format!("{:<31} gauge", metric.name()));
} else if any.downcast_ref::<Heatmap>().is_some() {
for (label, _) in PERCENTILES {
let name = format!("{}_{}", metric.name(), label);
metrics.push(format!("{:<31} percentile", name));
}
} else {
continue;
}
}

metrics.sort();
for metric in metrics {
println!("{}", metric);
}
std::process::exit(0);
}

// load config from file
let config = if let Some(file) = std::env::args().nth(1) {
let config = if let Some(file) = matches.value_of("CONFIG") {
debug!("loading config: {}", file);
match SegcacheConfig::load(&file) {
match SegcacheConfig::load(file) {
Ok(c) => c,
Err(e) => {
error!("{}", e);
Expand Down

0 comments on commit fc8e451

Please sign in to comment.