Настройка ведения журнала для скрипта или интерактивного сеанса в Python - PullRequest
0 голосов
/ 04 декабря 2018

Я хочу иметь возможность входить из записных книжек jupyter в stderr, не записывая никакой информации о входе в саму записную книжку jupyter, и я хочу иметь возможность войти в файл при запуске сценария.

По умолчанию,в блокноте jupyter ведение журнала установлено на предупреждение, поэтому мне нужно изменить его, чтобы оно представляло собой информацию для code.py.

У меня есть некоторый код в модуле:

code.py

import logging
logger = logging.getLogger()

handler = logging.StreamHandler(sys.stderr)
if logger.level == 30:
    logger.setLevel(logging.INFO)
logger.handlers = [handler] + logger.handlers

def do_something_cool():
        logger.info("You are cool")

ВБлокнот jupyter это apperas так, как я хочу.

Когда я использую эту функцию из скрипта, я делаю следующее:

my_script.py
if __name__ == '__main__':
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    handler = logging.FileHandler(str(DIRECTORY / 'log_model_info.log'))
    logger.addHandler(handler)

Это выглядит как хак для меня, что я делаю в code.py Есть ли лучший способ справиться с этим?

1 Ответ

0 голосов
/ 04 декабря 2018

Согласно Основное руководство по ведению журналов - документация по Python 2.7.15 , вы настраиваете протоколирование либо с помощью logging.basicConfig(), например:

logging.basicConfig(stream=sys.stderr, level=logging.INFO)   # stream=sys.stderr is the default,
                                                             # so you can omit it

или,в файл:

logging.basicConfig(filename='log_model_info.log', level=logging.INFO)        

или путем добавления обработчиков, настройки уровней, настройки форматов и т. д. вручную с помощью других logging API - logger.addHandler(), logger.setLevel() и т. д.


Для вашего конкретного случая достаточно basicConfig(): использовать stream для интерактивной консоли (или вообще опустить его, поскольку stream=sys.stderr является значением по умолчанию) и filenameдля сценария, как показано в примерах ниже.В обоих случаях вам нужно настроить уровень как минимум на INFO, потому что по умолчанию для корневого регистратора является WARN.

Также нет необходимости получать объект Logger, если вы будете использовать только корневой регистратор -используйте функции ведения журнала на уровне модуля.

Итак, ваш первый код станет:

import logging
logging.basicConfig(level=logging.INFO)

def do_something_cool():
    logging.info("You are cool")

, а второй:

import logging
logging.basicConfig(filename='log_model_info.log', level=logging.INFO)

Вот и мойтипичный код настройки ведения журналов для сценариев, оставленных без присмотра, - чтобы вы могли понять, как выглядит пользовательский код установки logging:

# set up logging #####################################
import sys,logging,logging.handlers,os.path
#place log alongside the script
log_file=os.path.splitext(__file__)[0]+".log"
l = logging.getLogger()
l.setLevel(logging.INFO)
f = logging.Formatter('%(asctime)s %(process)d:%(thread)d %(name)s %(levelname)-8s %(message)s')
h=logging.StreamHandler(sys.stdout)
h.setLevel(logging.NOTSET)
h.setFormatter(f)
l.addHandler(h)
h=logging.handlers.RotatingFileHandler(log_file,maxBytes=1024**2,backupCount=1)
h.setLevel(logging.NOTSET)
h.setFormatter(f)
l.addHandler(h)
del h,f
#hook to log unhandled exceptions
def excepthook(type,value,traceback):
    logging.error("Unhandled exception occured",exc_info=(type,value,traceback))
    #Don't need another copy of traceback on stderr
    if old_excepthook!=sys.__excepthook__:
        old_excepthook(type,value,traceback)
old_excepthook = sys.excepthook
sys.excepthook = excepthook
del log_file,os
# ####################################################
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...