diff --git a/peach-stats/Cargo.toml b/peach-stats/Cargo.toml index b603d20..c8a4914 100644 --- a/peach-stats/Cargo.toml +++ b/peach-stats/Cargo.toml @@ -28,13 +28,13 @@ travis-ci = { repository = "peachcloud/peach-stats", branch = "master" } maintenance = { status = "actively-developed" } [dependencies] -env_logger = "0.6" -jsonrpc-core = "11" -jsonrpc-http-server = "11" -jsonrpc-test = "11" +env_logger = "0.9" +jsonrpc-core = "18" +jsonrpc-http-server = "18" log = "0.4" -probes = "0.3" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -snafu = "0.4" -systemstat = "0.1" +miniserde = "0.1.15" +probes = "0.4.1" +systemstat = "0.1.10" + +[dev-dependencies] +jsonrpc-test = "18" diff --git a/peach-stats/README.md b/peach-stats/README.md index f187a53..b2d527e 100644 --- a/peach-stats/README.md +++ b/peach-stats/README.md @@ -14,7 +14,7 @@ System statistics microservice module for PeachCloud. Provides a JSON-RPC wrappe | `load_average` | Load average statistics | `one`, `five`, `fifteen` | | `mem_stats` | Memory statistics | `total`, `free`, `used` | | `ping` | Microservice status | `success` if running | -| `uptime` | System uptime | `secs`, `nanos` | +| `uptime` | System uptime | `secs` | ### Environment @@ -101,7 +101,7 @@ With microservice running, open a second terminal window and use `curl` to call Server responds with: -`{"jsonrpc":"2.0","result":"{\"secs\":840968,\"nanos\":0}","id":1}` +`{"jsonrpc":"2.0","result":"{\"secs\":840968}","id":1}` ### Licensing diff --git a/peach-stats/src/error.rs b/peach-stats/src/error.rs index 12ce99d..b558364 100644 --- a/peach-stats/src/error.rs +++ b/peach-stats/src/error.rs @@ -1,67 +1,69 @@ -use std::{error, io}; +use std::{error, fmt, io}; use jsonrpc_core::{types::error::Error, ErrorCode}; use probes::ProbeError; -use serde_json::Error as SerdeError; -use snafu::Snafu; -pub type BoxError = Box; - -#[derive(Debug, Snafu)] -#[snafu(visibility(pub(crate)))] +#[derive(Debug)] pub enum StatError { - #[snafu(display("Failed to retrieve CPU statistics: {}", source))] - ReadCpuStat { source: ProbeError }, + CpuStat { source: ProbeError }, + DiskUsage { source: ProbeError }, + LoadAvg { source: ProbeError }, + MemStat { source: ProbeError }, + Uptime { source: io::Error }, +} - #[snafu(display("Failed to retrieve disk usage statistics: {}", source))] - ReadDiskUsage { source: ProbeError }, +impl error::Error for StatError {} - #[snafu(display("Failed to retrieve load average statistics: {}", source))] - ReadLoadAvg { source: ProbeError }, - - #[snafu(display("Failed to retrieve memory statistics: {}", source))] - ReadMemStat { source: ProbeError }, - - #[snafu(display("Failed to retrieve system uptime: {}", source))] - ReadUptime { source: io::Error }, - - #[snafu(display("JSON serialization failed: {}", source))] - SerdeSerialize { source: SerdeError }, +impl fmt::Display for StatError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + StatError::CpuStat { ref source } => { + write!(f, "Failed to retrieve CPU statistics: {}", source) + } + StatError::DiskUsage { ref source } => { + write!(f, "Failed to retrieve disk usage statistics: {}", source) + } + StatError::LoadAvg { ref source } => { + write!(f, "Failed to retrieve load average statistics: {}", source) + } + StatError::MemStat { ref source } => { + write!(f, "Failed to retrieve memory statistics: {}", source) + } + StatError::Uptime { ref source } => { + write!(f, "Failed to retrieve system uptime: {}", source) + } + } + } } impl From for Error { fn from(err: StatError) -> Self { match &err { - StatError::ReadCpuStat { source } => Error { + StatError::CpuStat { source } => Error { code: ErrorCode::ServerError(-32001), message: format!("Failed to retrieve CPU statistics: {}", source), data: None, }, - StatError::ReadDiskUsage { source } => Error { + StatError::DiskUsage { source } => Error { code: ErrorCode::ServerError(-32001), message: format!("Failed to retrieve disk usage statistics: {}", source), data: None, }, - StatError::ReadLoadAvg { source } => Error { + StatError::LoadAvg { source } => Error { code: ErrorCode::ServerError(-32001), message: format!("Failed to retrieve load average statistics: {}", source), data: None, }, - StatError::ReadMemStat { source } => Error { + StatError::MemStat { source } => Error { code: ErrorCode::ServerError(-32001), message: format!("Failed to retrieve memory statistics: {}", source), data: None, }, - StatError::ReadUptime { source } => Error { + StatError::Uptime { source } => Error { code: ErrorCode::ServerError(-32001), message: format!("Failed to retrieve system uptime: {}", source), data: None, }, - StatError::SerdeSerialize { source } => Error { - code: ErrorCode::ServerError(-32002), - message: format!("JSON serialization failed: {}", source), - data: None, - }, } } } diff --git a/peach-stats/src/lib.rs b/peach-stats/src/lib.rs index 68eff8d..00ce6a1 100644 --- a/peach-stats/src/lib.rs +++ b/peach-stats/src/lib.rs @@ -6,56 +6,56 @@ use std::{env, result::Result}; use jsonrpc_core::{IoHandler, Value}; use jsonrpc_http_server::{AccessControlAllowOrigin, DomainsValidation, ServerBuilder}; -#[allow(unused_imports)] -use jsonrpc_test as test; use log::info; -use crate::error::BoxError; +use crate::error::StatError; -pub fn run() -> Result<(), BoxError> { +pub fn run() -> Result<(), StatError> { info!("Starting up."); info!("Creating JSON-RPC I/O handler."); let mut io = IoHandler::default(); - io.add_method("cpu_stats", move |_| { + io.add_method("cpu_stats", move |_| async { info!("Fetching CPU statistics."); let stats = stats::cpu_stats()?; Ok(Value::String(stats)) }); - io.add_method("cpu_stats_percent", move |_| { + io.add_method("cpu_stats_percent", move |_| async { info!("Fetching CPU statistics as percentages."); let stats = stats::cpu_stats_percent()?; Ok(Value::String(stats)) }); - io.add_method("disk_usage", move |_| { + io.add_method("disk_usage", move |_| async { info!("Fetching disk usage statistics."); let disks = stats::disk_usage()?; Ok(Value::String(disks)) }); - io.add_method("load_average", move |_| { + io.add_method("load_average", move |_| async { info!("Fetching system load average statistics."); let avg = stats::load_average()?; Ok(Value::String(avg)) }); - io.add_method("mem_stats", move |_| { + io.add_method("mem_stats", move |_| async { info!("Fetching current memory statistics."); let mem = stats::mem_stats()?; Ok(Value::String(mem)) }); - io.add_method("ping", |_| Ok(Value::String("success".to_string()))); + io.add_method("ping", |_| async { + Ok(Value::String("success".to_string())) + }); - io.add_method("uptime", move |_| { + io.add_method("uptime", move |_| async { info!("Fetching system uptime."); let uptime = stats::uptime()?; @@ -85,16 +85,17 @@ pub fn run() -> Result<(), BoxError> { #[cfg(test)] mod tests { use super::*; + use jsonrpc_test as test_rpc; // test to ensure correct success response #[test] fn rpc_success() { let rpc = { let mut io = IoHandler::new(); - io.add_method("rpc_success_response", |_| { + io.add_method("rpc_success_response", |_| async { Ok(Value::String("success".into())) }); - test::Rpc::from(io) + test_rpc::Rpc::from(io) }; assert_eq!(rpc.request("rpc_success_response", &()), r#""success""#); diff --git a/peach-stats/src/stats.rs b/peach-stats/src/stats.rs index a3c42bb..15c9031 100644 --- a/peach-stats/src/stats.rs +++ b/peach-stats/src/stats.rs @@ -1,14 +1,14 @@ use std::result::Result; +use miniserde::json; use probes::{cpu, disk_usage, load, memory}; -use snafu::ResultExt; use systemstat::{Platform, System}; -use crate::error::*; +use crate::error::StatError; use crate::structs::{CpuStat, CpuStatPercentages, DiskUsage, LoadAverage, MemStat}; pub fn cpu_stats() -> Result { - let cpu_stats = cpu::proc::read().context(ReadCpuStat)?; + let cpu_stats = cpu::proc::read().map_err(|source| StatError::CpuStat { source })?; let s = cpu_stats.stat; let cpu = CpuStat { user: s.user, @@ -16,13 +16,13 @@ pub fn cpu_stats() -> Result { nice: s.nice, idle: s.idle, }; - let json_cpu = serde_json::to_string(&cpu).context(SerdeSerialize)?; + let json_cpu = json::to_string(&cpu); Ok(json_cpu) } pub fn cpu_stats_percent() -> Result { - let cpu_stats = cpu::proc::read().context(ReadCpuStat)?; + let cpu_stats = cpu::proc::read().map_err(|source| StatError::CpuStat { source })?; let s = cpu_stats.stat.in_percentages(); let cpu = CpuStatPercentages { user: s.user, @@ -30,13 +30,13 @@ pub fn cpu_stats_percent() -> Result { nice: s.nice, idle: s.idle, }; - let json_cpu = serde_json::to_string(&cpu).context(SerdeSerialize)?; + let json_cpu = json::to_string(&cpu); Ok(json_cpu) } pub fn disk_usage() -> Result { - let disks = disk_usage::read().context(ReadDiskUsage)?; + let disks = disk_usage::read().map_err(|source| StatError::DiskUsage { source })?; let mut disk_usages = Vec::new(); for d in disks { let disk = DiskUsage { @@ -49,39 +49,42 @@ pub fn disk_usage() -> Result { }; disk_usages.push(disk); } - let json_disks = serde_json::to_string(&disk_usages).context(SerdeSerialize)?; + let json_disks = json::to_string(&disk_usages); Ok(json_disks) } pub fn load_average() -> Result { - let l = load::read().context(ReadLoadAvg)?; + let l = load::read().map_err(|source| StatError::LoadAvg { source })?; let load_avg = LoadAverage { one: l.one, five: l.five, fifteen: l.fifteen, }; - let json_load_avg = serde_json::to_string(&load_avg).context(SerdeSerialize)?; + let json_load_avg = json::to_string(&load_avg); Ok(json_load_avg) } pub fn mem_stats() -> Result { - let m = memory::read().context(ReadMemStat)?; + let m = memory::read().map_err(|source| StatError::MemStat { source })?; let mem = MemStat { total: m.total(), free: m.free(), used: m.used(), }; - let json_mem = serde_json::to_string(&mem).context(SerdeSerialize)?; + let json_mem = json::to_string(&mem); Ok(json_mem) } pub fn uptime() -> Result { let sys = System::new(); - let uptime = sys.uptime().context(ReadUptime)?; - let json_uptime = serde_json::to_string(&uptime).context(SerdeSerialize)?; + let uptime = sys + .uptime() + .map_err(|source| StatError::Uptime { source })?; + let uptime_secs = uptime.as_secs(); + let json_uptime = json::to_string(&uptime_secs); Ok(json_uptime) } diff --git a/peach-stats/src/structs.rs b/peach-stats/src/structs.rs index 1fe12ee..f307879 100644 --- a/peach-stats/src/structs.rs +++ b/peach-stats/src/structs.rs @@ -1,4 +1,4 @@ -use serde::Serialize; +use miniserde::Serialize; #[derive(Debug, Serialize)] pub struct CpuStat {