Python: Как записать ошибку в консоли в текстовый файл?

#python #python-3.x #python-2.7

#python #python-3.x #python-2.7

Вопрос:

У меня есть скрипт на Python, который каждые 10 минут отправляет мне электронное письмо со всем, что написано в консоли. Я запускаю это с помощью crontab в моем Ubuntu 18.04 vps. Иногда он не отправляет почту, поэтому я предполагаю, что при возникновении ошибки выполнение останавливается, но как я могу записать ошибки в текстовый файл, чтобы я мог проанализировать ошибку?

Комментарии:

1. Запись в файл журнала с помощью пакета logging.

2. Какой код вы используете? Разве вы не можете просто обернуть это в try и сохранить исключение в catch ?

3. logging предпочтительный способ сделать это. Если вы чувствуете себя достаточно дьявольски, вы можете передать объект дескриптора файла в print с file помощью kwarg

Ответ №1:

Модуль протоколирования

Чтобы продемонстрировать подход с logging модулем, это был бы общий подход

 import logging

# Create a logging instance
logger = logging.getLogger('my_application')
logger.setLevel(logging.INFO) # you can set this to be DEBUG, INFO, ERROR

# Assign a file-handler to that instance
fh = logging.FileHandler("file_dir.txt")
fh.setLevel(logging.INFO) # again, you can set this differently

# Format your logs (optional)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter) # This will set the format to the file handler

# Add the handler to your logging instance
logger.addHandler(fh)

try:
    raise ValueError("Some error occurred")
except ValueError as e:
    logger.exception(e) # Will send the errors to the file
  

И если я cat file_dir.txt

 2019-03-14 14:52:50,676 - my_application - ERROR - Some error occurred
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError: Some error occurred
  

Печать в файл

Как я указал в комментариях, вы могли бы также выполнить это с print помощью (я не уверен, что вам за это будут аплодировать)

 # Set your stdout pointer to a file handler
with open('my_errors.txt', 'a') as fh:
    try:
        raise ValueError("Some error occurred")
    except ValueError as e:
        print(e, file=fh)
  

cat my_errors.txt

 Some error occurred
  

Обратите внимание, что в этом случае это logging.exception включает обратную трассировку, что является одним из многих огромных преимуществ этого модуля

Редактировать

В интересах полноты, traceback модуль использует аналогичный подход, как print , где вы можете указать дескриптор файла:

 import traceback
import sys

with open('error.txt', 'a') as fh:
    try:
        raise ValueError("Some error occurred")
    except ValueError as e:
        e_type, e_val, e_tb = sys.exc_info()
        traceback.print_exception(e_type, e_val, e_tb, file=fh)
  

Это будет включать всю информацию, которую вы хотите из logging

Ответ №2:

Вы можете использовать logging модуль, как предложено в комментариях (возможно, улучшенный, но выходящий за рамки моих знаний), или перехватывать ошибки с помощью try и except подобных:

 try:
    pass
    #run the code you currently have
except Exception as e: # catch ALLLLLL errors!!!
    print(e) # or more likely you'd want something like "email_to_me(e)"
  

Хотя обычно не рекомендуется перехватывать все исключения, потому что тогда, если ваша программа завершится сбоем по какой-либо причине, это будет отражено в except предложении, поэтому лучший подход — выяснить, с какой конкретной ошибкой вы сталкиваетесь, например, IndexError , а затем просто перехватить эту конкретную ошибку, например:

 try:
    pass
    #run the code you currently have
except IndexError as e: # catch only indexing errors!!!
    print(e) # or more likely you'd want something like "email_to_me(e)"
  

Комментарии:

1. Большое вам спасибо! На данный момент мне сложно вести журнал, я займусь этим в ближайшем будущем

2. @strangethingspy Нет проблем! Если это решило вашу проблему, обычной практикой является установить флажок возле моего сообщения, чтобы принять его как ответ, который вы искали! Когда вы получите 15 повторений, вы также сможете проголосовать за полезные ответы (и вопросы) 🙂

Ответ №3:

Чтобы иметь возможность отлаживать и не только знать тип произошедшей ошибки, вы также можете получить стек ошибок, используя модуль traceback (обычно в стартовом пакете модулей):

 import traceback
try:
    my_function()
except Exception as e:
    print(e)
    traceback.print_exc()
  

А затем запустите свой код ‘my_code.py ‘ в usig консоли >>

 python my_code.py >> my_prints.txt
  

Затем все распечатки вашего кода будут записаны в этот .txt файл, включая напечатанную ошибку и ее стек. Это очень интересно в вашем случае или при запуске кода в docker, если вы хотите отключиться от него с помощью ctrl p q и при этом знать, что печатается.