AutoGPT: Enhance log readability of autogpt.core

This commit is contained in:
Reinier van der Leer
2023-09-15 13:11:43 +02:00
parent 5074d696cf
commit 9bd13c5897
4 changed files with 89 additions and 43 deletions

View File

@@ -1,7 +1,9 @@
import click
from autogpt.core.agent import AgentSettings, SimpleAgent
from autogpt.core.runner.client_lib.logging import get_client_logger
from autogpt.core.runner.client_lib.logging import (
configure_root_logger, get_client_logger
)
from autogpt.core.runner.client_lib.parser import (
parse_ability_result,
parse_agent_name_and_goals,
@@ -13,6 +15,8 @@ from autogpt.core.runner.client_lib.parser import (
async def run_auto_gpt(user_configuration: dict):
"""Run the Auto-GPT CLI client."""
configure_root_logger()
client_logger = get_client_logger()
client_logger.debug("Getting agent settings")

View File

@@ -1,4 +1,26 @@
import logging
import sys
from colorama import Fore, Style
SIMPLE_LOG_FORMAT = "%(asctime)s %(levelname)s %(message)s"
DEBUG_LOG_FORMAT = (
"%(asctime)s.%(msecs)03d %(levelname)s %(filename)s:%(lineno)d %(message)s"
)
def configure_root_logger():
console_formatter = FancyConsoleFormatter(SIMPLE_LOG_FORMAT)
stdout = logging.StreamHandler(stream=sys.stdout)
stdout.setLevel(logging.DEBUG)
stdout.addFilter(BelowLevelFilter(logging.WARNING))
stdout.setFormatter(console_formatter)
stderr = logging.StreamHandler()
stderr.setLevel(logging.WARNING)
stderr.setFormatter(console_formatter)
logging.basicConfig(level=logging.DEBUG, handlers=[stdout, stderr])
def get_client_logger():
@@ -7,14 +29,59 @@ def get_client_logger():
client_logger = logging.getLogger("autogpt_client_application")
client_logger.setLevel(logging.DEBUG)
formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
client_logger.addHandler(ch)
return client_logger
class FancyConsoleFormatter(logging.Formatter):
"""
A custom logging formatter designed for console output.
This formatter enhances the standard logging output with color coding. The color
coding is based on the level of the log message, making it easier to distinguish
between different types of messages in the console output.
The color for each level is defined in the LEVEL_COLOR_MAP class attribute.
"""
# level -> (level & text color, title color)
LEVEL_COLOR_MAP = {
logging.DEBUG: Fore.LIGHTBLACK_EX,
logging.INFO: Fore.BLUE,
logging.WARNING: Fore.YELLOW,
logging.ERROR: Fore.RED,
logging.CRITICAL: Fore.RED + Style.BRIGHT,
}
def format(self, record: logging.LogRecord) -> str:
# Make sure `msg` is a string
if not hasattr(record, "msg"):
record.msg = ""
elif not type(record.msg) == str:
record.msg = str(record.msg)
# Determine default color based on error level
level_color = ""
if record.levelno in self.LEVEL_COLOR_MAP:
level_color = self.LEVEL_COLOR_MAP[record.levelno]
record.levelname = f"{level_color}{record.levelname}{Style.RESET_ALL}"
# Determine color for message
color = getattr(record, "color", level_color)
color_is_specified = hasattr(record, "color")
# Don't color INFO messages unless the color is explicitly specified.
if color and (record.levelno != logging.INFO or color_is_specified):
record.msg = f"{color}{record.msg}{Style.RESET_ALL}"
return super().format(record)
class BelowLevelFilter(logging.Filter):
"""Filter for logging levels below a certain threshold."""
def __init__(self, below_level: int):
super().__init__()
self.below_level = below_level
def filter(self, record: logging.LogRecord):
return record.levelno < self.below_level

View File

@@ -12,7 +12,8 @@ from openai.util import logger as openai_logger
if TYPE_CHECKING:
from autogpt.config import Config
from .filters import BelowLevelFilter
from autogpt.core.runner.client_lib.logging import BelowLevelFilter
from .formatters import AutoGptFormatter
from .handlers import TTSHandler, TypingConsoleHandler

View File

@@ -1,25 +1,13 @@
import logging
from colorama import Fore, Style
from colorama import Style
from autogpt.core.runner.client_lib.logging import FancyConsoleFormatter
from .utils import remove_color_codes
class AutoGptFormatter(logging.Formatter):
"""
Allows to handle custom placeholders 'title_color' and 'message_no_color'.
To use this formatter, make sure to pass 'color', 'title' as log extras.
"""
# level -> (level & text color, title color)
LEVEL_COLOR_MAP = {
logging.DEBUG: Fore.LIGHTBLACK_EX,
logging.INFO: Fore.BLUE,
logging.WARNING: Fore.YELLOW,
logging.ERROR: Fore.RED,
logging.CRITICAL: Fore.RED + Style.BRIGHT,
}
class AutoGptFormatter(FancyConsoleFormatter):
def format(self, record: logging.LogRecord) -> str:
# Make sure `msg` is a string
if not hasattr(record, "msg"):
@@ -31,26 +19,12 @@ class AutoGptFormatter(logging.Formatter):
if record.msg and not getattr(record, "preserve_color", False):
record.msg = remove_color_codes(record.msg)
# Determine default color based on error level
level_color = ""
if record.levelno in self.LEVEL_COLOR_MAP:
level_color = self.LEVEL_COLOR_MAP[record.levelno]
record.levelname = f"{level_color}{record.levelname}{Style.RESET_ALL}"
# Determine color for message
color = getattr(record, "color", level_color)
color_is_specified = hasattr(record, "color")
# Determine color for title
title = getattr(record, "title", "")
title_color = getattr(record, "title_color", "") or level_color
title_color = getattr(record, "title_color", "") or self.LEVEL_COLOR_MAP.get(record.levelno, "")
if title and title_color:
title = f"{title_color + Style.BRIGHT}{title}{Style.RESET_ALL}"
# Make sure record.title is set, and padded with a space if not empty
record.title = f"{title} " if title else ""
# Don't color INFO messages unless the color is explicitly specified.
if color and (record.levelno != logging.INFO or color_is_specified):
record.msg = f"{color}{record.msg}{Style.RESET_ALL}"
return super().format(record)