aboutsummaryrefslogtreecommitdiff
path: root/autogpts/autogpt/autogpt/logs/config.py
blob: 7b8a043b10e7da41d099e099344827309615f0ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
"""Logging module for Auto-GPT."""
from __future__ import annotations

import logging
import sys
from pathlib import Path
from typing import TYPE_CHECKING, Optional

from auto_gpt_plugin_template import AutoGPTPluginTemplate
from openai.util import logger as openai_logger

if TYPE_CHECKING:
    from autogpt.config import Config
    from autogpt.speech import TTSConfig

from autogpt.core.runner.client_lib.logging import BelowLevelFilter

from .formatters import AutoGptFormatter
from .handlers import TTSHandler, TypingConsoleHandler

LOG_DIR = Path(__file__).parent.parent.parent / "logs"
LOG_FILE = "activity.log"
DEBUG_LOG_FILE = "debug.log"
ERROR_LOG_FILE = "error.log"

SIMPLE_LOG_FORMAT = "%(asctime)s %(levelname)s  %(title)s%(message)s"
DEBUG_LOG_FORMAT = (
    "%(asctime)s %(levelname)s %(filename)s:%(lineno)d" "  %(title)s%(message)s"
)

SPEECH_OUTPUT_LOGGER = "VOICE"
USER_FRIENDLY_OUTPUT_LOGGER = "USER_FRIENDLY_OUTPUT"

_chat_plugins: list[AutoGPTPluginTemplate] = []


def configure_logging(
    debug_mode: bool = False,
    plain_output: bool = False,
    tts_config: Optional[TTSConfig] = None,
    log_dir: Path = LOG_DIR,
) -> None:
    """Configure the native logging module."""

    # create log directory if it doesn't exist
    if not log_dir.exists():
        log_dir.mkdir()

    log_level = logging.DEBUG if debug_mode else logging.INFO
    log_format = DEBUG_LOG_FORMAT if debug_mode else SIMPLE_LOG_FORMAT
    console_formatter = AutoGptFormatter(log_format)

    # Console output handlers
    stdout = logging.StreamHandler(stream=sys.stdout)
    stdout.setLevel(log_level)
    stdout.addFilter(BelowLevelFilter(logging.WARNING))
    stdout.setFormatter(console_formatter)
    stderr = logging.StreamHandler()
    stderr.setLevel(logging.WARNING)
    stderr.setFormatter(console_formatter)

    # INFO log file handler
    activity_log_handler = logging.FileHandler(log_dir / LOG_FILE, "a", "utf-8")
    activity_log_handler.setLevel(logging.INFO)
    activity_log_handler.setFormatter(
        AutoGptFormatter(SIMPLE_LOG_FORMAT, no_color=True)
    )

    if debug_mode:
        # DEBUG log file handler
        debug_log_handler = logging.FileHandler(log_dir / DEBUG_LOG_FILE, "a", "utf-8")
        debug_log_handler.setLevel(logging.DEBUG)
        debug_log_handler.setFormatter(
            AutoGptFormatter(DEBUG_LOG_FORMAT, no_color=True)
        )

    # ERROR log file handler
    error_log_handler = logging.FileHandler(log_dir / ERROR_LOG_FILE, "a", "utf-8")
    error_log_handler.setLevel(logging.ERROR)
    error_log_handler.setFormatter(AutoGptFormatter(DEBUG_LOG_FORMAT, no_color=True))

    # Configure the root logger
    logging.basicConfig(
        format=log_format,
        level=log_level,
        handlers=(
            [stdout, stderr, activity_log_handler, error_log_handler]
            + ([debug_log_handler] if debug_mode else [])
        ),
    )

    ## Set up user-friendly loggers

    # Console output handler which simulates typing
    typing_console_handler = TypingConsoleHandler(stream=sys.stdout)
    typing_console_handler.setLevel(logging.INFO)
    typing_console_handler.setFormatter(console_formatter)

    user_friendly_output_logger = logging.getLogger(USER_FRIENDLY_OUTPUT_LOGGER)
    user_friendly_output_logger.setLevel(logging.INFO)
    user_friendly_output_logger.addHandler(
        typing_console_handler if not plain_output else stdout
    )
    if tts_config:
        user_friendly_output_logger.addHandler(TTSHandler(tts_config))
    user_friendly_output_logger.addHandler(activity_log_handler)
    user_friendly_output_logger.addHandler(error_log_handler)
    user_friendly_output_logger.addHandler(stderr)
    user_friendly_output_logger.propagate = False

    speech_output_logger = logging.getLogger(SPEECH_OUTPUT_LOGGER)
    speech_output_logger.setLevel(logging.INFO)
    if tts_config:
        speech_output_logger.addHandler(TTSHandler(tts_config))
    speech_output_logger.propagate = False

    # JSON logger with better formatting
    json_logger = logging.getLogger("JSON_LOGGER")
    json_logger.setLevel(logging.DEBUG)
    json_logger.propagate = False

    # Disable debug logging from OpenAI library
    openai_logger.setLevel(logging.INFO)


def configure_chat_plugins(config: Config) -> None:
    """Configure chat plugins for use by the logging module"""

    logger = logging.getLogger(__name__)

    # Add chat plugins capable of report to logger
    if config.chat_messages_enabled:
        if _chat_plugins:
            _chat_plugins.clear()

        for plugin in config.plugins:
            if hasattr(plugin, "can_handle_report") and plugin.can_handle_report():
                logger.debug(f"Loaded plugin into logger: {plugin.__class__.__name__}")
                _chat_plugins.append(plugin)