tirkarthi commented on issue #37443:
URL: https://github.com/apache/airflow/issues/37443#issuecomment-2026880213

   I just realized since ansi codes are now converted to html this is already 
possible with a custom log handler. Below is a custom handler to print lines 
with error or exception in bold red. Maybe we can add a default color handler 
to airflow so that users can switch to this if needed from airflow.cfg along 
with add it as a recipe in logs documentation to customize color, style etc. as 
per needs.
   
   Color logs : 
   
   
![image](https://github.com/apache/airflow/assets/3972343/49cd5767-fa3b-4b3f-8193-e47d385e6bc0)
   
   
   ```
   # airflow.cfg changes in logging section
   
   logging_config_class = log_config.LOGGING_CONFIG
   task_log_reader = color_handler
   ```
   
   ```python
   
   # ~/airflow/config/log_config.py
   
   from copy import deepcopy
   import os
   
   from airflow.config_templates.airflow_local_settings import 
DEFAULT_LOGGING_CONFIG
   
   LOGGING_CONFIG = deepcopy(DEFAULT_LOGGING_CONFIG)
   
   
   LOGGING_CONFIG["handlers"]["color_handler"] = {
       'class': "airflow.utils.log.file_task_handler.ColorFileHandler", # 
replace this with correct path
       'formatter': 'airflow',
       'base_log_folder': '/home/karthikeyan/airflow/logs',
       'filters': ['mask_secrets']
   }
   
   
   LOGGING_CONFIG["loggers"]["airflow.task"]["handlers"] = ["task", 
"color_handler"]
   ```
   
   ```python
   class ColorFileHandler(FileTaskHandler):
   
       ERROR_KEYWORDS = ["error", "exception"]
   
       def _read(self,
                 ti: TaskInstance,
                 try_number: int,
                 metadata: dict[str, Any] | None = None):
   
           import colorama
   
           log, metadata = super()._read(ti, try_number, metadata)
           processed_lines = []
   
           for line in log.splitlines():
               if any(keyword in line.lower() for keyword in 
self.ERROR_KEYWORDS):
                   if line.startswith("["):
                       timestamp, level, msg = line.split(maxsplit=2)
                       processed_lines.append(f'{timestamp} {level} 
{colorama.Style.BRIGHT}{colorama.Fore.RED}{msg}{colorama.Fore.RESET}{colorama.Style.RESET_ALL}')
                   else:
                       
processed_lines.append(f'{colorama.Style.BRIGHT}{colorama.Fore.RED}{line}{colorama.Fore.RESET}{colorama.Style.RESET_ALL}')
               else:
                   processed_lines.append(line)
   
           return "\n".join(processed_lines), metadata
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to