Skip to content

Commit

Permalink
output: move output structures to a crate
Browse files Browse the repository at this point in the history
rpc-perf periodically takes a snapshot of its observed performance
metrics and outputs them into JSON. Move the structures comprising
this JSON into the rpcperf-dataspec crate so that external consumers
can parse rpc-perf's output by importing the crate from lib/dataspec.
  • Loading branch information
mihirn authored Aug 18, 2023
1 parent c46358c commit bb2db86
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 83 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

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

29 changes: 23 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
[package]
name = "rpc-perf"
version = "5.0.2-alpha.0"
[workspace.package]
authors = ["Brian Martin <brian@iop.systems>"]
edition = "2021"
description = "RPC Performance Testing"
homepage = "https://github.com/iopsystems/rpc-perf"
repository = "https://github.com/iopsystems/rpc-perf"
license = "MIT OR Apache-2.0"

[package]
name = "rpc-perf"
description = "RPC Performance Testing"
version = "5.0.2-alpha.0"
authors = { workspace = true }
edition = { workspace = true }
homepage = { workspace = true }
repository = { workspace = true }
license = { workspace = true }

[workspace.dependencies]
histogram = "0.7.4"
serde = "1.0.144"

[dependencies]
ahash = "0.8.3"
async-channel = "1.8.0"
Expand All @@ -21,7 +32,7 @@ foreign-types-shared = "0.3.1"
futures = "0.3.28"
http-body-util = "0.1.0-rc.2"
hyper = { version = "1.0.0-rc.3", features = ["http1", "http2", "client"]}
histogram = "0.7.4"
histogram = { workspace = true }
humantime = "2.1.0"
momento = "0.31.0"
metriken = "0.2.3"
Expand All @@ -36,7 +47,8 @@ rand_xoshiro = "0.6.0"
ratelimit = "0.7.0"
redis = { version = "0.22.3", features = ["tokio-comp"] }
ringlog = "0.2.0"
serde = "1.0.144"
rpcperf-dataspec = { path = "lib/dataspec" }
serde = { workspace = true }
serde_json = "1.0.94"
session = { git = "https://github.com/pelikan-io/pelikan" }
sha2 = "0.10.7"
Expand All @@ -47,6 +59,11 @@ toml = "0.7.2"
zipf = "7.0.0"
warp = "0.3.4"

[workspace]
members = [
"lib/dataspec",
]

[profile.release]
opt-level = 3
debug = true
Expand Down
96 changes: 96 additions & 0 deletions lib/dataspec/Cargo.lock

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

12 changes: 12 additions & 0 deletions lib/dataspec/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "rpcperf-dataspec"
version = "0.1.0"
authors = { workspace = true }
edition = { workspace = true }
homepage = { workspace = true }
repository = { workspace = true }
license = { workspace = true }

[dependencies]
histogram = { workspace = true }
serde = { workspace = true }
80 changes: 80 additions & 0 deletions lib/dataspec/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//! Format of JSON output from rpc-perf. These structures can be used
//! by any consumer of the produced data to parse the files.

use serde::{Deserialize, Serialize};

use histogram::CompactHistogram;

#[derive(Serialize, Deserialize)]
pub struct Connections {
/// number of current connections (gauge)
pub current: i64,
/// number of total connect attempts
pub total: u64,
/// number of connections established
pub opened: u64,
/// number of connect attempts that failed
pub error: u64,
/// number of connect attempts that hit timeout
pub timeout: u64,
}

#[derive(Copy, Clone, Serialize, Deserialize)]
pub struct Requests {
pub total: u64,
pub ok: u64,
pub reconnect: u64,
pub unsupported: u64,
}

#[derive(Serialize, Deserialize)]
pub struct Responses {
/// total number of responses
pub total: u64,
/// number of responses that were successful
pub ok: u64,
/// number of responses that were unsuccessful
pub error: u64,
/// number of responses that were missed due to timeout
pub timeout: u64,
/// number of read requests with a hit response
pub hit: u64,
/// number of read requests with a miss response
pub miss: u64,
}

#[derive(Serialize, Deserialize)]
pub struct ClientStats {
pub connections: Connections,
pub requests: Requests,
pub responses: Responses,
pub request_latency: CompactHistogram,
}

#[derive(Serialize, Deserialize)]
pub struct PubsubStats {
pub publishers: Publishers,
pub subscribers: Subscribers,
}

#[derive(Serialize, Deserialize)]
pub struct Publishers {
// current number of publishers
pub current: i64,
}

#[derive(Serialize, Deserialize)]
pub struct Subscribers {
// current number of subscribers
pub current: i64,
}

#[derive(Serialize, Deserialize)]
pub struct JsonSnapshot {
pub window: u64,
pub elapsed: f64,
#[serde(skip_serializing_if = "Option::is_none")]
pub target_qps: Option<f64>,
pub client: ClientStats,
pub pubsub: PubsubStats,
}
81 changes: 4 additions & 77 deletions src/output/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::*;
use rpcperf_dataspec::*;

use ahash::{HashMap, HashMapExt};
use ratelimit::Ratelimiter;
use serde::Serialize;
use std::io::{BufWriter, Write};

use histogram::CompactHistogram;
Expand Down Expand Up @@ -219,80 +220,6 @@ fn pubsub_stats(snapshot: &mut Snapshot, elapsed: f64) -> u64 {
pubsub_tx_ok
}

#[derive(Serialize)]
struct Connections {
/// number of current connections (gauge)
current: i64,
/// number of total connect attempts
total: u64,
/// number of connections established
opened: u64,
/// number of connect attempts that failed
error: u64,
/// number of connect attempts that hit timeout
timeout: u64,
}

#[derive(Serialize, Copy, Clone)]
struct Requests {
total: u64,
ok: u64,
reconnect: u64,
unsupported: u64,
}

#[derive(Serialize)]
struct Responses {
/// total number of responses
total: u64,
/// number of responses that were successful
ok: u64,
/// number of responses that were unsuccessful
error: u64,
/// number of responses that were missed due to timeout
timeout: u64,
/// number of read requests with a hit response
hit: u64,
/// number of read requests with a miss response
miss: u64,
}

#[derive(Serialize)]
struct Client {
connections: Connections,
requests: Requests,
responses: Responses,
request_latency: CompactHistogram,
}

#[derive(Serialize)]
struct Pubsub {
publishers: Publishers,
subscribers: Subscribers,
}

#[derive(Serialize)]
struct Publishers {
// current number of publishers
current: i64,
}

#[derive(Serialize)]
struct Subscribers {
// current number of subscribers
current: i64,
}

#[derive(Serialize)]
struct JsonSnapshot {
window: u64,
elapsed: f64,
#[serde(skip_serializing_if = "Option::is_none")]
target_qps: Option<f64>,
client: Client,
pubsub: Pubsub,
}

// gets the non-zero buckets for the most recent window in the heatmap
fn heatmap_to_buckets(heatmap: &Heatmap) -> CompactHistogram {
// XXX: The heatmap corrects for wraparound and fixes indices once
Expand Down Expand Up @@ -380,13 +307,13 @@ pub fn json(config: Config, ratelimit: Option<&Ratelimiter>) {
window: window_id,
elapsed,
target_qps: ratelimit.as_ref().map(|ratelimit| ratelimit.rate()),
client: Client {
client: ClientStats {
connections,
requests,
responses,
request_latency: heatmap_to_buckets(&REQUEST_LATENCY),
},
pubsub: Pubsub {
pubsub: PubsubStats {
publishers: Publishers {
current: PUBSUB_PUBLISHER_CURR.value(),
},
Expand Down

0 comments on commit bb2db86

Please sign in to comment.