From b3e9bc5e119c5106d88e2696208894acf967ffc5 Mon Sep 17 00:00:00 2001 From: Rostyslav Ivanika Date: Sun, 17 Jan 2021 18:37:38 +0200 Subject: [PATCH] separate code into lib and binary --- Cargo.toml | 1 + rsloglib/Cargo.toml | 11 +++ rsloglib/src/lib.rs | 5 + {src => rsloglib/src}/slowlog.rs | 4 +- {src => rsloglib/src}/slowlog_reader.rs | 30 +++++- src/lib.rs | 121 ------------------------ src/main.rs | 101 +++++++++++++++++++- 7 files changed, 143 insertions(+), 130 deletions(-) create mode 100644 rsloglib/Cargo.toml create mode 100644 rsloglib/src/lib.rs rename {src => rsloglib/src}/slowlog.rs (95%) rename {src => rsloglib/src}/slowlog_reader.rs (79%) delete mode 100644 src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index c83d49d..62cce3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [dependencies] +rsloglib = {path = "rsloglib"} redis = "0.19.0" log = "0.4.11" stderrlog = "0.5" diff --git a/rsloglib/Cargo.toml b/rsloglib/Cargo.toml new file mode 100644 index 0000000..30d4d2c --- /dev/null +++ b/rsloglib/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "rsloglib" +version = "0.1.0" +authors = ["Rostyslav Ivanika "] +edition = "2018" + + +[dependencies] +redis = "0.19.0" +log = "0.4.11" +serde = {version="1", features=["derive"]} diff --git a/rsloglib/src/lib.rs b/rsloglib/src/lib.rs new file mode 100644 index 0000000..87d98de --- /dev/null +++ b/rsloglib/src/lib.rs @@ -0,0 +1,5 @@ +mod slowlog; +mod slowlog_reader; + +pub use slowlog::*; +pub use slowlog_reader::*; \ No newline at end of file diff --git a/src/slowlog.rs b/rsloglib/src/slowlog.rs similarity index 95% rename from src/slowlog.rs rename to rsloglib/src/slowlog.rs index 5e956d9..12101e4 100644 --- a/src/slowlog.rs +++ b/rsloglib/src/slowlog.rs @@ -1,7 +1,7 @@ -use serde::Serialize; +use serde::{Serialize, Deserialize}; -#[derive(Debug, Default, PartialEq, Serialize)] +#[derive(Debug, Default, PartialEq, Serialize, Deserialize)] pub struct SlowlogRecord { pub id: u64, pub time: u64, diff --git a/src/slowlog_reader.rs b/rsloglib/src/slowlog_reader.rs similarity index 79% rename from src/slowlog_reader.rs rename to rsloglib/src/slowlog_reader.rs index 31c4d80..0ceb808 100644 --- a/src/slowlog_reader.rs +++ b/rsloglib/src/slowlog_reader.rs @@ -1,17 +1,39 @@ use crate::slowlog::SlowlogRecord; -use crate::ConnectionProvider; +use std::time::Duration; + +#[derive(Clone)] +pub struct RedisConnectionProvider { + client: redis::Client, + timeout: u64, +} + +impl From<(redis::Client, u64)> for RedisConnectionProvider { + fn from(arg: (redis::Client, u64)) -> RedisConnectionProvider { + RedisConnectionProvider { + client: arg.0, + timeout: arg.1, + } + } +} + +impl RedisConnectionProvider { + pub fn get_connection(&self) -> redis::RedisResult { + self.client + .get_connection_with_timeout(Duration::from_secs(self.timeout)) + } +} pub struct SlowlogReader { - connection_provider: ConnectionProvider, + connection_provider: RedisConnectionProvider, connection: redis::Connection, last_id: i64, length: u32, uptime: u64, } -impl std::convert::TryFrom for SlowlogReader { +impl std::convert::TryFrom for SlowlogReader { type Error = redis::RedisError; - fn try_from(connection_provider: ConnectionProvider) -> Result { + fn try_from(connection_provider: RedisConnectionProvider) -> Result { let sl_reader = SlowlogReader { connection: connection_provider.get_connection()?, connection_provider, diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index beae98c..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,121 +0,0 @@ -use std::thread::sleep; -use std::time::Duration; -mod slowlog; -use slowlog::SlowlogRecord; -mod argument_parsing; -mod slowlog_reader; -use argument_parsing::OutputFormat; -use slowlog_reader::SlowlogReader; -use std::convert::TryFrom; - -#[derive(Clone)] -pub struct ConnectionProvider { - client: redis::Client, - timeout: u64, -} - -impl From<(redis::Client, u64)> for ConnectionProvider { - fn from(arg: (redis::Client, u64)) -> ConnectionProvider { - ConnectionProvider { - client: arg.0, - timeout: arg.1, - } - } -} - -impl ConnectionProvider { - pub fn get_connection(&self) -> redis::RedisResult { - self.client - .get_connection_with_timeout(Duration::from_secs(self.timeout)) - } -} - -fn print_rec(r: &SlowlogRecord, format: &OutputFormat) { - match format { - OutputFormat::Text => { - println!( - "[{}] id: {},\tduration: {},\tclient: {},\tclient_name: {},\tcommand: {:?}", - r.time, r.id, r.duration, r.client_socket, r.client_name, r.command - ) - } - OutputFormat::Json => { - println!("{}", serde_json::to_string(r).unwrap()) - } - } -} - -fn error_handler(e: redis::RedisError) { - match e.kind() { - redis::ErrorKind::IoError => { - log::error!("Can't establish connection to redis cluster: {}", e) - } - _ => unimplemented!("Error not handled: {}({:?})", e, e.kind()), - } -} - -fn create_slowlog_reader(con_provider: ConnectionProvider, interval: u64) -> SlowlogReader { - log::debug!("Creating slowlog reader"); - loop { - match SlowlogReader::try_from(con_provider.clone()) { - Err(e) => error_handler(e), - Ok(slr) => return slr, - } - sleep(Duration::new(interval, 0)) - } -} - -fn read_once(con_provider: ConnectionProvider, config: &argument_parsing::Config) { - match { - move || -> Result<(), redis::RedisError> { - for r in slowlog_reader::get_slowlog(&mut con_provider.get_connection()?, 128)?.iter() { - print_rec(r, &config.output_format) - } - Ok(()) - } - }() { - Err(e) => error_handler(e), - Ok(_) => std::process::exit(0), - } -} - -fn read_continiously(con_provider: ConnectionProvider, config: &argument_parsing::Config) { - let mut sl_reader = create_slowlog_reader(con_provider, config.interval); - - loop { - match sl_reader - .get() - .map_err(|e| sl_reader.redis_error_handler(e)) - { - Ok(records) => { - for r in records.iter().rev() { - print_rec(r, &config.output_format) - } - } - Err(e) => { - if let Err(e) = e { - error_handler(e) - } - } - } - sleep(Duration::new(config.interval, 0)); - } -} - -pub fn main() { - let config = argument_parsing::get_config() - .map_err(|e| e.exit()) - .unwrap(); - stderrlog::new() - .timestamp(stderrlog::Timestamp::Second) - .verbosity(config.verbosity) - .quiet(config.quiet) - .init() - .unwrap(); - let redis_client = redis::Client::open((&config.hostname, config.port)).unwrap(); - let connection_provider = ConnectionProvider::from((redis_client, config.interval)); - if config.follow { - read_continiously(connection_provider, &config) - } else { - read_once(connection_provider, &config) - } -} diff --git a/src/main.rs b/src/main.rs index c4fe307..e5cc09d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,99 @@ +use std::thread::sleep; +use std::time::Duration; +use std::convert::TryFrom; -fn main(){ - rslog::main(); -} \ No newline at end of file +mod argument_parsing; +use argument_parsing::OutputFormat; + +use rsloglib::{SlowlogRecord,SlowlogReader, RedisConnectionProvider}; + + +fn print_rec(r: &SlowlogRecord, format: &OutputFormat) { + match format { + OutputFormat::Text => { + println!( + "[{}] id: {},\tduration: {},\tclient: {},\tclient_name: {},\tcommand: {:?}", + r.time, r.id, r.duration, r.client_socket, r.client_name, r.command + ) + } + OutputFormat::Json => { + println!("{}", serde_json::to_string(r).unwrap()) + } + } +} + +fn error_handler(e: redis::RedisError) { + match e.kind() { + redis::ErrorKind::IoError => { + log::error!("Can't establish connection to redis cluster: {}", e) + } + _ => unimplemented!("Error not handled: {}({:?})", e, e.kind()), + } +} + +fn create_slowlog_reader(con_provider: RedisConnectionProvider, interval: u64) -> SlowlogReader { + log::debug!("Creating slowlog reader"); + loop { + match SlowlogReader::try_from(con_provider.clone()) { + Err(e) => error_handler(e), + Ok(slr) => return slr, + } + sleep(Duration::new(interval, 0)) + } +} + +fn read_once(con_provider: RedisConnectionProvider, config: &argument_parsing::Config) { + match { + move || -> Result<(), redis::RedisError> { + for r in rsloglib::get_slowlog(&mut con_provider.get_connection()?, 128)?.iter() { + print_rec(r, &config.output_format) + } + Ok(()) + } + }() { + Err(e) => error_handler(e), + Ok(_) => std::process::exit(0), + } +} + +fn read_continiously(con_provider: RedisConnectionProvider, config: &argument_parsing::Config) { + let mut sl_reader = create_slowlog_reader(con_provider, config.interval); + + loop { + match sl_reader + .get() + .map_err(|e| sl_reader.redis_error_handler(e)) + { + Ok(records) => { + for r in records.iter().rev() { + print_rec(r, &config.output_format) + } + } + Err(e) => { + if let Err(e) = e { + error_handler(e) + } + } + } + sleep(Duration::new(config.interval, 0)); + } +} + +pub fn main() { + let config = argument_parsing::get_config() + .map_err(|e| e.exit()) + .unwrap(); + stderrlog::new() + .timestamp(stderrlog::Timestamp::Second) + .verbosity(config.verbosity) + .quiet(config.quiet) + .init() + .unwrap(); + let redis_client = redis::Client::open((&config.hostname, config.port)).unwrap(); + let connection_provider = RedisConnectionProvider::from((redis_client, config.interval)); + if config.follow { + read_continiously(connection_provider, &config) + } else { + read_once(connection_provider, &config) + } +}