se agrega la rotación de log y se actualiza la documentación del proyecto

This commit is contained in:
George committed 2026-08-05 08:30:16 -05:00
1 parent cf2c1ee147
commit 372e6fe7f8
13 files changed
+459 -97

No files matched your search

+50 -28
View File
@@ -2,13 +2,15 @@ import sys
import os
from datetime import datetime, timedelta
# ========================================================================
_stdout_original = sys.stdout
_stderr_original = sys.stderr
_file_stream = None
_log_dir = "logs"
# ============================================================================
class MultiStream:
"""
Clase para redirigir la salida a múltiples flujos (consola y archivo).
"""
def __init__(self, *streams):
self.streams = streams
self.streams = list(streams)
def write(self, data):
for stream in self.streams:
@@ -19,31 +21,51 @@ class MultiStream:
for stream in self.streams:
stream.flush()
# ========================================================================
def reemplazar_file(self, old_fh, new_fh):
for i, s in enumerate(self.streams):
if s is old_fh:
self.streams[i] = new_fh
return
# ============================================================================
def _ruta_log(hoy=None):
if hoy is None:
hoy = datetime.now().strftime("%Y-%m-%d")
if not os.path.exists(_log_dir):
os.makedirs(_log_dir)
return os.path.join(_log_dir, f"{hoy}.log")
# ============================================================================
def setup_logger():
"""
Configura la redirección de stdout y stderr a un archivo de log y a la consola.
Retorna la ruta del archivo de log creado.
"""
log_dir = "logs"
if not os.path.exists(log_dir):
os.makedirs(log_dir)
# Nombre del archivo: YYYY-MM-DD_HH-MM-SS.log
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
log_filename = f"{timestamp}.log"
log_path = os.path.join(log_dir, log_filename)
# Abrir archivo en modo append con encoding utf-8 para soportar iconos
log_file = open(log_path, "a", encoding="utf-8")
# Redirigir stdout y stderr
sys.stdout = MultiStream(sys.stdout, log_file)
sys.stderr = MultiStream(sys.stderr, log_file)
global _file_stream
log_path = _ruta_log()
_file_stream = open(log_path, "a", encoding="utf-8")
sys.stdout = MultiStream(_stdout_original, _file_stream)
sys.stderr = MultiStream(_stderr_original, _file_stream)
return log_path
# ========================================================================
# ============================================================================
def rotar_log():
global _file_stream
hoy = datetime.now().strftime("%Y-%m-%d")
log_path = _ruta_log(hoy)
if _file_stream and os.path.abspath(_file_stream.name) == os.path.abspath(log_path):
return
nuevo_fh = open(log_path, "a", encoding="utf-8")
if isinstance(sys.stdout, MultiStream):
sys.stdout.reemplazar_file(_file_stream, nuevo_fh)
if isinstance(sys.stderr, MultiStream):
sys.stderr.reemplazar_file(_file_stream, nuevo_fh)
try:
_file_stream.close()
except Exception:
pass
_file_stream = nuevo_fh
print(f"📄 Log rotado a: {log_path}")
# ============================================================================
def limpiar_logs_antiguos(dias=7):
"""
Elimina archivos de log con más de 'n' días de antigüedad.
@@ -68,4 +90,4 @@ def limpiar_logs_antiguos(dias=7):
if count > 0:
print(f"🧹 Se eliminaron {count} archivos de log antiguos (más de {dias} días).")
# ========================================================================
# ============================================================================