Как выводить в консоль сообщения о действиях бота с понятным интерфейсом?
Имеется следующий код. Как можно настроить telebot.logger,, чтобы вывод был максимально простым?
import logging
logger = telebot.logger
telebot.logger.setLevel(logging.DEBUG)
И.. Чтобы получилось примерно следующее
User: Как я могу получить список команд?
Bot: Используйте /Help
User: Благодарю.
Ответы (2 шт):
попробуйте, возможно это натолкнёт Вас на своё дополнение
def log(message):
print("<!------!>")
print(datetime.now())
print("Сообщение от {0} {1} (id = {2}) \n {3}".format(message.from_user.first_name,
message.from_user.last_name,
str(message.from_user.id), message.text))
вызывайте данную функцию в том месте где требуется лог, например:
@bot.message_handlercommands=['start'])
def cmd_create(message):
send = bot.send_message(message.chat.id, 'Введи название задачи')
bot.register_next_step_handler(send, create)
log(message)
в консоли будет что-то вроде этого:
2020-04-23 14:18:13.696639
Сообщение от %Fname% %Lname% (id = %ID%)
/start
Это заблуждение. Для того чтобы понять в чём оно состоит нужно разобраться с принципом работы встроенной библиотеки logger.
Ваш код (код приведённый в инструкции к telebot):
logger = telebot.logger
telebot.logger.setLevel(logging.DEBUG)
получает объект logger пакета. В нём реализовано не то что вам нужно и повлиять на это нет возможности. Этот логгер для разработчиков самого пакета pythontelegrambotapi.
Вам нужно создать собственный логгер и наполнить его нужным вам функционалом. Упрощённый пример:
import telebot
import sys, logging
TOKEN = '123:qwe'
bot = telebot.TeleBot(TOKEN)
# Здесь настраиваем логгер только для вывода в консоль.
# Получаем логгер по имени файла
log = logging.getLogger(__name__)
# Устанавливаем уровень логирования
# По умолчанию логгер имеет уровень WARNING. У нас сообщения другого уровня,
# поэтому понижаем до INFO
# Подробнее про уровни тут https://docs.python.org/3/library/logging.html#logging-levels
log.setLevel(logging.INFO)
# Назначаем вывод в консоль (Должно работать по умолчанию, но у меня надо добавлять)
log.addHandler(logging.StreamHandler(stream=sys.stdout))
# Будет работать как обычный print(), но сообщения уровня INFO
# можно отключать при назначении уровня WARNING
# Далее нам надо все получаемые сообщения скармливать логгеру
def listener(messages: list[telebot.types.Message]):
'Функция получает все обновления бота и логирует сообщения'
for m in messages:
log.info(f'{m.from_user.full_name}: {m.text}') # логируем сообщение в нужном формате
bot.set_update_listener(listener) # зарегистрировать функцию
# Для записи сообщений от бота используйте в нужном месте
@bot.message_handler(commands=['start'])
def start(m: telebot.types.Message):
answer = 'Используйте /Help'
bot_message = bot.send_message(m.chat.id, answer)
log.info(f'Bot: {answer}')
if __name__ == '__main__':
# Это сообщение будет выводиться даже если оставим значение уровня
# логирования по умолчанию (WARNING)
log.warning('Бот запущен')
bot.infinity_polling()
Вывод:
Бот запущен
User: /start
Bot: Используйте /Help
Более того, нужно разделить ведение журнала по разным пользователям, иначе у вас получится каша из сообщений из разных чатов. Такие журналы записывать в разные файлы. И настроим формат вывода с указанием времени.
Вот более сложный пример:
import telebot
import os, sys, logging
TOKEN = '123:qwe'
bot = telebot.TeleBot(TOKEN)
LOG_PATH = 'userdata/logs/'
if not os.path.exists(LOG_PATH): os.makedirs(LOG_PATH)
def get_chat_logger(m: telebot.types.Message):
'Функция возвращает logger для ведения журнала'
chat_log_fname = os.path.join(LOG_PATH, 'f{m.chat.title}_messages')
# Получаем логгер для конкретного чата.
logger = logging.getLogger(str(m.chat.id))
# По умолчанию этот логгер будет выводить сообщения в консоль
# Если мы хотим сохранять их в файл, то нужно добавить обработчики
# Причём, если мы хотим чтобы вывод выл и в фал и на экран, то
# Нужно два обработчика
if not logger.handlers: # Проверяем, чтобы не добавлять обработчики повторно
# По умолчанию логгер имеет уровень WARNING. У нас сообщения
# другого уровня, поэтому понижаем до INFO
logger.setLevel(logging.INFO)
fh = logging.FileHandler(chat_log_fname, encoding='utf-8')
# У обработчиков тоже нужно установить уровень.
# Так можно контролировать куда что выводить.
fh.setLevel(logging.INFO)
# Форматтер указывает что должны содержать указанные строки. Просто добавим веремя.
# Вы можете использовать атрибуты из документации
# https://docs.python.org/3/library/logging.html#logrecord-attributes
formatter = logging.Formatter('[%(asctime)s] %(message)s', datefmt='%Y.%m.%d %H:%M:%S')
fh.setFormatter(formatter)
# Повторим тоже самое для вывода в консоль
sh = logging.StreamHandler(stream=sys.stdout)
sh.setFormatter(formatter)
# Назначим обработчики
logger.addHandler(sh)
logger.addHandler(fh)
return logger
# Далее нам надо все получаемые сообщения скармливать логгеру
def listener(messages: list[telebot.types.Message]):
'Функция получает все обновления бота и логирует сообщения'
for m in messages:
log = get_chat_logger(m) # Получаем логгер для чата
log.info(f'{m.from_user.full_name}: {m.text}') # логируем сообщение в нужном формате
bot.set_update_listener(listener) # зарегистрировать функцию
# Для записи сообщений от бота используйте в нужном месте
@bot.message_handler(commands=['start'])
def start(m: telebot.types.Message):
answer = 'Используйте /Help'
bot_message = bot.send_message(m.chat.id, answer)
get_chat_logger(m).info(f'{bot.get_me().full_name}: {answer}')
if __name__ == '__main__':
# Здесь создадим ещё один логгер только для вывода в консоль.
# Можно было использовать обычный print(), но для примера
log = logging.getLogger(__name__)
log.addHandler(logging.StreamHandler(stream=sys.stdout))
log.warning('Бот запущен')
bot.infinity_polling()
Подробнее про уровни логгера.
