Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add csv logging from daemon #432

Merged
merged 7 commits into from
Oct 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@ debug/
target/
.idea/
pkg/


# Auto-generated by autoignore:
# --------------- #
test.csv
# ----------------#
30 changes: 28 additions & 2 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ enum GetType {
},

/// The battery condition in percentage
#[structopt(name = "bat_cond")]
#[structopt(name = "bat-cond")]
BatCond {
#[structopt(short, long)]
raw: bool,
Expand Down Expand Up @@ -186,12 +186,20 @@ enum ACSCommand {
no_animation: bool,

/// Graph
#[structopt(short = "g", long = "--graph")]
#[structopt(short = "g", long = "graph")]
graph_type: Option<String>,

/// Commit hash
#[structopt(short, long)]
commit: bool,

/// Write to a csv file
#[structopt(long = "csv")]
csv_file: Option<String>,

/// Log file size cutoff in MB
#[structopt(long = "log-size-cutoff", default_value = "20")]
log_size_cutoff: i32,
},

/// Monitor each cpu, it's min, max, and current speed, along with the governor
Expand Down Expand Up @@ -220,6 +228,14 @@ enum ACSCommand {
/// Commit hash
#[structopt(short, long)]
commit: bool,

/// Write to a csv file
#[structopt(long = "csv")]
csv_file: Option<String>,

/// Log file size cutoff in MB
#[structopt(long = "log-size-cutoff", default_value = "20")]
log_size_cutoff: i32,
},
}

Expand All @@ -234,6 +250,8 @@ pub fn parse_args(config: config::Config) {
graph: GraphType::Hidden,
commit: false,
testing: false,
csv_file: None,
log_size_cutoff: 20,
};

let int = Interface {
Expand Down Expand Up @@ -280,6 +298,8 @@ pub fn parse_args(config: config::Config) {
no_animation,
graph_type,
commit,
csv_file,
log_size_cutoff,
} => {
if !config_dir_exists() {
warn_user!("Config directory '/etc/acs' does not exist!");
Expand Down Expand Up @@ -315,6 +335,8 @@ pub fn parse_args(config: config::Config) {
graph: parsed_graph_type,
commit,
testing: false,
csv_file,
log_size_cutoff,
};

match daemon_init(settings, config) {
Expand All @@ -333,6 +355,8 @@ pub fn parse_args(config: config::Config) {
graph_type,
hook,
commit,
csv_file,
log_size_cutoff,
} => {
if !config_dir_exists() {
warn_user!("Config directory '/etc/acs' does not exist!");
Expand Down Expand Up @@ -367,6 +391,8 @@ pub fn parse_args(config: config::Config) {
graph: parsed_graph_type,
commit,
testing: false,
csv_file,
log_size_cutoff,
};

match daemon_init(settings, config) {
Expand Down
20 changes: 20 additions & 0 deletions src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::fmt;
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use super::system::{calculate_cpu_percent, read_int, read_str, ProcStat};
use super::Error;
Expand All @@ -23,6 +24,7 @@ pub trait Speed {
fn get_temp(&mut self) -> Result<(), Error>;
fn get_gov(&mut self) -> Result<(), Error>;
fn set_gov(&mut self, gov: String) -> Result<(), Error>;
fn to_csv(&self) -> String;
fn random() -> CPU;
}

Expand Down Expand Up @@ -205,6 +207,24 @@ impl Speed for CPU {
},
}
}

fn to_csv(&self) -> String {
format!(
"{},{},{},{},{},{},{},{},{}\n",
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or(Duration::new(0 as u64, 1 as u32))
.as_secs(),
self.name,
self.number,
self.max_freq,
self.min_freq,
self.cur_freq,
self.cur_temp,
self.cur_usage,
self.gov
)
}
}

impl fmt::Display for CPU {
Expand Down
96 changes: 96 additions & 0 deletions src/daemon.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use crate::power::battery::{has_battery, Battery};
use std::convert::TryInto;
use std::fs::{File, OpenOptions};
use std::io::Write;
use std::path::Path;
use std::sync::{Arc, Mutex};
use std::time::SystemTime;
use std::{thread, time};
Expand Down Expand Up @@ -59,6 +62,7 @@ pub trait Checker {
) -> Result<(), Error>;

fn init(&mut self);
fn setup_csv_logging(&mut self);

fn start_loop(&mut self) -> Result<(), Error>;
fn end_loop(&mut self);
Expand All @@ -69,6 +73,7 @@ pub trait Checker {
fn update_all(&mut self) -> Result<(), Error>;

fn run_state_machine(&mut self) -> State;
fn write_csv(&mut self);

fn preprint_render(&mut self) -> String;
fn postprint_render(&mut self) -> String;
Expand Down Expand Up @@ -184,6 +189,85 @@ impl Checker for Daemon {
state
}

fn write_csv(&mut self) {
let lines = &self.cpus.iter().map(|c| c.to_csv()).collect::<String>();

if let Some(name) = &self.settings.csv_file {
// Open file in append mode
// future additions may keep this file open
let mut file = OpenOptions::new()
.write(true)
.append(true) // This is needed to append to file
.open(name)
.unwrap();

// If file is smaller than log_size_cutoff
if file.metadata().unwrap().len() < (self.settings.log_size_cutoff * 1000_000) as u64 {
// Try to write the cpus
match write!(file, "{}", lines) {
Ok(_) => {}
Err(..) => {
self.logger
.log("Could not write to CSV file.", logger::Severity::Warning);
}
};
} else {
self.logger.log(
&format!(
"Max log file size reached of {}MB",
self.settings.log_size_cutoff
),
logger::Severity::Warning,
);
// Deactivate csv logging after file size max
self.settings.csv_file = None;
}
}
}

fn setup_csv_logging(&mut self) {
// If csv log mode is on
if let Some(name) = &self.settings.csv_file {
// If file does not exist
if !Path::new(name).exists() {
// Try to create file
match File::create(name) {
Ok(a) => {
// Write header and show error if broken
match write!(
&a,
"epoch,name,number,max_freq,min_freq,cur_freq,cur_temp,cur_usage,gov\n"
) {
Ok(_) => {}
Err(..) => {
self.logger
.log("Could not write to CSV file.", logger::Severity::Warning);
}
};
}
// File did not get created
Err(..) => {
self.logger.log(
"Could not create file. Turning csv log mode off and continuing.",
logger::Severity::Warning,
);
// Turn log mode off
self.settings.csv_file = None;
}
}
} else {
// File did exist, use it
self.logger.log(
&format!(
"File \"{}\" already exists, continuing in append mode.",
name
),
logger::Severity::Warning,
);
}
}
}

fn init(&mut self) {
// Get the commit hash from the compile time env variable
if self.settings.commit {
Expand All @@ -192,6 +276,8 @@ impl Checker for Daemon {

self.timeout_battery = time::Duration::from_millis(self.settings.delay_battery);
self.timeout = time::Duration::from_millis(self.settings.delay);

self.setup_csv_logging();
}

fn start_loop(&mut self) -> Result<(), Error> {
Expand All @@ -204,6 +290,8 @@ impl Checker for Daemon {
self.lid_state = read_lid_state()?;
self.usage = calculate_average_usage(&self.cpus) * 100.0;

self.write_csv();

Ok(())
}

Expand Down Expand Up @@ -484,6 +572,8 @@ pub fn daemon_init(settings: Settings, config: Config) -> Result<Arc<Mutex<Daemo
graph: settings.graph,
commit: settings.commit,
testing: settings.testing,
csv_file: settings.csv_file,
log_size_cutoff: settings.log_size_cutoff,
};

// Attempt to create battery object
Expand Down Expand Up @@ -640,6 +730,8 @@ mod tests {
graph: GraphType::Hidden,
commit: false,
testing: true,
csv_file: None,
log_size_cutoff: 20,
};

let config = default_config();
Expand Down Expand Up @@ -668,6 +760,8 @@ mod tests {
graph: GraphType::Hidden,
commit: false,
testing: true,
csv_file: None,
log_size_cutoff: 20,
};

let config = default_config();
Expand Down Expand Up @@ -699,6 +793,8 @@ mod tests {
graph: GraphType::Hidden,
commit: false,
testing: true,
csv_file: None,
log_size_cutoff: 20,
};

let config = default_config();
Expand Down
2 changes: 2 additions & 0 deletions src/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ pub fn interactive() {
graph: GraphType::Hidden,
commit: false,
testing: false,
csv_file: None,
log_size_cutoff: 20,
};

loop {
Expand Down
2 changes: 2 additions & 0 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@ pub struct Settings {
pub graph: GraphType,
pub commit: bool,
pub testing: bool,
pub csv_file: Option<String>,
pub log_size_cutoff: i32,
}