- kills MeasurementWindow/WTen - all warnings silenced - cruft removedmaster
@@ -1,6 +1,6 @@ | |||||
[package] | [package] | ||||
name = "logging" | name = "logging" | ||||
version = "0.2.3" | |||||
version = "0.3.0" | |||||
authors = ["Jonathan Strong <jstrong@legis.io>"] | authors = ["Jonathan Strong <jstrong@legis.io>"] | ||||
[dependencies] | [dependencies] | ||||
@@ -1,3 +1,4 @@ | |||||
#![allow(unused_imports)] | |||||
#[macro_use] extern crate slog; | #[macro_use] extern crate slog; | ||||
extern crate logging; | extern crate logging; | ||||
extern crate slog_term; | extern crate slog_term; | ||||
@@ -1,13 +1,12 @@ | |||||
//! Utilities to efficiently send data to influx | //! Utilities to efficiently send data to influx | ||||
//! | //! | ||||
use std::iter::FromIterator; | |||||
use std::io::{Write, Read}; | |||||
use std::sync::mpsc::{Sender, Receiver, channel, SendError}; | |||||
use std::io::Read; | |||||
use std::sync::mpsc::{Sender, channel, SendError}; | |||||
use std::thread; | use std::thread; | ||||
use std::fs::{self, OpenOptions}; | |||||
use std::fs; | |||||
use std::time::Duration; | use std::time::Duration; | ||||
use std::hash::{Hash, BuildHasherDefault}; | |||||
use std::hash::BuildHasherDefault; | |||||
use hyper::status::StatusCode; | use hyper::status::StatusCode; | ||||
use hyper::client::response::Response; | use hyper::client::response::Response; | ||||
@@ -15,15 +14,14 @@ use hyper::Url; | |||||
use hyper::client::Client; | use hyper::client::Client; | ||||
use influent::measurement::{Measurement, Value}; | use influent::measurement::{Measurement, Value}; | ||||
use zmq; | use zmq; | ||||
use chrono::{DateTime, Utc, TimeZone}; | |||||
#[allow(unused_imports)] | |||||
use chrono::{DateTime, Utc}; | |||||
use sloggers::types::Severity; | use sloggers::types::Severity; | ||||
use ordermap::OrderMap; | use ordermap::OrderMap; | ||||
use fnv::FnvHasher; | use fnv::FnvHasher; | ||||
use decimal::d128; | use decimal::d128; | ||||
use uuid::Uuid; | use uuid::Uuid; | ||||
use money::Ticker; | |||||
use super::{nanos, file_logger}; | use super::{nanos, file_logger}; | ||||
use warnings::Warning; | use warnings::Warning; | ||||
@@ -211,6 +209,7 @@ impl InfluxWriter { | |||||
self.tx.clone() | self.tx.clone() | ||||
} | } | ||||
#[allow(unused_assignments)] | |||||
pub fn new(host: &'static str, db: &'static str, log_path: &str, buffer_size: u8) -> Self { | pub fn new(host: &'static str, db: &'static str, log_path: &str, buffer_size: u8) -> Self { | ||||
let (kill_switch, terminate) = channel(); | let (kill_switch, terminate) = channel(); | ||||
let (tx, rx) = channel(); | let (tx, rx) = channel(); | ||||
@@ -219,8 +218,12 @@ impl InfluxWriter { | |||||
debug!(logger, "initializing url"; | debug!(logger, "initializing url"; | ||||
"DB_HOST" => host, | "DB_HOST" => host, | ||||
"DB_NAME" => db); | "DB_NAME" => db); | ||||
#[cfg(not(test))] | |||||
let url = Url::parse_with_params(&format!("http://{}:8086/write", host), &[("db", db), ("precision", "ns")]).expect("influx writer url should parse"); | let url = Url::parse_with_params(&format!("http://{}:8086/write", host), &[("db", db), ("precision", "ns")]).expect("influx writer url should parse"); | ||||
#[cfg(not(test))] | |||||
let client = Client::new(); | let client = Client::new(); | ||||
debug!(logger, "initializing buffers"); | debug!(logger, "initializing buffers"); | ||||
let mut meas_buf = String::with_capacity(32 * 32 * 32); | let mut meas_buf = String::with_capacity(32 * 32 * 32); | ||||
let mut buf = String::with_capacity(32 * 32 * 32); | let mut buf = String::with_capacity(32 * 32 * 32); | ||||
@@ -264,7 +267,7 @@ impl InfluxWriter { | |||||
Ok(mut resp) => { | Ok(mut resp) => { | ||||
let mut server_resp = String::with_capacity(1024); | let mut server_resp = String::with_capacity(1024); | ||||
resp.read_to_string(&mut server_resp); //.unwrap_or(0); | |||||
let _ = resp.read_to_string(&mut server_resp); //.unwrap_or(0); | |||||
error!(logger, "influx server error"; | error!(logger, "influx server error"; | ||||
"status" => resp.status.to_string(), | "status" => resp.status.to_string(), | ||||
"body" => server_resp); | "body" => server_resp); | ||||
@@ -285,7 +288,7 @@ impl InfluxWriter { | |||||
loop { | loop { | ||||
rcvd_msg = false; | rcvd_msg = false; | ||||
rx.recv_timeout(Duration::from_millis(10)) | |||||
let _ = rx.recv_timeout(Duration::from_millis(10)) | |||||
.map(|mut meas: OwnedMeasurement| { | .map(|mut meas: OwnedMeasurement| { | ||||
// if we didn't set the timestamp, it would end up | // if we didn't set the timestamp, it would end up | ||||
// being whenever we accumulated `BUFFER_SIZE` messages, | // being whenever we accumulated `BUFFER_SIZE` messages, | ||||
@@ -473,8 +476,6 @@ pub fn serialize_owned(measurement: &OwnedMeasurement, line: &mut String) { | |||||
add_tag(line, key, value); | add_tag(line, key, value); | ||||
} | } | ||||
let mut fields = measurement.fields.iter(); | |||||
let add_field = |line: &mut String, key: &str, value: &OwnedValue, is_first: bool| { | let add_field = |line: &mut String, key: &str, value: &OwnedValue, is_first: bool| { | ||||
if is_first { line.push_str(" "); } else { line.push_str(","); } | if is_first { line.push_str(" "); } else { line.push_str(","); } | ||||
line.push_str(&escape_tag(key)); | line.push_str(&escape_tag(key)); | ||||
@@ -543,7 +544,7 @@ pub fn writer(warnings: Sender<Warning>) -> thread::JoinHandle<()> { | |||||
Ok(Response { status, .. }) if status == StatusCode::NoContent => {} | Ok(Response { status, .. }) if status == StatusCode::NoContent => {} | ||||
Ok(mut resp) => { | Ok(mut resp) => { | ||||
resp.read_to_string(&mut server_resp); //.unwrap_or(0); | |||||
let _ = resp.read_to_string(&mut server_resp); //.unwrap_or(0); | |||||
let _ = warnings.send( | let _ = warnings.send( | ||||
Warning::Error( | Warning::Error( | ||||
format!("Influx server: {}", server_resp))); | format!("Influx server: {}", server_resp))); | ||||
@@ -582,9 +583,6 @@ pub struct OwnedMeasurement { | |||||
pub timestamp: Option<i64>, | pub timestamp: Option<i64>, | ||||
pub fields: Map<&'static str, OwnedValue>, | pub fields: Map<&'static str, OwnedValue>, | ||||
pub tags: Map<&'static str, &'static str>, | pub tags: Map<&'static str, &'static str>, | ||||
//pub n_tags: usize, | |||||
//pub n_fields: usize, | |||||
//pub string_tags: HashMap<&'static str, String> | |||||
} | } | ||||
impl OwnedMeasurement { | impl OwnedMeasurement { | ||||
@@ -594,9 +592,6 @@ impl OwnedMeasurement { | |||||
timestamp: None, | timestamp: None, | ||||
tags: new_map(n_tags), | tags: new_map(n_tags), | ||||
fields: new_map(n_fields), | fields: new_map(n_fields), | ||||
//n_tags, | |||||
//n_fields, | |||||
//string_tags: HashMap::new() | |||||
} | } | ||||
} | } | ||||
@@ -609,11 +604,6 @@ impl OwnedMeasurement { | |||||
self | self | ||||
} | } | ||||
// pub fn add_string_tag(mut self, key: &'static str, value: String) -> Self { | |||||
// self.string_tags.insert(key, value); | |||||
// self | |||||
// } | |||||
pub fn add_field(mut self, key: &'static str, value: OwnedValue) -> Self { | pub fn add_field(mut self, key: &'static str, value: OwnedValue) -> Self { | ||||
self.fields.insert(key, value); | self.fields.insert(key, value); | ||||
self | self | ||||
@@ -630,6 +620,7 @@ impl OwnedMeasurement { | |||||
} | } | ||||
} | } | ||||
#[allow(unused_imports, unused_variables)] | |||||
#[cfg(test)] | #[cfg(test)] | ||||
mod tests { | mod tests { | ||||
use super::*; | use super::*; | ||||
@@ -735,7 +726,7 @@ mod tests { | |||||
int [ seven => { 1 + 2 } ], | int [ seven => { 1 + 2 } ], | ||||
time [ 1 ] | time [ 1 ] | ||||
); | ); | ||||
thread::sleep_ms(10); | |||||
thread::sleep(Duration::from_millis(10)); | |||||
let meas: OwnedMeasurement = rx.try_recv().unwrap(); | let meas: OwnedMeasurement = rx.try_recv().unwrap(); | ||||
assert_eq!(meas.key, "test_measurement"); | assert_eq!(meas.key, "test_measurement"); | ||||
assert_eq!(meas.tags.get("one"), Some(&"a")); | assert_eq!(meas.tags.get("one"), Some(&"a")); | ||||
@@ -759,7 +750,7 @@ mod tests { | |||||
time[t] | time[t] | ||||
); | ); | ||||
thread::sleep_ms(10); | |||||
thread::sleep(Duration::from_millis(10)); | |||||
let meas: OwnedMeasurement = rx.try_recv().unwrap(); | let meas: OwnedMeasurement = rx.try_recv().unwrap(); | ||||
assert_eq!(meas.key, "test_measurement"); | assert_eq!(meas.key, "test_measurement"); | ||||
assert_eq!(meas.tags.get("one"), Some(&"a")); | assert_eq!(meas.tags.get("one"), Some(&"a")); | ||||
@@ -783,7 +774,7 @@ mod tests { | |||||
time[1] | time[1] | ||||
); | ); | ||||
thread::sleep_ms(10); | |||||
thread::sleep(Duration::from_millis(10)); | |||||
let meas: OwnedMeasurement = rx.try_recv().unwrap(); | let meas: OwnedMeasurement = rx.try_recv().unwrap(); | ||||
assert_eq!(meas.key, "test_measurement"); | assert_eq!(meas.key, "test_measurement"); | ||||
assert_eq!(meas.tags.get("one"), Some(&"a")); | assert_eq!(meas.tags.get("one"), Some(&"a")); | ||||
@@ -872,7 +863,7 @@ mod tests { | |||||
let now = now(); | let now = now(); | ||||
meas.set_timestamp(now); | meas.set_timestamp(now); | ||||
serialize(&meas, &mut buf); | serialize(&meas, &mut buf); | ||||
socket.send_str(&buf, 0); | |||||
socket.send_str(&buf, 0).unwrap(); | |||||
drop(w); | drop(w); | ||||
} | } | ||||
@@ -914,7 +905,7 @@ mod tests { | |||||
Ok(Response { status, .. }) if status == StatusCode::NoContent => {} | Ok(Response { status, .. }) if status == StatusCode::NoContent => {} | ||||
Ok(mut resp) => { | Ok(mut resp) => { | ||||
resp.read_to_string(&mut server_resp); //.unwrap_or(0); | |||||
resp.read_to_string(&mut server_resp).unwrap(); | |||||
panic!("{}", server_resp); | panic!("{}", server_resp); | ||||
} | } | ||||
@@ -968,7 +959,7 @@ mod tests { | |||||
let raw = r#"error encountered trying to send krkn order: Other("Failed to send http request: Other("Resource temporarily unavailable (os error 11)")")"#; | let raw = r#"error encountered trying to send krkn order: Other("Failed to send http request: Other("Resource temporarily unavailable (os error 11)")")"#; | ||||
let mut buf = String::new(); | let mut buf = String::new(); | ||||
let mut server_resp = String::new(); | let mut server_resp = String::new(); | ||||
let mut m = OwnedMeasurement::new("rust_test") | |||||
let m = OwnedMeasurement::new("rust_test") | |||||
.add_field("s", OwnedValue::String(raw.to_string())) | .add_field("s", OwnedValue::String(raw.to_string())) | ||||
.set_timestamp(now()); | .set_timestamp(now()); | ||||
serialize_owned(&m, &mut buf); | serialize_owned(&m, &mut buf); | ||||
@@ -987,7 +978,7 @@ mod tests { | |||||
Ok(Response { status, .. }) if status == StatusCode::NoContent => {} | Ok(Response { status, .. }) if status == StatusCode::NoContent => {} | ||||
Ok(mut resp) => { | Ok(mut resp) => { | ||||
resp.read_to_string(&mut server_resp); //.unwrap_or(0); | |||||
resp.read_to_string(&mut server_resp).unwrap(); | |||||
panic!("{}", server_resp); | panic!("{}", server_resp); | ||||
} | } | ||||
@@ -1,19 +1,14 @@ | |||||
use std::thread::{self, JoinHandle}; | use std::thread::{self, JoinHandle}; | ||||
use std::sync::{Arc, Mutex, RwLock}; | |||||
use std::sync::mpsc::{self, Sender, Receiver, channel}; | |||||
use std::collections::VecDeque; | |||||
use std::fmt::{self, Display, Write}; | |||||
use std::sync::mpsc::{Sender, channel}; | |||||
use std::fmt; | |||||
use std::time::{Instant, Duration}; | use std::time::{Instant, Duration}; | ||||
use chrono::{self, DateTime, Utc, TimeZone}; | |||||
use chrono::{self, DateTime, Utc}; | |||||
use pub_sub::PubSub; | use pub_sub::PubSub; | ||||
use zmq; | |||||
use influent::measurement::{Measurement, Value}; | |||||
use sloggers::types::Severity; | use sloggers::types::Severity; | ||||
//use chashmap::CHashMap; | |||||
use windows::{DurationWindow, Incremental, Window}; | use windows::{DurationWindow, Incremental, Window}; | ||||
use money::{Ticker, Side, ByExchange, Exchange}; | |||||
use money::{Ticker, Side, Exchange}; | |||||
use super::file_logger; | use super::file_logger; | ||||
use influx::{self, OwnedMeasurement, OwnedValue}; | use influx::{self, OwnedMeasurement, OwnedValue}; | ||||
@@ -37,24 +32,22 @@ pub fn dt_nanos(t: DateTime<Utc>) -> i64 { | |||||
pub fn now() -> i64 { dt_nanos(Utc::now()) } | pub fn now() -> i64 { dt_nanos(Utc::now()) } | ||||
pub fn tfmt(ns: Nanos) -> String { | pub fn tfmt(ns: Nanos) -> String { | ||||
let mut f = String::new(); | |||||
match ns { | match ns { | ||||
t if t <= MICROSECOND => { | t if t <= MICROSECOND => { | ||||
write!(f, "{}ns", t); | |||||
format!("{}ns", t) | |||||
} | } | ||||
t if t > MICROSECOND && t < MILLISECOND => { | t if t > MICROSECOND && t < MILLISECOND => { | ||||
write!(f, "{}u", t / MICROSECOND); | |||||
format!("{}u", t / MICROSECOND) | |||||
} | } | ||||
t if t > MILLISECOND && t < SECOND => { | t if t > MILLISECOND && t < SECOND => { | ||||
write!(f, "{}ms", t / MILLISECOND); | |||||
format!("{}ms", t / MILLISECOND) | |||||
} | } | ||||
t => { | t => { | ||||
write!(f, "{}.{}sec", t / SECOND, t / MILLISECOND); | |||||
format!("{}.{}sec", t / SECOND, t / MILLISECOND) | |||||
} | } | ||||
} | } | ||||
f | |||||
} | } | ||||
pub fn tfmt_dur(d: Duration) -> String { | pub fn tfmt_dur(d: Duration) -> String { | ||||
@@ -70,21 +63,22 @@ pub fn tfmt_dt(dt: DateTime<Utc>) -> String { | |||||
} | } | ||||
pub fn tfmt_write(ns: Nanos, f: &mut fmt::Formatter) { | |||||
pub fn tfmt_write(ns: Nanos, f: &mut fmt::Formatter) -> fmt::Result { | |||||
match ns { | match ns { | ||||
t if t <= MICROSECOND => { | t if t <= MICROSECOND => { | ||||
write!(f, "{}ns", t); | |||||
write!(f, "{}ns", t) | |||||
} | } | ||||
t if t > MICROSECOND && t < MILLISECOND => { | t if t > MICROSECOND && t < MILLISECOND => { | ||||
write!(f, "{}u", t / MICROSECOND); | |||||
write!(f, "{}u", t / MICROSECOND) | |||||
} | } | ||||
t if t > MILLISECOND && t < SECOND => { | t if t > MILLISECOND && t < SECOND => { | ||||
write!(f, "{}ms", t / MILLISECOND); | |||||
write!(f, "{}ms", t / MILLISECOND) | |||||
} | } | ||||
t => { | t => { | ||||
write!(f, "{}.{}sec", t / SECOND, t / MILLISECOND); | |||||
write!(f, "{}.{}sec", t / SECOND, t / MILLISECOND) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -101,69 +95,19 @@ pub enum Latency { | |||||
pub enum ExperiencedLatency { | pub enum ExperiencedLatency { | ||||
GdaxWebsocket(Duration), | GdaxWebsocket(Duration), | ||||
//GdaxWebsocketNoLock(Duration), | |||||
GdaxHttpPublic(Duration), | GdaxHttpPublic(Duration), | ||||
GdaxHttpPrivate(Duration), | GdaxHttpPrivate(Duration), | ||||
PlnxHttpPublic(Duration), | PlnxHttpPublic(Duration), | ||||
PlnxHttpPrivate(Duration), | PlnxHttpPrivate(Duration), | ||||
PlnxOrderBook(Duration), | PlnxOrderBook(Duration), | ||||
ExmoHttpPublic(Duration), | |||||
KrknHttpPublic(Duration), | KrknHttpPublic(Duration), | ||||
KrknHttpPrivate(Duration), | KrknHttpPrivate(Duration), | ||||
KrknTrade(Duration, &'static str, Option<Ticker>, Option<Side>), | KrknTrade(Duration, &'static str, Option<Ticker>, Option<Side>), | ||||
EventLoop(Duration), | |||||
PlnxWs(Ticker), | PlnxWs(Ticker), | ||||
Terminate | Terminate | ||||
} | } | ||||
// impl Message for ExperiencedLatency { | |||||
// fn kill_switch() -> Self { | |||||
// ExperiencedLatency::Terminate | |||||
// } | |||||
// } | |||||
/// represents over what period of time | |||||
/// the latency measurements were taken | |||||
pub trait MeasurementWindow { | |||||
fn duration(&self) -> Duration; | |||||
} | |||||
#[derive(Debug, Clone, Copy)] | |||||
pub struct WThirty; | |||||
impl Default for WThirty { | |||||
fn default() -> Self { WThirty {} } | |||||
} | |||||
impl MeasurementWindow for WThirty { | |||||
fn duration(&self) -> Duration { Duration::from_secs(30) } | |||||
} | |||||
#[derive(Debug, Clone, Copy)] | |||||
pub struct WTen; | |||||
impl Default for WTen { | |||||
fn default() -> Self { WTen {} } | |||||
} | |||||
impl MeasurementWindow for WTen { | |||||
fn duration(&self) -> Duration { Duration::from_secs(10) } | |||||
} | |||||
#[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||
pub struct Update { | pub struct Update { | ||||
pub gdax_ws: Nanos, | pub gdax_ws: Nanos, | ||||
@@ -182,9 +126,7 @@ impl Default for Update { | |||||
} | } | ||||
#[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||
pub struct LatencyUpdate<W> | |||||
where W: MeasurementWindow | |||||
{ | |||||
pub struct LatencyUpdate { | |||||
pub gdax_ws: Nanos, | pub gdax_ws: Nanos, | ||||
pub krkn_pub: Nanos, | pub krkn_pub: Nanos, | ||||
pub krkn_priv: Nanos, | pub krkn_priv: Nanos, | ||||
@@ -201,94 +143,38 @@ pub struct LatencyUpdate<W> | |||||
pub krkn_last: DateTime<Utc>, | pub krkn_last: DateTime<Utc>, | ||||
pub plnx_ws_count: u64, | pub plnx_ws_count: u64, | ||||
//pub event_loop: Nanos, | |||||
pub size: W, | |||||
} | } | ||||
impl<W> Default for LatencyUpdate<W> | |||||
where W: MeasurementWindow + Default | |||||
{ | |||||
impl Default for LatencyUpdate { | |||||
fn default() -> Self { | fn default() -> Self { | ||||
LatencyUpdate { | LatencyUpdate { | ||||
gdax_ws: Nanos::default(), | |||||
krkn_pub: Nanos::default(), | |||||
krkn_priv: Nanos::default(), | |||||
plnx_pub: Nanos::default(), | |||||
plnx_priv: Nanos::default(), | |||||
plnx_order: Nanos::default(), | |||||
krkn_trade_30_mean: Nanos::default(), | |||||
krkn_trade_30_max: Nanos::default(), | |||||
krkn_trade_300_mean: Nanos::default(), | |||||
krkn_trade_300_max: Nanos::default(), | |||||
plnx_ws_count: 0, | |||||
plnx_last: Utc::now(), | |||||
krkn_last: Utc::now(), | |||||
size: W::default() | |||||
gdax_ws : 0, | |||||
krkn_pub : 0, | |||||
krkn_priv : 0, | |||||
plnx_pub : 0, | |||||
plnx_priv : 0, | |||||
plnx_order : 0, | |||||
krkn_trade_30_mean : 0, | |||||
krkn_trade_30_max : 0, | |||||
krkn_trade_300_mean : 0, | |||||
krkn_trade_300_max : 0, | |||||
plnx_ws_count : 0, | |||||
plnx_last : Utc::now(), | |||||
krkn_last : Utc::now(), | |||||
} | } | ||||
} | } | ||||
} | } | ||||
impl<W> Display for LatencyUpdate<W> | |||||
where W: MeasurementWindow | |||||
{ | |||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |||||
write!(f, " gdax ws: "); | |||||
tfmt_write(self.gdax_ws, f); | |||||
write!(f, "\n krkn pub: "); | |||||
tfmt_write(self.krkn_pub, f); | |||||
write!(f, "\n krkn priv: "); | |||||
tfmt_write(self.krkn_priv, f); | |||||
write!(f, "\n krkn trade 30 mean: "); | |||||
tfmt_write(self.krkn_trade_30_mean, f); | |||||
write!(f, "\n krkn trade 30 max: "); | |||||
tfmt_write(self.krkn_trade_30_max, f); | |||||
write!(f, "\n krkn trade 300 mean: "); | |||||
tfmt_write(self.krkn_trade_300_mean, f); | |||||
write!(f, "\n krkn trade 300 max: "); | |||||
tfmt_write(self.krkn_trade_300_max, f); | |||||
write!(f, "\n plnx pub: "); | |||||
tfmt_write(self.plnx_pub, f); | |||||
write!(f, "\n plnx priv: "); | |||||
tfmt_write(self.plnx_priv, f); | |||||
write!(f, "\n plnx orderbook loop: "); | |||||
tfmt_write(self.plnx_order, f); | |||||
//write!(f, "\n gdax ws nolock: "); | |||||
//tfmt_write(self.gdax_ws_nolock, f); | |||||
//write!(f, "\n event loop: "); | |||||
//tfmt(self.event_loop, f); | |||||
write!(f,"") | |||||
} | |||||
} | |||||
impl<W: MeasurementWindow> LatencyUpdate<W> { | |||||
pub fn measurement_window(&self) -> Duration { | |||||
self.size.duration() | |||||
} | |||||
} | |||||
pub struct Manager { | pub struct Manager { | ||||
pub tx: Sender<Latency>, | pub tx: Sender<Latency>, | ||||
pub channel: PubSub<Update>, | pub channel: PubSub<Update>, | ||||
thread: Option<JoinHandle<()>>, | thread: Option<JoinHandle<()>>, | ||||
} | } | ||||
pub struct LatencyManager<W> | |||||
where W: MeasurementWindow + Clone + Send + Sync | |||||
{ | |||||
pub struct LatencyManager { | |||||
pub tx: Sender<ExperiencedLatency>, | pub tx: Sender<ExperiencedLatency>, | ||||
pub channel: PubSub<LatencyUpdate<W>>, | |||||
pub channel: PubSub<LatencyUpdate>, | |||||
thread: Option<JoinHandle<()>>, | thread: Option<JoinHandle<()>>, | ||||
} | } | ||||
@@ -323,7 +209,6 @@ impl Manager { | |||||
measurements: Sender<OwnedMeasurement>) -> Self { | measurements: Sender<OwnedMeasurement>) -> Self { | ||||
let (tx, rx) = channel(); | let (tx, rx) = channel(); | ||||
let tx_copy = tx.clone(); | |||||
let channel = PubSub::new(); | let channel = PubSub::new(); | ||||
let channel_copy = channel.clone(); | let channel_copy = channel.clone(); | ||||
let logger = file_logger(log_path, Severity::Info); | let logger = file_logger(log_path, Severity::Info); | ||||
@@ -336,25 +221,22 @@ impl Manager { | |||||
let mut last = Last::default(); | let mut last = Last::default(); | ||||
info!(logger, "entering loop"); | info!(logger, "entering loop"); | ||||
let mut terminate = false; | |||||
let thread = Some(thread::spawn(move || { | let thread = Some(thread::spawn(move || { | ||||
loop { | loop { | ||||
let loop_time = Instant::now(); | let loop_time = Instant::now(); | ||||
rx.try_recv().map(|msg| { | |||||
if let Ok(msg) = rx.recv_timeout(Duration::from_millis(1)) { | |||||
debug!(logger, "rcvd {:?}", msg); | debug!(logger, "rcvd {:?}", msg); | ||||
match msg { | match msg { | ||||
Latency::Ws(exch, ticker, dur) => { | |||||
// shortcut | |||||
Latency::Ws(_, _, dur) => { | |||||
gdax_ws.update(loop_time, dur); | gdax_ws.update(loop_time, dur); | ||||
last.gdax = loop_time; | last.gdax = loop_time; | ||||
} | } | ||||
Latency::Trade(exch, ticker, dur) => { | |||||
//shorcut | |||||
Latency::Trade(_, ticker, dur) => { | |||||
gdax_trade.update(loop_time, dur); | gdax_trade.update(loop_time, dur); | ||||
last.gdax = loop_time; | last.gdax = loop_time; | ||||
let nanos = DurationWindow::nanos(dur); | let nanos = DurationWindow::nanos(dur); | ||||
@@ -362,17 +244,14 @@ impl Manager { | |||||
OwnedMeasurement::new("gdax_trade_api") | OwnedMeasurement::new("gdax_trade_api") | ||||
.add_tag("ticker", ticker.to_str()) | .add_tag("ticker", ticker.to_str()) | ||||
.add_field("nanos", OwnedValue::Integer(nanos as i64)) | .add_field("nanos", OwnedValue::Integer(nanos as i64)) | ||||
.set_timestamp(influx::now())); | |||||
.set_timestamp(influx::now())).unwrap(); | |||||
} | } | ||||
Latency::Terminate => { | |||||
crit!(logger, "rcvd Terminate order"); | |||||
terminate = true; | |||||
} | |||||
Latency::Terminate => break, | |||||
_ => {} | _ => {} | ||||
} | } | ||||
}); | |||||
} | |||||
if loop_time - last.broadcast > Duration::from_millis(100) { | if loop_time - last.broadcast > Duration::from_millis(100) { | ||||
debug!(logger, "initalizing broadcast"); | debug!(logger, "initalizing broadcast"); | ||||
@@ -382,17 +261,13 @@ impl Manager { | |||||
gdax_trade: gdax_trade.refresh(&loop_time).mean_nanos(), | gdax_trade: gdax_trade.refresh(&loop_time).mean_nanos(), | ||||
gdax_last: dt_from_dur(loop_time - last.gdax) | gdax_last: dt_from_dur(loop_time - last.gdax) | ||||
}; | }; | ||||
channel.send(update); | |||||
channel.send(update).unwrap(); | |||||
last.broadcast = loop_time; | last.broadcast = loop_time; | ||||
debug!(logger, "sent broadcast"); | debug!(logger, "sent broadcast"); | ||||
} else { | |||||
#[cfg(feature = "no-thrash")] | |||||
thread::sleep(Duration::new(0, 1000)); | |||||
} | |||||
} | |||||
if terminate { break } | |||||
} | } | ||||
crit!(logger, "goodbye"); | |||||
debug!(logger, "latency manager terminating"); | |||||
})); | })); | ||||
Manager { | Manager { | ||||
@@ -403,54 +278,55 @@ impl Manager { | |||||
} | } | ||||
} | } | ||||
impl Drop for Manager { | |||||
impl Drop for LatencyManager { | |||||
fn drop(&mut self) { | fn drop(&mut self) { | ||||
self.tx.send(Latency::Terminate); | |||||
for _ in 0..100 { self.tx.send(ExperiencedLatency::Terminate).unwrap(); } | |||||
if let Some(thread) = self.thread.take() { | if let Some(thread) = self.thread.take() { | ||||
let _ = thread.join(); | let _ = thread.join(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
impl Drop for Manager { | |||||
fn drop(&mut self) { | |||||
for _ in 0..100 { self.tx.send(Latency::Terminate).unwrap(); } | |||||
if let Some(thread) = self.thread.take() { | |||||
let _ = thread.join(); | |||||
} | |||||
} | |||||
} | |||||
//impl<W: MeasurementWindow + Clone + Send + Sync> LatencyManager<W> { | |||||
impl LatencyManager<WTen> { | |||||
pub fn new(w: WTen) -> Self { | |||||
impl LatencyManager { | |||||
pub fn new(d: Duration) -> Self { | |||||
let (tx, rx) = channel(); | let (tx, rx) = channel(); | ||||
let tx_copy = tx.clone(); | let tx_copy = tx.clone(); | ||||
let channel = PubSub::new(); | let channel = PubSub::new(); | ||||
let channel_copy = channel.clone(); | let channel_copy = channel.clone(); | ||||
let w = w.clone(); | |||||
//let w = w.clone(); | |||||
let thread = Some(thread::spawn(move || { | let thread = Some(thread::spawn(move || { | ||||
let logger = file_logger("var/log/latency-manager.log", Severity::Info); | let logger = file_logger("var/log/latency-manager.log", Severity::Info); | ||||
info!(logger, "initializing zmq"); | info!(logger, "initializing zmq"); | ||||
let ctx = zmq::Context::new(); | |||||
let socket = influx::push(&ctx).unwrap(); | |||||
let mut buf = String::with_capacity(4096); | |||||
info!(logger, "initializing DurationWindows"); | info!(logger, "initializing DurationWindows"); | ||||
let mut gdax_ws = DurationWindow::new(w.duration()); | |||||
let mut gdax_priv = DurationWindow::new(w.duration()); | |||||
let mut krkn_pub = DurationWindow::new(w.duration()); | |||||
let mut krkn_priv = DurationWindow::new(w.duration()); | |||||
let mut plnx_pub = DurationWindow::new(w.duration()); | |||||
let mut plnx_priv = DurationWindow::new(w.duration()); | |||||
let mut plnx_order = DurationWindow::new(w.duration()); | |||||
let mut plnx_ws_count: Window<u32> = Window::new(w.duration()); | |||||
let mut gdax_ws = DurationWindow::new(d); | |||||
let mut gdax_priv = DurationWindow::new(d); | |||||
let mut krkn_pub = DurationWindow::new(d); | |||||
let mut krkn_priv = DurationWindow::new(d); | |||||
let mut plnx_pub = DurationWindow::new(d); | |||||
let mut plnx_priv = DurationWindow::new(d); | |||||
let mut plnx_order = DurationWindow::new(d); | |||||
let mut plnx_ws_count: Window<u32> = Window::new(d); | |||||
// yes I am intentionally breaking from the hard-typed duration | // yes I am intentionally breaking from the hard-typed duration | ||||
// window ... that was a stupid idea | // window ... that was a stupid idea | ||||
// | // | ||||
let mut krkn_trade_30 = DurationWindow::new(Duration::from_secs(30)); | let mut krkn_trade_30 = DurationWindow::new(Duration::from_secs(30)); | ||||
let mut krkn_trade_300 = DurationWindow::new(Duration::from_secs(300)); | let mut krkn_trade_300 = DurationWindow::new(Duration::from_secs(300)); | ||||
//let mut gdax_ws_nolock = DurationWindow::new(w.duration()); | |||||
//let mut event_loop = DurationWindow::new(w.duration()); | |||||
let mut last = Last::default(); | let mut last = Last::default(); | ||||
thread::sleep_ms(1); | |||||
thread::sleep(Duration::from_millis(1)); | |||||
info!(logger, "entering loop"); | info!(logger, "entering loop"); | ||||
loop { | loop { | ||||
@@ -466,7 +342,7 @@ impl LatencyManager<WTen> { | |||||
} | } | ||||
ExperiencedLatency::GdaxWebsocket(d) => gdax_ws.update(loop_time, d), | ExperiencedLatency::GdaxWebsocket(d) => gdax_ws.update(loop_time, d), | ||||
//ExperiencedLatency::GdaxWebsocketNoLock(d) => gdax_ws_nolock.update(loop_time, d), | |||||
ExperiencedLatency::GdaxHttpPrivate(d) => gdax_priv.update(loop_time, d), | ExperiencedLatency::GdaxHttpPrivate(d) => gdax_priv.update(loop_time, d), | ||||
ExperiencedLatency::KrknHttpPublic(d) => { | ExperiencedLatency::KrknHttpPublic(d) => { | ||||
@@ -499,30 +375,14 @@ impl LatencyManager<WTen> { | |||||
plnx_ws_count.update(loop_time, 1_u32); | plnx_ws_count.update(loop_time, 1_u32); | ||||
} | } | ||||
ExperiencedLatency::KrknTrade(d, cmd, ticker, side) => { | |||||
ExperiencedLatency::KrknTrade(d, cmd, _, _) => { | |||||
debug!(logger, "new KrknTrade"; | debug!(logger, "new KrknTrade"; | ||||
"cmd" => cmd); | "cmd" => cmd); | ||||
last.krkn = loop_time; | last.krkn = loop_time; | ||||
let n = DurationWindow::nanos(d); | |||||
krkn_trade_30.update(loop_time, d); | krkn_trade_30.update(loop_time, d); | ||||
krkn_trade_300.update(loop_time, d); | krkn_trade_300.update(loop_time, d); | ||||
// let ticker_s = ticker.map(|t| t.to_string()).unwrap_or("".into()); | |||||
// let side_s = side.map(|s| s.to_string()).unwrap_or("".into()); | |||||
// let mut m = Measurement::new("krkn_trade_api"); | |||||
// m.add_field("nanos", Value::Integer(n as i64)); | |||||
// m.add_tag("cmd", cmd); | |||||
// if ticker.is_some() { | |||||
// m.add_tag("ticker", &ticker_s); | |||||
// } | |||||
// if side.is_some() { | |||||
// m.add_tag("side", &side_s); | |||||
// } | |||||
// m.set_timestamp(now()); | |||||
// influx::serialize(&m, &mut buf); | |||||
// socket.send_str(&buf, 0); | |||||
// buf.clear(); | |||||
} | } | ||||
//ExperiencedLatency::EventLoop(d) => event_loop.update(Instant::now(), d), | |||||
other => { | other => { | ||||
warn!(logger, "unexpected msg: {:?}", other); | warn!(logger, "unexpected msg: {:?}", other); | ||||
} | } | ||||
@@ -539,7 +399,6 @@ impl LatencyManager<WTen> { | |||||
krkn_trade_300.refresh(&loop_time); | krkn_trade_300.refresh(&loop_time); | ||||
let update = LatencyUpdate { | let update = LatencyUpdate { | ||||
gdax_ws: gdax_ws.refresh(&loop_time).mean_nanos(), | gdax_ws: gdax_ws.refresh(&loop_time).mean_nanos(), | ||||
//gdax_ws_nolock: gdax_ws_nolock.refresh(&loop_time).mean_nanos(), | |||||
krkn_pub: krkn_pub.refresh(&loop_time).mean_nanos(), | krkn_pub: krkn_pub.refresh(&loop_time).mean_nanos(), | ||||
krkn_priv: krkn_priv.refresh(&loop_time).mean_nanos(), | krkn_priv: krkn_priv.refresh(&loop_time).mean_nanos(), | ||||
plnx_pub: plnx_pub.refresh(&loop_time).mean_nanos(), | plnx_pub: plnx_pub.refresh(&loop_time).mean_nanos(), | ||||
@@ -557,10 +416,8 @@ impl LatencyManager<WTen> { | |||||
plnx_ws_count: plnx_ws_count.refresh(&loop_time).count() as u64, | plnx_ws_count: plnx_ws_count.refresh(&loop_time).count() as u64, | ||||
//event_loop: event_loop.refresh(&now).mean_nanos(), | |||||
size: w.clone(), | |||||
}; | }; | ||||
channel.send(update); | |||||
channel.send(update).unwrap(); | |||||
last.broadcast = loop_time; | last.broadcast = loop_time; | ||||
debug!(logger, "sent broadcast"); | debug!(logger, "sent broadcast"); | ||||
} | } | ||||
@@ -575,9 +432,3 @@ impl LatencyManager<WTen> { | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -4,6 +4,8 @@ | |||||
#![feature(test)] | #![feature(test)] | ||||
#[macro_use] extern crate slog; | #[macro_use] extern crate slog; | ||||
#[allow(unused_imports)] | |||||
#[macro_use] extern crate money; | #[macro_use] extern crate money; | ||||
extern crate test; | extern crate test; | ||||
@@ -12,32 +14,28 @@ extern crate influent; | |||||
extern crate chrono; | extern crate chrono; | ||||
extern crate hyper; | extern crate hyper; | ||||
extern crate termion; | extern crate termion; | ||||
//extern crate pub_sub; | |||||
extern crate sloggers; | extern crate sloggers; | ||||
extern crate slog_term; | extern crate slog_term; | ||||
extern crate fnv; | extern crate fnv; | ||||
extern crate ordermap; | extern crate ordermap; | ||||
extern crate decimal; | extern crate decimal; | ||||
extern crate uuid; | extern crate uuid; | ||||
//extern crate shuteye; | |||||
//extern crate chashmap; | |||||
extern crate windows; | extern crate windows; | ||||
extern crate pubsub as pub_sub; | extern crate pubsub as pub_sub; | ||||
use std::sync::Arc; | |||||
use chrono::{DateTime, Utc}; | use chrono::{DateTime, Utc}; | ||||
#[allow(unused_imports)] | |||||
use sloggers::Build; | use sloggers::Build; | ||||
#[allow(unused_imports)] | |||||
use sloggers::types::{Severity, TimeZone}; | use sloggers::types::{Severity, TimeZone}; | ||||
#[allow(unused_imports)] | |||||
use sloggers::file::FileLoggerBuilder; | use sloggers::file::FileLoggerBuilder; | ||||
pub mod influx; | pub mod influx; | ||||
pub mod warnings; | pub mod warnings; | ||||
pub mod latency; | pub mod latency; | ||||
//pub type FileLogger = slog::Logger<Arc<slog::SendSyncRefUnwindSafeDrain<Ok=(), Err=slog::private::NeverStruct>>>; | |||||
/// converts a chrono::DateTime to an integer timestamp (ns) | /// converts a chrono::DateTime to an integer timestamp (ns) | ||||
/// | /// | ||||
pub fn nanos(t: DateTime<Utc>) -> u64 { | pub fn nanos(t: DateTime<Utc>) -> u64 { | ||||
@@ -52,9 +50,8 @@ pub fn file_logger(path: &str, level: Severity) -> slog::Logger { | |||||
builder.build().unwrap() | builder.build().unwrap() | ||||
} | } | ||||
#[cfg(any(test, feature = "test"))] | #[cfg(any(test, feature = "test"))] | ||||
pub fn file_logger(path: &str, level: Severity) -> slog::Logger { | |||||
pub fn file_logger(_: &str, _: Severity) -> slog::Logger { | |||||
use slog::*; | use slog::*; | ||||
Logger::root(Discard, o!()) | Logger::root(Discard, o!()) | ||||
} | } | ||||
@@ -3,14 +3,14 @@ | |||||
use std::thread::{self, JoinHandle}; | use std::thread::{self, JoinHandle}; | ||||
use std::sync::{Arc, Mutex, RwLock}; | use std::sync::{Arc, Mutex, RwLock}; | ||||
use std::sync::mpsc::{self, Sender, Receiver, channel}; | |||||
use std::sync::mpsc::{Sender, channel}; | |||||
use std::collections::{BTreeMap, VecDeque}; | use std::collections::{BTreeMap, VecDeque}; | ||||
use std::fmt::{self, Display, Error as FmtError, Formatter}; | use std::fmt::{self, Display, Error as FmtError, Formatter}; | ||||
use std::io::{self, Read, Write}; | |||||
use std::io::{self, Write}; | |||||
use std::fs; | use std::fs; | ||||
use zmq; | use zmq; | ||||
use chrono::{DateTime, Utc, TimeZone}; | |||||
use chrono::{DateTime, Utc}; | |||||
use termion::color::{self, Fg, Bg}; | use termion::color::{self, Fg, Bg}; | ||||
use influent::measurement::{Measurement, Value as InfluentValue}; | use influent::measurement::{Measurement, Value as InfluentValue}; | ||||
use slog::{self, OwnedKVList, Drain, Key, KV, Level, Logger}; | use slog::{self, OwnedKVList, Drain, Key, KV, Level, Logger}; | ||||
@@ -188,17 +188,11 @@ impl Warning { | |||||
impl Display for Warning { | impl Display for Warning { | ||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { | fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { | ||||
self.category(f); | |||||
self.category(f)?; | |||||
write!(f, " {}", self.msg()) | write!(f, " {}", self.msg()) | ||||
} | } | ||||
} | } | ||||
// impl Message for Warning { | |||||
// fn kill_switch() -> Self { | |||||
// Warning::Terminate | |||||
// } | |||||
// } | |||||
#[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||
pub struct Record { | pub struct Record { | ||||
pub time: DateTime<Utc>, | pub time: DateTime<Utc>, | ||||
@@ -252,7 +246,6 @@ impl Value { | |||||
#[derive(Debug, Clone, PartialEq)] | #[derive(Debug, Clone, PartialEq)] | ||||
pub struct MeasurementRecord { | pub struct MeasurementRecord { | ||||
fields: Vec<(Key, Value)>, | fields: Vec<(Key, Value)>, | ||||
//measurement: &'a mut Measurement<'a>, | |||||
tags: Vec<(Key, String)>, | tags: Vec<(Key, String)>, | ||||
} | } | ||||
@@ -276,7 +269,7 @@ impl MeasurementRecord { | |||||
} | } | ||||
other => { | other => { | ||||
self.add_field(key, Value::String(val)); | |||||
self.add_field(other, Value::String(val)).unwrap(); | |||||
} | } | ||||
} | } | ||||
@@ -285,7 +278,7 @@ impl MeasurementRecord { | |||||
pub fn serialize_values(&mut self, record: &slog::Record, values: &OwnedKVList) { | pub fn serialize_values(&mut self, record: &slog::Record, values: &OwnedKVList) { | ||||
let mut builder = TagBuilder { mrec: self }; | let mut builder = TagBuilder { mrec: self }; | ||||
values.serialize(record, &mut builder); | |||||
let _ = values.serialize(record, &mut builder); | |||||
} | } | ||||
pub fn to_measurement<'a>(&'a self, name: &'a str) -> Measurement<'a> { | pub fn to_measurement<'a>(&'a self, name: &'a str) -> Measurement<'a> { | ||||
@@ -313,7 +306,7 @@ impl MeasurementRecord { | |||||
impl slog::Serializer for MeasurementRecord { | impl slog::Serializer for MeasurementRecord { | ||||
fn emit_usize(&mut self, key: Key, val: usize) -> SlogResult { self.add_field(key, Value::Integer(val as i64)) } | fn emit_usize(&mut self, key: Key, val: usize) -> SlogResult { self.add_field(key, Value::Integer(val as i64)) } | ||||
fn emit_isize(&mut self, key: Key, val: isize) -> SlogResult { self.add_field(key, Value::Integer(val as i64)) } | fn emit_isize(&mut self, key: Key, val: isize) -> SlogResult { self.add_field(key, Value::Integer(val as i64)) } | ||||
fn emit_bool(&mut self, key: Key, val: bool) -> SlogResult { self.add_field(key, Value::Boolean(val)); Ok(()) } | |||||
fn emit_bool(&mut self, key: Key, val: bool) -> SlogResult { self.add_field(key, Value::Boolean(val)) } | |||||
fn emit_u8(&mut self, key: Key, val: u8) -> SlogResult { self.add_field(key, Value::Integer(val as i64)) } | fn emit_u8(&mut self, key: Key, val: u8) -> SlogResult { self.add_field(key, Value::Integer(val as i64)) } | ||||
fn emit_i8(&mut self, key: Key, val: i8) -> SlogResult { self.add_field(key, Value::Integer(val as i64)) } | fn emit_i8(&mut self, key: Key, val: i8) -> SlogResult { self.add_field(key, Value::Integer(val as i64)) } | ||||
fn emit_u16(&mut self, key: Key, val: u16) -> SlogResult { self.add_field(key, Value::Integer(val as i64)) } | fn emit_u16(&mut self, key: Key, val: u16) -> SlogResult { self.add_field(key, Value::Integer(val as i64)) } | ||||
@@ -326,7 +319,7 @@ impl slog::Serializer for MeasurementRecord { | |||||
fn emit_f64(&mut self, key: Key, val: f64) -> SlogResult { self.add_field(key, Value::Float(val)) } | fn emit_f64(&mut self, key: Key, val: f64) -> SlogResult { self.add_field(key, Value::Float(val)) } | ||||
fn emit_str(&mut self, key: Key, val: &str) -> SlogResult { self.add_field(key, Value::String(val.to_string())) } | fn emit_str(&mut self, key: Key, val: &str) -> SlogResult { self.add_field(key, Value::String(val.to_string())) } | ||||
fn emit_unit(&mut self, key: Key) -> SlogResult { self.add_field(key, Value::Boolean(true)) } | fn emit_unit(&mut self, key: Key) -> SlogResult { self.add_field(key, Value::Boolean(true)) } | ||||
fn emit_none(&mut self, key: Key) -> SlogResult { Ok(()) } //self.add_field(key, Value::String("none".into())) } | |||||
fn emit_none(&mut self, _: Key) -> SlogResult { Ok(()) } //self.add_field(key, Value::String("none".into())) } | |||||
fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> SlogResult { self.add_field(key, Value::String(val.to_string())) } | fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> SlogResult { self.add_field(key, Value::String(val.to_string())) } | ||||
} | } | ||||
@@ -342,7 +335,7 @@ impl<'a> slog::Serializer for TagBuilder<'a> { | |||||
} | } | ||||
other => { | other => { | ||||
self.mrec.add_field(key, Value::String(val.to_string())) | |||||
self.mrec.add_field(other, Value::String(val.to_string())) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -354,7 +347,7 @@ impl<'a> slog::Serializer for TagBuilder<'a> { | |||||
} | } | ||||
other => { | other => { | ||||
self.mrec.add_field(key, Value::String(val.to_string())) | |||||
self.mrec.add_field(other, Value::String(val.to_string())) | |||||
} | } | ||||
} | } | ||||
@@ -392,7 +385,7 @@ impl<D: Drain> Drain for WarningsDrain<D> { | |||||
if record.level() <= self.level { | if record.level() <= self.level { | ||||
let mut ser = MeasurementRecord::new(); | let mut ser = MeasurementRecord::new(); | ||||
ser.serialize_values(record, values); | ser.serialize_values(record, values); | ||||
record.kv().serialize(record, &mut ser); | |||||
let _ = record.kv().serialize(record, &mut ser); | |||||
let msg = record.msg().to_string(); | let msg = record.msg().to_string(); | ||||
if let Ok(lock) = self.tx.lock() { | if let Ok(lock) = self.tx.lock() { | ||||
let _ = lock.send(Warning::Log { | let _ = lock.send(Warning::Log { | ||||
@@ -413,7 +406,6 @@ impl<D: Drain> Drain for WarningsDrain<D> { | |||||
} | } | ||||
} | } | ||||
#[derive(Debug)] | #[derive(Debug)] | ||||
pub struct WarningsManager { | pub struct WarningsManager { | ||||
pub tx: Sender<Warning>, | pub tx: Sender<Warning>, | ||||
@@ -440,11 +432,11 @@ impl WarningsManager { | |||||
if let Ok(msg) = rx.recv() { | if let Ok(msg) = rx.recv() { | ||||
match msg { | match msg { | ||||
Warning::Terminate => { | Warning::Terminate => { | ||||
crit!(logger, "terminating"); | |||||
debug!(logger, "terminating"); | |||||
break; | break; | ||||
} | } | ||||
Warning::Log { level, module, function, line, msg, kv } => { | |||||
Warning::Log { level, msg, kv, .. } => { | |||||
debug!(logger, "new Warning::Debug arrived"; | debug!(logger, "new Warning::Debug arrived"; | ||||
"msg" => &msg); | "msg" => &msg); | ||||
let mut meas = kv.to_measurement(measurement_name); | let mut meas = kv.to_measurement(measurement_name); | ||||
@@ -489,11 +481,12 @@ impl Drop for WarningsManager { | |||||
fn drop(&mut self) { | fn drop(&mut self) { | ||||
let _ = self.tx.send(Warning::Terminate); | let _ = self.tx.send(Warning::Terminate); | ||||
if let Some(thread) = self.thread.take() { | if let Some(thread) = self.thread.take() { | ||||
thread.join(); | |||||
thread.join().unwrap(); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
#[allow(dead_code)] | |||||
pub struct ZmqDrain<D> | pub struct ZmqDrain<D> | ||||
where D: Drain, | where D: Drain, | ||||
{ | { | ||||
@@ -533,24 +526,25 @@ impl<D> Drain for ZmqDrain<D> | |||||
fn log(&self, record: &slog::Record, values: &OwnedKVList) -> Result<Self::Ok, Self::Err> { | fn log(&self, record: &slog::Record, values: &OwnedKVList) -> Result<Self::Ok, Self::Err> { | ||||
{ | { | ||||
let mut buf = self.buf.lock().unwrap(); | let mut buf = self.buf.lock().unwrap(); | ||||
write!(buf, "{time} {level}", | |||||
let _ = write!(buf, "{time} {level}", | |||||
time = Utc::now().format(TIMESTAMP_FORMAT), | time = Utc::now().format(TIMESTAMP_FORMAT), | ||||
level = record.level().as_short_str()); | level = record.level().as_short_str()); | ||||
{ | { | ||||
let mut thread_ser = ThreadSer(&mut buf); | let mut thread_ser = ThreadSer(&mut buf); | ||||
record.kv().serialize(record, &mut thread_ser); | |||||
values.serialize(record, &mut thread_ser); | |||||
let _ = record.kv().serialize(record, &mut thread_ser); | |||||
let _ = values.serialize(record, &mut thread_ser); | |||||
} | } | ||||
write!(buf, " {file:<20} {line:<5} {msg}", | |||||
file = record.file(), | |||||
line = record.line(), | |||||
msg = record.msg()); | |||||
let _ = write!(buf, " {file:<20} {line:<5} {msg}", | |||||
file = record.file(), | |||||
line = record.line(), | |||||
msg = record.msg()); | |||||
{ | { | ||||
let mut kv_ser = KvSer(&mut buf); | let mut kv_ser = KvSer(&mut buf); | ||||
record.kv().serialize(record, &mut kv_ser); | |||||
values.serialize(record, &mut kv_ser); | |||||
// discarding any errors here... | |||||
let _ = record.kv().serialize(record, &mut kv_ser); | |||||
let _ = values.serialize(record, &mut kv_ser); | |||||
} | } | ||||
let _ = self.socket.send(&buf, 0); | let _ = self.socket.send(&buf, 0); | ||||
@@ -563,6 +557,7 @@ impl<D> Drain for ZmqDrain<D> | |||||
/// Can be used as a `Write` with `slog_term` and | /// Can be used as a `Write` with `slog_term` and | ||||
/// other libraries. | /// other libraries. | ||||
/// | /// | ||||
#[allow(dead_code)] | |||||
pub struct ZmqIo { | pub struct ZmqIo { | ||||
ctx: zmq::Context, | ctx: zmq::Context, | ||||
socket: zmq::Socket, | socket: zmq::Socket, | ||||
@@ -611,13 +606,13 @@ impl Write for ZmqIo { | |||||
struct ThreadSer<'a>(&'a mut Vec<u8>); | struct ThreadSer<'a>(&'a mut Vec<u8>); | ||||
impl<'a> slog::ser::Serializer for ThreadSer<'a> { | impl<'a> slog::ser::Serializer for ThreadSer<'a> { | ||||
fn emit_arguments(&mut self, key: &str, val: &fmt::Arguments) -> slog::Result { | |||||
fn emit_arguments(&mut self, _: &str, _: &fmt::Arguments) -> slog::Result { | |||||
Ok(()) | Ok(()) | ||||
} | } | ||||
fn emit_str(&mut self, key: &str, val: &str) -> slog::Result { | fn emit_str(&mut self, key: &str, val: &str) -> slog::Result { | ||||
if key == "thread" { | if key == "thread" { | ||||
write!(self.0, " {:<20}", val); | |||||
write!(self.0, " {:<20}", val)?; | |||||
} | } | ||||
Ok(()) | Ok(()) | ||||
} | } | ||||
@@ -717,6 +712,7 @@ impl<'a> slog::ser::Serializer for KvSer<'a> { | |||||
} | } | ||||
} | } | ||||
#[allow(unused_variables, unused_imports)] | |||||
#[cfg(test)] | #[cfg(test)] | ||||
mod tests { | mod tests { | ||||
use super::*; | use super::*; | ||||
@@ -735,9 +731,6 @@ mod tests { | |||||
level: Level::Trace, | level: Level::Trace, | ||||
}; | }; | ||||
let logger = slog::Logger::root(drain, o!()); | let logger = slog::Logger::root(drain, o!()); | ||||
//for _ in 0..60 { | |||||
// debug!(logger, "test 123"; "exchange" => "plnx"); | |||||
//} | |||||
} | } | ||||
#[bench] | #[bench] | ||||
@@ -765,6 +758,5 @@ mod tests { | |||||
let _ = tx.lock().unwrap().send(Msg::Terminate); | let _ = tx.lock().unwrap().send(Msg::Terminate); | ||||
let len = worker.join().unwrap(); | let len = worker.join().unwrap(); | ||||
//println!("{}", len); | //println!("{}", len); | ||||
} | } | ||||
} | } |