added logger

LOG_LEVEL env var is now supported
This commit is contained in:
Niklas Kapelle 2025-04-26 18:54:46 +02:00
parent e77ee9c8a3
commit 6496f671d9
Signed by: niklas
GPG Key ID: 4EB651B36D841D16
6 changed files with 88 additions and 16 deletions

33
Cargo.lock generated
View File

@ -395,12 +395,14 @@ version = "0.1.0"
dependencies = [
"chrono",
"gpio",
"log",
"regex",
"rocket",
"rppal",
"rust-embed",
"serde",
"serde_json",
"simplelog",
"tokio",
]
@ -786,6 +788,15 @@ dependencies = [
"libc",
]
[[package]]
name = "num_threads"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
dependencies = [
"libc",
]
[[package]]
name = "object"
version = "0.36.7"
@ -1278,6 +1289,17 @@ dependencies = [
"libc",
]
[[package]]
name = "simplelog"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0"
dependencies = [
"log",
"termcolor",
"time",
]
[[package]]
name = "slab"
version = "0.4.9"
@ -1351,6 +1373,15 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]]
name = "thread_local"
version = "1.1.8"
@ -1369,7 +1400,9 @@ checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
dependencies = [
"deranged",
"itoa",
"libc",
"num-conv",
"num_threads",
"powerfmt",
"serde",
"time-core",

View File

@ -13,6 +13,8 @@ serde_json = "1.0.140"
rocket = "0.5.1"
tokio = { version = "1.44.2", features = ["full"] }
rust-embed = "8.7.0"
log = "0.4.27"
simplelog = "0.12.2"
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
linker = "arm-linux-gnueabihf-gcc"

View File

@ -1,13 +1,21 @@
use log::info;
use serde::{Deserialize, Serialize};
use std::{
collections::{HashMap, HashSet},
error::Error,
fmt::Display,
fs,
};
#[derive(PartialEq, Eq, Deserialize, Serialize, Hash, Clone, PartialOrd, Ord)]
pub struct TallyID(pub String);
impl Display for TallyID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Deserialize, Serialize)]
pub struct AttendanceDay {
date: String,
@ -106,6 +114,7 @@ impl AttendanceDay {
if self.ids.contains(&id) {
return;
}
info!("Adding id: {}", id);
self.ids.push(id);
}
}

View File

@ -1,8 +1,9 @@
use std::sync::Arc;
use id_store::IDStore;
use log::{LevelFilter, error, info, warn};
use pm3::{pm3_mock, run_pm3};
use tokio::sync::{mpsc, Mutex};
use simplelog::{ConfigBuilder, SimpleLogger};
use std::{env, sync::Arc};
use tokio::sync::{Mutex, mpsc};
use webserver::start_webserver;
mod id_store;
@ -10,17 +11,40 @@ mod parser;
mod pm3;
mod webserver;
fn setup_logger() {
let log_level = env::var("LOG_LEVEL")
.ok()
.and_then(|level| level.parse::<LevelFilter>().ok())
.unwrap_or({
if cfg!(debug_assertions) {
LevelFilter::Debug
} else {
LevelFilter::Warn
}
});
let config = ConfigBuilder::new()
.set_target_level(LevelFilter::Error)
.build();
let _ = SimpleLogger::init(log_level, config);
}
#[tokio::main]
async fn main() {
setup_logger();
info!("Starting application");
let (tx, mut rx) = mpsc::channel::<String>(1);
tokio::spawn(async move {
match run_pm3(tx).await {
Ok(()) => {
println!("PM3 exited with an zero error code");
warn!("PM3 exited with a zero exit code");
}
Err(e) => {
println!("PM3 failed to run: {}", e);
error!("Failed to run PM3: {}", e);
}
}
});
@ -37,7 +61,7 @@ async fn main() {
match start_webserver(store.clone()).await {
Ok(()) => {}
Err(e) => {
eprintln!("Failed to start webserver: {}", e);
error!("Failed to start webserver: {}", e);
}
}
}

View File

@ -1,18 +1,18 @@
use log::{debug, error, info};
use std::env;
use std::error::Error;
use std::io::{self, BufRead};
use std::process::{Command, Stdio};
use tokio::time::{Duration, sleep};
use tokio::sync::mpsc;
use tokio::time::{Duration, sleep};
pub async fn run_pm3(tx: mpsc::Sender<String>) -> Result<(), Box<dyn Error>> {
let pm3_path = match env::var("PM3_BIN") {
Ok(path) => path,
Err(_) => {
println!("PM3_BIN not set. Using default value");
info!("PM3_BIN not set. Using default value");
"pm3".to_owned()
},
}
};
let mut cmd = Command::new("stdbuf")
@ -29,18 +29,20 @@ pub async fn run_pm3(tx: mpsc::Sender<String>) -> Result<(), Box<dyn Error>> {
for line_result in reader.lines() {
match line_result {
Ok(line) => {
debug!("PM3: {}", line);
let parse_result = super::parser::parse_line(&line);
if let Some(uid) = parse_result {
debug!("Read ID: {}", uid);
match tx.send(uid).await {
Ok(()) => {}
Err(e) => {
eprintln!("Failed to send to channel: {}", e);
error!("Failed to send to channel: {}", e);
}
}
}
}
Err(e) => {
eprintln!("{}", e);
error!("Failed to read line from PM3: {}", e);
}
}
}
@ -50,7 +52,7 @@ pub async fn run_pm3(tx: mpsc::Sender<String>) -> Result<(), Box<dyn Error>> {
if status.success() {
Ok(())
} else {
Err("pm3 had non zero exit code".into())
Err("PM3 exited with a non zero exit code".into())
}
}
@ -60,7 +62,7 @@ pub async fn pm3_mock(tx: mpsc::Sender<String>) -> Result<(), Box<dyn Error>> {
match tx.send("F1409618".to_owned()).await {
Ok(()) => {}
Err(e) => {
eprintln!("Failed to send to channel: {}", e);
error!("Failed to send to channel: {}", e);
}
}

View File

@ -1,3 +1,4 @@
use log::{error, info};
use rocket::http::Status;
use rocket::{Config, State};
use rocket::{get, http::ContentType, response::content::RawHtml, routes};
@ -49,10 +50,11 @@ fn static_files(file: std::path::PathBuf) -> Option<(ContentType, Vec<u8>)> {
#[get("/api/csv")]
async fn export_csv(manager: &State<Arc<Mutex<IDStore>>>) -> Result<String, Status> {
info!("Exporting CSV");
match manager.lock().await.export_csv() {
Ok(csv) => Ok(csv),
Err(e) => {
eprintln!("Failed to generate csv: {}", e);
error!("Failed to generate csv: {}", e);
Err(Status::InternalServerError)
}
}