Résolution de bugs
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
"""Suivi des utilisateurs connectes a Amadea via parsing des logs."""
|
"""Suivi des utilisateurs connectes a Amadea via parsing des logs."""
|
||||||
|
|
||||||
|
import gzip
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@@ -16,11 +17,57 @@ _ISOFT_LOGIN_RE = re.compile(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _read_log_file(filepath):
|
||||||
|
"""Lit un fichier log, supporte .log et .log.gz."""
|
||||||
|
try:
|
||||||
|
if filepath.endswith('.gz'):
|
||||||
|
with gzip.open(filepath, 'rt', encoding='utf-8', errors='ignore') as f:
|
||||||
|
return f.read()
|
||||||
|
else:
|
||||||
|
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
return f.read()
|
||||||
|
except (PermissionError, OSError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _log_files_for_date(log_path, prefix, date_str):
|
def _log_files_for_date(log_path, prefix, date_str):
|
||||||
"""Retourne les fichiers de logs pour un prefixe et une date donnes, tries par index."""
|
"""Retourne les fichiers de logs pour un prefixe et une date donnes, tries par index.
|
||||||
|
|
||||||
|
Essai 1 : fichiers avec la date dans le nom (ex: awevents_26-04-13_1.log).
|
||||||
|
Essai 2 : si aucun fichier trouve, cherche sans date dans le nom et filtre
|
||||||
|
par date de modification du fichier (ex: serveur HDS).
|
||||||
|
"""
|
||||||
|
def is_valid(f):
|
||||||
|
return f.endswith('.log') or f.endswith('.log.gz')
|
||||||
|
|
||||||
|
def sort_key(f):
|
||||||
|
m = re.search(r'_(\d+)\.log(\.gz)?$', f)
|
||||||
|
return int(m.group(1)) if m else 0
|
||||||
|
|
||||||
|
# Essai 1 : date dans le nom
|
||||||
pattern = os.path.join(log_path, f"{prefix}_{date_str}_*")
|
pattern = os.path.join(log_path, f"{prefix}_{date_str}_*")
|
||||||
files = [f for f in glob.glob(pattern) if not f.endswith('.zip')]
|
files = [f for f in glob.glob(pattern) if is_valid(f)]
|
||||||
return sorted(files, key=lambda f: int(re.search(r'_(\d+)\.[^.]+$', f).group(1)))
|
if files:
|
||||||
|
return sorted(files, key=sort_key)
|
||||||
|
|
||||||
|
# Essai 2 : sans date dans le nom, filtrer par date de modification
|
||||||
|
try:
|
||||||
|
target_date = datetime.strptime(date_str, "%y-%m-%d").date()
|
||||||
|
except ValueError:
|
||||||
|
return []
|
||||||
|
|
||||||
|
fallback_pattern = os.path.join(log_path, f"{prefix}_*")
|
||||||
|
files = []
|
||||||
|
for f in glob.glob(fallback_pattern):
|
||||||
|
if not is_valid(f):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
mtime = os.path.getmtime(f)
|
||||||
|
if datetime.fromtimestamp(mtime).date() == target_date:
|
||||||
|
files.append(f)
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
return sorted(files, key=sort_key)
|
||||||
|
|
||||||
|
|
||||||
class UserMonitor:
|
class UserMonitor:
|
||||||
@@ -90,21 +137,17 @@ class UserMonitor:
|
|||||||
hourly = {h: set() for h in range(24)}
|
hourly = {h: set() for h in range(24)}
|
||||||
|
|
||||||
for filepath in awevents_files:
|
for filepath in awevents_files:
|
||||||
try:
|
content = _read_log_file(filepath)
|
||||||
with open(filepath, "r", encoding="utf-8", errors="ignore") as f:
|
if content:
|
||||||
for line in f:
|
for line in content.splitlines():
|
||||||
self._parse_awevents_line(line, users, cutoff_24h, hourly)
|
self._parse_awevents_line(line, users, cutoff_24h, hourly)
|
||||||
except (PermissionError, OSError):
|
|
||||||
continue
|
|
||||||
|
|
||||||
isoft_files = _log_files_for_date(log_path, "isoft", date_str)
|
isoft_files = _log_files_for_date(log_path, "isoft", date_str)
|
||||||
for filepath in isoft_files:
|
for filepath in isoft_files:
|
||||||
try:
|
content = _read_log_file(filepath)
|
||||||
with open(filepath, "r", encoding="utf-8", errors="ignore") as f:
|
if content:
|
||||||
for line in f:
|
for line in content.splitlines():
|
||||||
self._parse_isoft_line(line, users)
|
self._parse_isoft_line(line, users)
|
||||||
except (PermissionError, OSError):
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._compute_statuses(users, thresholds, now)
|
self._compute_statuses(users, thresholds, now)
|
||||||
|
|
||||||
@@ -213,9 +256,10 @@ class UserMonitor:
|
|||||||
continue
|
continue
|
||||||
hourly = {h: set() for h in range(24)}
|
hourly = {h: set() for h in range(24)}
|
||||||
for filepath in files:
|
for filepath in files:
|
||||||
try:
|
content = _read_log_file(filepath)
|
||||||
with open(filepath, "r", encoding="utf-8", errors="ignore") as f:
|
if not content:
|
||||||
for line in f:
|
continue
|
||||||
|
for line in content.splitlines():
|
||||||
m = re.match(
|
m = re.match(
|
||||||
r'^(\d{4}-\d{2}-\d{2} (\d{2}):\d{2}:\d{2}).*login=([^,]+),',
|
r'^(\d{4}-\d{2}-\d{2} (\d{2}):\d{2}:\d{2}).*login=([^,]+),',
|
||||||
line
|
line
|
||||||
@@ -225,8 +269,6 @@ class UserMonitor:
|
|||||||
login = m.group(3).strip()
|
login = m.group(3).strip()
|
||||||
if login:
|
if login:
|
||||||
hourly[hour].add(login)
|
hourly[hour].add(login)
|
||||||
except (PermissionError, OSError):
|
|
||||||
continue
|
|
||||||
max_concurrent = max((len(v) for v in hourly.values()), default=0)
|
max_concurrent = max((len(v) for v in hourly.values()), default=0)
|
||||||
result.append({"date": day.isoformat(), "count": max_concurrent})
|
result.append({"date": day.isoformat(), "count": max_concurrent})
|
||||||
return result
|
return result
|
||||||
|
|||||||
Reference in New Issue
Block a user