From e64fc88ec68e156d739eb761e305a1d2d790f4e1 Mon Sep 17 00:00:00 2001 From: dongjulim Date: Mon, 7 Oct 2024 18:44:39 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9D=BC=EC=A0=95=20=EC=8B=9C=EA=B0=84?= =?UTF-8?q?=EB=A7=88=EB=8B=A4=20=EC=88=9C=ED=9A=8C=ED=95=98=EA=B2=8C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20&=20message=20=EA=B4=80=EB=A0=A8=20struct?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 39 +++++++++++++++------------ src/metrics/disk.rs | 64 +++++++++++++++++++++++++++++++++++++++++---- src/struct_set.rs | 12 +++++++++ 3 files changed, 93 insertions(+), 22 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2848621..db3cb19 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,10 @@ -use lettre::message::header::ContentType; -use lettre::transport::smtp::authentication::Credentials; -use lettre::{Message, SmtpTransport, Transport}; +use core::time; use ssh::GetSshSession; -use ssh2::Session; -use std::net::TcpStream; +use std::thread; use std::{fs::File, io::Read}; -use struct_set::MailAgent; +use struct_set::{MailAgent, WarningMsg}; -mod metrics{ +mod metrics { pub mod disk; } mod ssh; @@ -21,19 +18,27 @@ fn main() { let mail_agent = MailAgent::new(&config); - for moniter_target in config.target_list { - let session = GetSshSession( - &moniter_target.ip, - &moniter_target.user, - &moniter_target.password, - ).unwrap(); + loop { + let mut warning_vec = Vec::::new(); - metrics::disk::disk_checker(&session); + for moniter_target in &config.target_list { + let session = GetSshSession( + &moniter_target.ip, + &moniter_target.user, + &moniter_target.password, + ) + .unwrap(); - if (false) { + // check and add server issue(warning) + warning_vec = metrics::disk::disk_checker(&session, warning_vec); + } + if !warning_vec.is_empty() { + // warning_vec의 데이터를 모두 가공해서 string화 시켜서 string에 concat 하기 let _ = mail_agent .clone() - .send(moniter_target.ip, "내용".to_string()); + .send("Disk Warnning report".to_string(), "내용".to_string()); } + + thread::sleep(time::Duration::from_secs(60)); } -} \ No newline at end of file +} diff --git a/src/metrics/disk.rs b/src/metrics/disk.rs index 1d03e55..4a7e52b 100644 --- a/src/metrics/disk.rs +++ b/src/metrics/disk.rs @@ -1,12 +1,66 @@ use std::io::Read; +use crate::struct_set::WarningMsg; use ssh2::Session; +use std::str::FromStr; -pub fn disk_checker(sess: &Session) { +#[derive(Debug)] +struct DfResultInfo { + filesystem: String, + size: u64, + used: u64, + available: u64, + use_percentage: String, + mounted_on: String, +} + +impl FromStr for DfResultInfo { + type Err = String; + + fn from_str(line: &str) -> Result { + let parts: Vec<&str> = line.split_whitespace().collect(); + + if parts.len() != 6 { + return Err("Line does not have exactly 6 columns".to_string()); + } + + Ok(DfResultInfo { + filesystem: parts[0].to_string(), + size: parts[1] + .parse() + .map_err(|_| "Invalid size value".to_string())?, + used: parts[2] + .parse() + .map_err(|_| "Invalid used value".to_string())?, + available: parts[3] + .parse() + .map_err(|_| "Invalid available value".to_string())?, + use_percentage: parts[4].to_string(), + mounted_on: parts[5].to_string(), + }) + } +} + +pub fn disk_checker(sess: &Session, warning_vec: Vec) -> Vec { let mut channel = sess.channel_session().unwrap(); channel.exec("df --total | tail -n +2").unwrap(); - let mut result = String::new(); - channel.read_to_string(&mut result).unwrap(); - println!("{}", result); //이제 이걸 가공하면 되는데 - channel.wait_close(); + let mut df_result = String::new(); + channel.read_to_string(&mut df_result).unwrap(); + + let mut df_result_infos: Vec = Vec::new(); + for line in df_result.lines() { + match line.parse::() { + Ok(info) => df_result_infos.push(info), + Err(e) => println!("Failed to parse line: {}, error: {}", line, e), + } + } + + println!("{:?}", df_result_infos); // todo: 이제 이걸 가공하면 되는데 가공해서 일정수치 넘으면 warning_vec 에 넣기 + for df_result_info in df_result_infos { + df_result_info.use_percentage // todo : string percentage 조건을 걸고 삭제 + } + + let _ = channel.wait_close(); + + return warning_vec; } diff --git a/src/struct_set.rs b/src/struct_set.rs index 31cb615..8ba8e5d 100644 --- a/src/struct_set.rs +++ b/src/struct_set.rs @@ -8,6 +8,18 @@ use lettre::Transport; use lettre::{message::header::Subject, transport::smtp::authentication::Credentials}; use serde::{Deserialize, Serialize}; +pub enum WarningType { + DiskFull, + CpuUseageHigh, + MemUseageHigh, +} + +pub(crate) struct WarningMsg { + war_type: WarningType, + target: ServerInfo, + msg: String, +} + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ServerInfo { pub ip: String, -- GitLab