nouvelle version

This commit is contained in:
oussi
2026-04-13 16:03:08 +02:00
parent eb62e74f08
commit ddfa84cfea
4874 changed files with 13731 additions and 28 deletions

View File

@@ -10,7 +10,7 @@ use axum::{
http::request::Parts,
response::{IntoResponse, Redirect, Response},
};
use std::sync::{Arc, RwLock};
use std::sync::Arc;
use tera::Tera;
use tokio::sync::Mutex as AsyncMutex;
use tower_sessions::Session;

View File

@@ -1,9 +1,11 @@
use axum::{
body::Bytes,
extract::{Form, State},
response::{IntoResponse, Redirect},
};
use serde::Deserialize;
use tower_sessions::Session;
use form_urlencoded;
use crate::routes::{flash, get_and_clear_flash, render_html, AppState, AuthUser};
@@ -179,32 +181,30 @@ pub async fn test_smtp(
Redirect::to("/settings")
}
#[derive(Deserialize)]
pub struct ProcessesForm {
#[serde(rename = "proc_name[]")]
pub proc_name: Option<Vec<String>>,
#[serde(rename = "proc_pattern[]")]
pub proc_pattern: Option<Vec<String>>,
#[serde(rename = "proc_mem_threshold[]")]
pub proc_mem_threshold: Option<Vec<String>>,
#[serde(rename = "proc_enabled[]")]
pub proc_enabled: Option<Vec<String>>,
#[serde(rename = "proc_alert_down[]")]
pub proc_alert_down: Option<Vec<String>>,
}
pub async fn update_processes(
_auth: AuthUser,
session: Session,
State(state): State<AppState>,
Form(form): Form<ProcessesForm>,
body: Bytes,
) -> impl IntoResponse {
use crate::config::ProcessConfig;
let names = form.proc_name.unwrap_or_default();
let patterns = form.proc_pattern.unwrap_or_default();
let mem_thresholds = form.proc_mem_threshold.unwrap_or_default();
let enableds = form.proc_enabled.unwrap_or_default();
let alert_downs = form.proc_alert_down.unwrap_or_default();
let mut names: Vec<String> = Vec::new();
let mut patterns: Vec<String> = Vec::new();
let mut mem_thresholds: Vec<String> = Vec::new();
let mut enableds: Vec<String> = Vec::new();
let mut alert_downs: Vec<String> = Vec::new();
for (key, value) in form_urlencoded::parse(body.as_ref()) {
match key.as_ref() {
"proc_name[]" => names.push(value.into_owned()),
"proc_pattern[]" => patterns.push(value.into_owned()),
"proc_mem_threshold[]" => mem_thresholds.push(value.into_owned()),
"proc_enabled[]" => enableds.push(value.into_owned()),
"proc_alert_down[]" => alert_downs.push(value.into_owned()),
_ => {}
}
}
let mut processes = Vec::new();
for (i, name) in names.iter().enumerate() {

View File

@@ -1,8 +1,10 @@
use chrono::{Duration, Local, NaiveDateTime, Timelike};
use flate2::read::GzDecoder;
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::fs;
use std::io::Read;
use std::path::Path;
use std::sync::{Arc, Mutex};
use tokio::sync::Mutex as AsyncMutex;
@@ -35,14 +37,58 @@ pub struct UserData {
pub no_files: bool,
}
fn read_log_file(path: &std::path::PathBuf) -> Option<String> {
if path.to_string_lossy().ends_with(".gz") {
let file = fs::File::open(path).ok()?;
let mut decoder = GzDecoder::new(file);
let mut content = String::new();
decoder.read_to_string(&mut content).ok()?;
Some(content)
} else {
fs::read_to_string(path).ok()
}
}
fn log_files_for_date(log_path: &Path, prefix: &str, date_str: &str) -> Vec<std::path::PathBuf> {
let pattern = format!("{}/{}_{}_*", log_path.to_string_lossy(), prefix, date_str);
let re = Regex::new(r"_(\d+)\.[^.]+$").unwrap();
let mut files: Vec<_> = glob::glob(&pattern)
let re = Regex::new(r"_(\d+)\.log(\.gz)?$").unwrap();
// Essai 1 : fichiers avec la date dans le nom (ex: awevents_26-04-13_1.log)
let pattern_with_date = format!("{}/{}_{}_*", log_path.to_string_lossy(), prefix, date_str);
let mut files: Vec<_> = glob::glob(&pattern_with_date)
.unwrap_or_else(|_| glob::glob("__nonexistent__").unwrap())
.filter_map(|f| f.ok())
.filter(|f| !f.to_string_lossy().ends_with(".zip"))
.filter(|f| {
let s = f.to_string_lossy();
!s.ends_with(".zip") && (s.ends_with(".log") || s.ends_with(".log.gz"))
})
.collect();
// Essai 2 : si aucun fichier trouvé, chercher sans date dans le nom
// et filtrer par date de modification (ex: serveur HDS)
if files.is_empty() {
if let Ok(target_date) = chrono::NaiveDate::parse_from_str(date_str, "%y-%m-%d") {
let pattern_no_date = format!("{}/{}_*", log_path.to_string_lossy(), prefix);
files = glob::glob(&pattern_no_date)
.unwrap_or_else(|_| glob::glob("__nonexistent__").unwrap())
.filter_map(|f| f.ok())
.filter(|f| {
let s = f.to_string_lossy();
!s.ends_with(".zip") && (s.ends_with(".log") || s.ends_with(".log.gz"))
})
.filter(|f| {
f.metadata()
.and_then(|m| m.modified())
.ok()
.map(|modified| {
let dt: chrono::DateTime<chrono::Local> = modified.into();
dt.date_naive() == target_date
})
.unwrap_or(false)
})
.collect();
}
}
files.sort_by_key(|f| {
re.captures(&f.to_string_lossy())
.and_then(|c| c.get(1))
@@ -189,7 +235,7 @@ impl UserMonitor {
(0..24).map(|h| (h, HashSet::new())).collect();
for file in &awevents_files {
if let Ok(content) = fs::read_to_string(file) {
if let Some(content) = read_log_file(&file) {
for line in content.lines() {
parse_awevents_line(line, &mut users, cutoff_24h, &mut hourly);
}
@@ -201,7 +247,7 @@ impl UserMonitor {
)
.unwrap();
for file in log_files_for_date(log_dir, "isoft", &date_str) {
if let Ok(content) = fs::read_to_string(file) {
if let Some(content) = read_log_file(&file) {
for line in content.lines() {
if let Some(m) = re_isoft.captures(line) {
let login = m[2].to_string();
@@ -277,7 +323,7 @@ impl UserMonitor {
let mut hourly: HashMap<u32, HashSet<String>> =
(0..24u32).map(|h| (h, HashSet::new())).collect();
for file in &files {
if let Ok(content) = fs::read_to_string(file) {
if let Some(content) = read_log_file(&file) {
for line in content.lines() {
if let Some(m) = re.captures(line) {
let hour: u32 = m[2].parse().unwrap_or(0);