From f3026f41c9321ab36b1a969ad644be56b175ee85 Mon Sep 17 00:00:00 2001 From: Jacquin Antoine Date: Sun, 10 May 2026 01:32:19 +0200 Subject: [PATCH] =?UTF-8?q?Pr=C3=A9fixer=20les=20logs=20par=20le=20nom=20d?= =?UTF-8?q?u=20fichier=20LAZ=20en=20cours?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajout d'un FilePrefixFilter qui préfixe chaque message avec [basename] quand un fichier est en cours de traitement. Les workers paralleles affichent ainsi clairement quel fichier produit chaque log. Co-Authored-By: Claude Opus 4.6 --- lidar_pipeline/cli.py | 4 ++++ lidar_pipeline/pipeline.py | 31 +++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lidar_pipeline/cli.py b/lidar_pipeline/cli.py index d91c19c..34960d2 100644 --- a/lidar_pipeline/cli.py +++ b/lidar_pipeline/cli.py @@ -125,6 +125,10 @@ Exemples: # Configure logging before any other output setup_logging(verbose=args.verbose, debug=args.debug) + # Add file prefix filter for parallel processing + from .pipeline import _file_filter + logger.addFilter(_file_filter) + logger.info("=" * 60) logger.info("Pipeline LiDAR Archéologique") logger.info("=" * 60) diff --git a/lidar_pipeline/pipeline.py b/lidar_pipeline/pipeline.py index ed7f3a1..c8e6a25 100644 --- a/lidar_pipeline/pipeline.py +++ b/lidar_pipeline/pipeline.py @@ -21,6 +21,24 @@ try: except RuntimeError: pass # Already set (e.g. in tests or when called multiple times) +logger = logging.getLogger("lidar") + + +class FilePrefixFilter(logging.Filter): + """Adds a file prefix to log messages when processing a specific file.""" + def __init__(self): + super().__init__() + self.basename = None + + def filter(self, record): + if self.basename: + record.msg = f"[{self.basename}] {record.msg}" + return True + + +# Module-level filter instance so process_file can set it +_file_filter = FilePrefixFilter() + from .dtm import classify_ground, create_dtm_fast from .visualizations import ( generate_hillshade, generate_slope, generate_aspect, generate_curvature, @@ -33,8 +51,6 @@ from .gpu import gpu_cleanup from .ign import generate_ign_overlay from .rendering import tif_to_png, generate_pdf_report -logger = logging.getLogger("lidar") - # Ordered list of visualization steps. # Each entry: (name, function_or_lambda) @@ -190,6 +206,7 @@ class LidarArchaeoPipeline: def process_file(self, laz_file): """Process a single LAZ file through the full pipeline.""" basename = laz_file.stem + _file_filter.basename = basename t_start = time.time() logger.info("=" * 60) @@ -231,6 +248,7 @@ class LidarArchaeoPipeline: t_total = time.time() - t_start logger.info(f"✓ {basename} terminé en {t_total:.1f}s") logger.debug(f" Détails: classification={t_classif:.1f}s, DTM={t_dtm:.1f}s, PDF={t_pdf:.1f}s") + _file_filter.basename = None return True def process_all(self): @@ -324,12 +342,13 @@ def _process_file_standalone(laz_file_str, input_dir, output_dir, resolution, fo # Configure logging in worker process (spawn doesn't inherit parent config) import logging import sys - logger = logging.getLogger("lidar") - if not logger.handlers: + worker_logger = logging.getLogger("lidar") + if not worker_logger.handlers: handler = logging.StreamHandler(sys.stdout) handler.setFormatter(logging.Formatter("%(message)s")) - logger.setLevel(logging.INFO) - logger.addHandler(handler) + worker_logger.setLevel(logging.INFO) + worker_logger.addHandler(handler) + worker_logger.addFilter(_file_filter) pipeline = LidarArchaeoPipeline(input_dir, output_dir, resolution=resolution, workers=1, force=force) basename = Path(laz_file_str).stem