From a1b6ea8a5274d65cad445cb16c4d5e7f4ec1633f Mon Sep 17 00:00:00 2001 From: Sebastian Rollen Date: Fri, 16 Jul 2021 12:02:13 -0400 Subject: [PATCH 1/2] switch to prometheus for reporting --- Cargo.lock | 314 ++++++++++++++++++++++++++++++++++++++----- Cargo.toml | 8 +- src/domain/mod.rs | 1 + src/domain/orders.rs | 48 +++++++ src/main.rs | 78 ++++++----- src/server.rs | 48 +++++++ src/settings.rs | 6 +- src/types.rs | 23 ---- 8 files changed, 432 insertions(+), 94 deletions(-) create mode 100644 src/domain/mod.rs create mode 100644 src/domain/orders.rs create mode 100644 src/server.rs delete mode 100644 src/types.rs diff --git a/Cargo.lock b/Cargo.lock index 62de9e2..465a28b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,6 +77,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "buf_redux" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" +dependencies = [ + "memchr", + "safemem", +] + [[package]] name = "bumpalo" version = "3.7.0" @@ -182,15 +192,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "dogstatsd" -version = "0.3.0" -source = "git+ssh://git@github.com/Overmuse/dogstatsd?tag=v0.3.0#d3734c850ce510951dc108e8de816e73ce2b4404" -dependencies = [ - "bytes", - "tokio", -] - [[package]] name = "dotenv" version = "0.15.0" @@ -341,6 +342,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.3" @@ -349,7 +361,7 @@ checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] @@ -377,6 +389,31 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +[[package]] +name = "headers" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b7591fb62902706ae8e7aaff416b1b0fa2c0fd0878b46dc13baa3712d8a855" +dependencies = [ + "base64", + "bitflags", + "bytes", + "headers-core", + "http", + "mime", + "sha-1", + "time", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + [[package]] name = "hermit-abi" version = "0.1.18" @@ -487,6 +524,15 @@ dependencies = [ "bytes", ] +[[package]] +name = "instant" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +dependencies = [ + "cfg-if", +] + [[package]] name = "ipnet" version = "2.3.1" @@ -560,6 +606,15 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +[[package]] +name = "lock_api" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.14" @@ -596,6 +651,16 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "mime_guess" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "mio" version = "0.7.13" @@ -618,6 +683,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "multipart" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050aeedc89243f5347c3e237e3e13dc76fbe4ae3742a57b94dc14f69acf76d4" +dependencies = [ + "buf_redux", + "httparse", + "log", + "mime", + "mime_guess", + "quick-error", + "rand 0.7.3", + "safemem", + "tempfile", + "twoway", +] + [[package]] name = "native-tls" version = "0.2.7" @@ -771,6 +854,31 @@ dependencies = [ "vcpkg", ] +[[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", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -851,6 +959,33 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "prometheus" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5986aa8d62380092d2f50f8b1cdba9cb9b6731ffd4b25b51fd126b6c3e05b99c" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot", + "protobuf", + "thiserror", +] + +[[package]] +name = "protobuf" +version = "2.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db50e77ae196458ccd3dc58a31ea1a90b0698ab1b7928d89f644c25d72070267" + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.9" @@ -860,6 +995,19 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + [[package]] name = "rand" version = "0.8.4" @@ -867,9 +1015,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha", - "rand_core", - "rand_hc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] @@ -879,7 +1037,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", ] [[package]] @@ -888,7 +1055,16 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom", + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -897,7 +1073,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core", + "rand_core 0.6.3", ] [[package]] @@ -976,22 +1152,24 @@ dependencies = [ [[package]] name = "reporting" -version = "0.1.5" +version = "0.2.0" dependencies = [ "alpaca", "anyhow", "config", - "dogstatsd", "dotenv", "futures", "kafka-settings", + "lazy_static", + "prometheus", "rdkafka", + "rust_decimal", "serde 1.0.126", "serde_json", - "serde_plain", "tokio", "tracing", "tracing-subscriber", + "warp", ] [[package]] @@ -1052,6 +1230,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + [[package]] name = "schannel" version = "0.1.19" @@ -1062,6 +1246,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "security-framework" version = "2.3.1" @@ -1134,15 +1330,6 @@ dependencies = [ "serde 1.0.126", ] -[[package]] -name = "serde_plain" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625fb0da2b006092b426a94acc1611bec52f2ec27bb27b266a9f93c29ee38eda" -dependencies = [ - "serde 1.0.126", -] - [[package]] name = "serde_urlencoded" version = "0.7.0" @@ -1224,7 +1411,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if", "libc", - "rand", + "rand 0.8.4", "redox_syscall", "remove_dir_all", "winapi", @@ -1322,6 +1509,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8864d706fdb3cc0843a49647ac892720dac98a6eeb818b77190592cf4994066" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-tungstenite" version = "0.13.0" @@ -1373,6 +1571,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" dependencies = [ "cfg-if", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1461,18 +1660,36 @@ dependencies = [ "input_buffer", "log", "native-tls", - "rand", + "rand 0.8.4", "sha-1", "url", "utf-8", ] +[[package]] +name = "twoway" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" +dependencies = [ + "memchr", +] + [[package]] name = "typenum" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.5" @@ -1521,7 +1738,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom", + "getrandom 0.2.3", "serde 1.0.126", ] @@ -1547,6 +1764,41 @@ dependencies = [ "try-lock", ] +[[package]] +name = "warp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332d47745e9a0c38636dbd454729b147d16bd1ed08ae67b3ab281c4506771054" +dependencies = [ + "bytes", + "futures", + "headers", + "http", + "hyper", + "log", + "mime", + "mime_guess", + "multipart", + "percent-encoding", + "pin-project", + "scoped-tls", + "serde 1.0.126", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tokio-util", + "tower-service", + "tracing", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 5b9316b..6f0436e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "reporting" -version = "0.1.5" +version = "0.2.0" authors = ["Sebastian Rollen "] edition = "2018" @@ -10,14 +10,16 @@ edition = "2018" alpaca = { tag = "v0.7.0", git = "ssh://git@github.com/Overmuse/alpaca" } anyhow = "1.0.41" config = "0.11.0" -dogstatsd = { git = "ssh://git@github.com/Overmuse/dogstatsd", tag = "v0.3.0" } dotenv = "0.15.0" futures = "0.3.15" kafka-settings = { git = "ssh://git@github.com/Overmuse/kafka-settings", tag = "v0.3.1" } +lazy_static = "1.4.0" +prometheus = "0.12.0" rdkafka = { version = "0.26.0", features = ["ssl-vendored"] } +rust_decimal = "1.14.3" serde = "1.0.126" serde_json = "1.0.64" -serde_plain = "0.3.0" tokio = { version = "1.7.0", features = ["rt-multi-thread", "macros"] } tracing = "0.1.26" tracing-subscriber = "0.2.18" +warp = "0.3.1" diff --git a/src/domain/mod.rs b/src/domain/mod.rs new file mode 100644 index 0000000..f667fd4 --- /dev/null +++ b/src/domain/mod.rs @@ -0,0 +1 @@ +pub mod orders; diff --git a/src/domain/orders.rs b/src/domain/orders.rs new file mode 100644 index 0000000..bb7fa93 --- /dev/null +++ b/src/domain/orders.rs @@ -0,0 +1,48 @@ +use crate::REGISTRY; +use alpaca::{AlpacaMessage, Event}; +use lazy_static::lazy_static; +use prometheus::{CounterVec, GaugeVec, IntCounterVec, Opts}; +use rust_decimal::prelude::*; +use tracing::debug; + +lazy_static! { + pub static ref NUM_TRADES: IntCounterVec = + IntCounterVec::new(Opts::new("num_trades", "Number of trades"), &["ticker"]) + .expect("Metric can be created"); + pub static ref GROSS_TRADE_AMOUNT: CounterVec = CounterVec::new( + Opts::new("gross_trade_amount", "Gross dollar amount traded"), + &["ticker"] + ) + .expect("Metric can be created"); + pub static ref NET_INVESTMENT_AMOUNT: GaugeVec = GaugeVec::new( + Opts::new("net_investment_amount", "Net dollar amount allocated"), + &["strategy", "ticker"] + ) + .expect("Metric can be created"); +} + +pub fn register() { + REGISTRY + .register(Box::new(NUM_TRADES.clone())) + .expect("collector can be registered"); + REGISTRY + .register(Box::new(GROSS_TRADE_AMOUNT.clone())) + .expect("collector can be registered"); + REGISTRY + .register(Box::new(NET_INVESTMENT_AMOUNT.clone())) + .expect("collector can be registered"); +} + +pub fn handle_alpaca_message(message: AlpacaMessage) { + if let AlpacaMessage::TradeUpdates(order_update) = message { + if let Event::Fill { price, .. } = order_update.event { + debug!("Received order fill update, generating metrics"); + let ticker = order_update.order.symbol; + let qty = order_update.order.qty.unwrap(); + NUM_TRADES.with_label_values(&[&ticker]).inc(); + GROSS_TRADE_AMOUNT + .with_label_values(&[&ticker]) + .inc_by((qty * price).abs().to_f64().unwrap()); + } + } +} diff --git a/src/main.rs b/src/main.rs index 29b999a..5f917b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,50 @@ use alpaca::AlpacaMessage; use anyhow::{Context, Result}; -use dogstatsd::Client; use futures::StreamExt; use kafka_settings::consumer; +use lazy_static::lazy_static; +use prometheus::Registry; use rdkafka::Message; -mod settings; -mod types; +use serde::Deserialize; use tracing::subscriber::set_global_default; -use tracing::{debug, info, trace}; +use tracing::{info, trace}; use tracing_subscriber::EnvFilter; -use types::ToMetrics; + +mod domain; +mod server; +mod settings; + +lazy_static! { + pub static ref REGISTRY: Registry = Registry::new(); +} + +pub fn register_custom_metrics() { + domain::orders::register(); +} + +#[derive(Deserialize)] +#[serde(untagged)] +pub enum Input { + Alpaca(AlpacaMessage), +} + +pub async fn run_kafka(kafka_settings: &kafka_settings::KafkaSettings) -> Result<()> { + let consumer = consumer(kafka_settings).context("Failed to create kafka consumer")?; + while let Some(message) = consumer.stream().next().await { + let message = message.context("Error from kafka")?; + if let Some(payload) = message.payload() { + trace!("Received payload"); + let input: Input = + serde_json::from_slice(payload).context("Failed to deserialize message")?; + match input { + Input::Alpaca(alpaca_message) => { + domain::orders::handle_alpaca_message(alpaca_message) + } + } + } + } + Ok(()) +} #[tokio::main] async fn main() -> Result<()> { @@ -20,35 +55,10 @@ async fn main() -> Result<()> { .finish(); set_global_default(subscriber).expect("Failed to set subscriber"); info!("Starting reporting"); + register_custom_metrics(); let settings = settings::Settings::new().context("Failed to load settings")?; - let consumer = consumer(&settings.kafka).context("Failed to create kafka consumer")?; - debug!("Creating dogstatsd client"); - let client = Client::new( - "127.0.0.1:0", - &format!("{}:8125", settings.app.target_address), - ) - .await - .context("Failed to create dogstatsd client")?; - while let Some(message) = consumer.stream().next().await { - let message = message.context("Error from kafka")?; - if let Some(payload) = message.payload() { - trace!("Received payload"); - let alpaca_message: AlpacaMessage = - serde_json::from_slice(payload).context("Failed to deserialize alpaca message")?; - if let AlpacaMessage::TradeUpdates(order_update) = alpaca_message { - debug!("Received trade update, generating metrics"); - let metrics = order_update - .order - .to_metrics() - .context("Failed to convert order to metrics")?; - for metric in metrics { - client - .send(metric) - .await - .context("Failed to send metrics")?; - } - } - } + tokio::select! { + _ = run_kafka(&settings.kafka) => Ok(()), + _ = server::run(settings.webserver.port) => Ok(()) } - Ok(()) } diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..f1e87e3 --- /dev/null +++ b/src/server.rs @@ -0,0 +1,48 @@ +use crate::REGISTRY; +use std::net::{Ipv4Addr, SocketAddrV4}; +use tracing::warn; +use warp::reply::Reply; +use warp::{get, path, serve, Filter, Rejection}; + +async fn metrics_handler() -> Result { + use prometheus::Encoder; + let encoder = prometheus::TextEncoder::new(); + + let mut buffer = Vec::new(); + if let Err(e) = encoder.encode(®ISTRY.gather(), &mut buffer) { + warn!("could not encode custom metrics: {}", e); + }; + let mut res = match String::from_utf8(buffer.clone()) { + Ok(v) => v, + Err(e) => { + warn!("custom metrics could not be from_utf8'd: {}", e); + String::default() + } + }; + buffer.clear(); + + let mut buffer = Vec::new(); + if let Err(e) = encoder.encode(&prometheus::gather(), &mut buffer) { + warn!("could not encode prometheus metrics: {}", e); + }; + let res_custom = match String::from_utf8(buffer.clone()) { + Ok(v) => v, + Err(e) => { + warn!("prometheus metrics could not be from_utf8'd: {}", e); + String::default() + } + }; + buffer.clear(); + + res.push_str(&res_custom); + Ok(res) +} + +#[tracing::instrument] +pub async fn run(port: u16) { + let health = path!("health").map(|| ""); + let metrics = path("metrics").and_then(metrics_handler); + let routes = get().and(health).or(metrics); + let address = SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), port); + serve(routes).run(address).await +} diff --git a/src/settings.rs b/src/settings.rs index 6b488cb..cfe1d9e 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -3,13 +3,13 @@ use kafka_settings::KafkaSettings; use serde::Deserialize; #[derive(Debug, Deserialize)] -pub struct AppSettings { - pub target_address: String, +pub struct WebServerSettings { + pub port: u16, } #[derive(Debug, Deserialize)] pub struct Settings { - pub app: AppSettings, + pub webserver: WebServerSettings, pub kafka: KafkaSettings, } diff --git a/src/types.rs b/src/types.rs deleted file mode 100644 index 3ef737f..0000000 --- a/src/types.rs +++ /dev/null @@ -1,23 +0,0 @@ -use alpaca::Order; -use anyhow::{Context, Result}; -use dogstatsd::Metric; - -pub trait ToMetrics { - fn to_metrics(&self) -> Result>; -} - -impl ToMetrics for Order { - fn to_metrics(&self) -> Result> { - let metrics = vec![Metric::increase("order") - .add_key_value( - "status", - serde_plain::to_string(&self.status).context("Failed to serialize order status")?, - ) - .add_key_value("ticker", &self.symbol) - .add_key_value( - "side", - serde_plain::to_string(&self.side).context("Failed to serialize order side")?, - )]; - Ok(metrics) - } -} From 1045d3384913dddf0e59d065765d55236ef80646 Mon Sep 17 00:00:00 2001 From: Sebastian Rollen Date: Fri, 16 Jul 2021 12:13:13 -0400 Subject: [PATCH 2/2] update github actions --- .github/workflows/release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 24e502a..6d1b56a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,12 +13,12 @@ jobs: uses: actions/checkout@v2 - name: Read version number id: read_toml - uses: outcome-co/action-read-toml@v2.0.10 + uses: SebRollen/toml_action@v1.0.0 with: - path: Cargo.toml - key: package.version + file: Cargo.toml + field: package.version - name: Set tag env variable - run: echo IMAGE_TAG=v${{steps.read_toml.outputs.package_version}} >> $GITHUB_ENV + run: echo IMAGE_TAG=v${{steps.read_toml.outputs.value}} >> $GITHUB_ENV - uses: ncipollo/release-action@v1 continue-on-error: true with: