Python registro con PTB: La misma línea registra dos veces pero sólo añade un manejador

votos
3
  • Python: 3.6.6
  • python-telegrama-bot: 10.0.2

Tengo este problema: He definido un registrador de pitón con un SMTPHandler, un TimedRotatingFileHandler y una StreamHandler.

El StreamHandler funciona bien, pero cuando trato de usarlo desde un controlador de pitón-telegrama-bot, la línea se imprime dos veces en la salida estándar con dos formatos diferentes y no puedo encontrar la manera de evitar una y se lleva otra uno (el cronometrado uno) para permanecer.

He descubierto la causa. Al añadir un ConversationHandler con un CallbackQueryHandler, este mensaje se muestra al iniciar.

WARNING:root:If 'per_message=False', 'CallbackQueryHandler' will not be tracked for every message.

Y entonces la línea de registro no deseado cada vez que aparece.

El código está aquí abajo como log_config.py. He añadido también el código de ejemplo para my_main_file.py pruebas y la salida de corriente como un comentario de varias líneas.

config / log_config.py :

import os

import logging
from logging import Formatter

from datetime import datetime


VERSION_NUM = '1.2.0'
LOG_MSG_FORMAT = '%(asctime)s - ({0}) %(levelname)s - %(name)s - %(message)s'
LOGFILE_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)),
                            'log',
                            'alfred.log')
logging.getLogger('telegram').setLevel(logging.WARNING)
logging.getLogger('chardet.charsetprober').setLevel(logging.WARNING)


def my_timezone_time(*args):
    # I simplified this line, because it's irrelevant
    return datetime.now().timetuple()


handlers = []


#
# ... different handlers added
#


# last handler to add, this one works just as I want

ch = logging.StreamHandler()
formatter = Formatter(LOG_MSG_FORMAT.format(VERSION_NUM))
formatter.converter = my_timezone_time
ch.setFormatter(formatter)
ch.setLevel(logging.INFO)
handlers.append(ch)


def getLogger(name):
    
    Returns a logger for the file. Works fine but when used,
       it always outputs the same line with the last handler 
       and also with an unknown handler not added by me 
       (must be some default instance)
    :param name: the file name
    :return: a logger
    
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)
    for h in handlers:
        logger.addHandler(h)

    return logger

my_main_file.py :

#!/usr/bin/python3
from telegram.ext import (Updater, CommandHandler, ConversationHandler,
                          run_async, CallbackQueryHandler)
from config.log_config import getLogger

# Enable logging
logger = getLogger(__name__)

updater = Updater('......')  # Replace with your bot token

# ************************** HANDLERS
# Define a few command handlers. These usually take the two arguments bot and
# update. Error handlers also receive the raised TelegramError object in error.


@run_async
def show_help(bot, update):
    logger.info('HELP!')


def error_handler(bot, update, error):
    logger.warning('La actualización %s causó el error %s', update, error)


def dumb_handler(bot, update, user_data):
    return ConversationHandler.END


def main():
    Start the bot.
    # Create the EventHandler and pass it your bot's token.
    global updater

    # Get the dispatcher to register handlers
    dp = updater.dispatcher

    # on different commands - answer in Telegram
    dp.add_handler(CommandHandler('help', show_help))

    # Add conversation handler with the states
    # The telegram conversation handler needs a handler_list with functions
    # so it can execute desired code in each state/step

    conv_handler = ConversationHandler(
        entry_points=[CommandHandler('irrelevant', dumb_handler,
                                     pass_user_data=True)
                      ],
        states={
            0: [CallbackQueryHandler(dumb_handler, pass_user_data=True)],
        },
        fallbacks=[],
    )
    dp.add_handler(conv_handler)

    # log all errors
    dp.add_error_handler(error_handler)

    updater.start_polling()
    updater.idle()


if __name__ == '__main__':
    main()


OUTPUT when used /help from the bot chat
(First is my wished output, second is the line I want to avoid)
------

2018-11-08 16:41:51,115 - (1.2.0) INFO - __main__ - HELP!
INFO:__main__:HELP!

Publicado el 07/11/2018 a las 22:44
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
1

telegram.ext.ConversationHandlerincluye varias llamadas de registro que utilizan logging.warningen lugar del self.loggerregistrador que probablemente debería utilizar, como esta llamada :

for handler in all_handlers:
    if isinstance(handler, CallbackQueryHandler):
        logging.warning("If 'per_message=False', 'CallbackQueryHandler' will not be "
                        "tracked for every message.")

logging.warningy las otras funciones de registro de nivel de módulo de conveniencia llaman logging.basicConfig, lo que añade un gestor en el registrador de la raíz si no hay controladores en el registrador de la raíz están presentes. Este controlador es el responsable de los no deseados

INFO:__main__:HELP!

el registro de salida.

El uso de logging.warninglugar de self.logger.warning, probablemente, se debe considerar un error pitón-telegrama-bot. No veo un problema abierto para que en su seguimiento de incidencias , por lo que es posible que desee presentar un informe de error.

En el ínterin, o si los desarrolladores de Python-telegrama-bot deciden el comportamiento está bien, se puede agregar un controlador nulo al registrador de la raíz para evitar basicConfigde añadir su propio controlador. Esto debe hacerse antes de que el ConversationHandlerse crea, anticiparse al basicConfig:

logging.getLogger().addHandler(logging.NullHandler())
Respondida el 08/11/2018 a las 19:16
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more