How add my custom handler to python logging.config.dictConfig()

Viewed 750

I try to add my handler to send errors to telegram. I create my own handler:

#myLogHandlers.py
import logging
from config import config
from pyrogram import Client
from time import time, sleep

logger = logging.getLogger(__name__)


class TelegramHandler(logging.Handler):
    """Loggig handler for sending logs to telegram"""

    def __init__(self, user_id_list: list[int],
                 chat_id_list: list[int]=[-525253371],
                 API_ID=config.API_ID,
                 API_HASH=config.API_HASH,
                 BOT_TOKEN=config.BOT_TOKEN,
                 timeout: int = 10):
        super().__init__()
        self.chat_id_list = chat_id_list
        self.API_ID = API_ID
        self.API_HASH = API_HASH
        self.BOT_TOKEN = BOT_TOKEN
        self.timeout = timeout
        self.appBot = self._get_app()

    def _get_app(self):
        return Client('appBotHandler', api_id=self.API_ID, api_hash=self.API_HASH, bot_token=self.BOT_TOKEN)

    def emit(self, record):
        msg = self.format(record)
        for chat_id in self.chat_id_list:
            t0 = time()
            while time() - t0 < self.timeout:
                try:
                    self.appBot.send_message(chat_id, msg)
                    break
                except Exception as ex:
                    logger.exception("Exception while sending %s to %s:", msg, chat_id)
                    sleep(1)

Then I config logging in main code module:

#serverBot.py
import logging.config

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'default': {
            'format': '{asctime} {levelname} {module}:{funcName}:{lineno} '
                      '{message}',
            'style': '{'
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'default'
        },
        'telegram': {
            (): 'myLogHandlers.TelegramHandler',
            'level': 'ERROR',
            'formatter': 'default'
        }
    },
    'loggers': {
        'serverBot': {
            'handlers': ['telegram', 'console'],
            'level': 'DEBUG',
            'propagate': True
        }
    }
}
logging.config.dictConfig(LOGGING)
logger = logging.getLogger('serverBot')

So I get error:

Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.9/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/logging/config.py", line 564, in configure
    handler = self.configure_handler(handlers[name])
  File "/usr/local/Cellar/python@3.9/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/logging/config.py", line 722, in configure_handler
    klass = self.resolve(cname)
  File "/usr/local/Cellar/python@3.9/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/logging/config.py", line 382, in resolve
    name = s.split('.')
AttributeError: 'NoneType' object has no attribute 'split'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/.../serverBot.py", line 10, in <module>
    logging.config.dictConfig(config.LOGGING)
  File "/usr/local/Cellar/python@3.9/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/logging/config.py", line 809, in dictConfig
    dictConfigClass(config).configure()
  File "/usr/local/Cellar/python@3.9/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/logging/config.py", line 571, in configure
    raise ValueError('Unable to configure handler '
ValueError: Unable to configure handler 'telegram'

Process finished with exit code 1

How can I say to logging.config where my handler is?

1 Answers

You need to follow the documentation more closely. For example, the key for a custom handler is documented as '()' (string), not () (empty tuple). Also, where are you providing the user_id_list that the handler needs in order to be instantiated? Without that, the instantiation would fail, even if it got that far.

Related