Uzyskaj dane wyjściowe z modułu rejestrowania w notatniku IPython

127

Po uruchomieniu następującego programu w notatniku IPython nie widzę żadnych danych wyjściowych:

import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug("test")

Czy ktoś wie, jak to zrobić, żebym mógł zobaczyć komunikat „testowy” wewnątrz notebooka?

Kyle Brandt
źródło
Jakiej wersji IPythona używasz, skoro to działa w 1.0?
Viktor Kerkez
@ViktorKerkez ipython3 notebook --versionpowraca1.0.0
Kyle Brandt
imgur.com/1b7nGZz Dostaję to, kiedy próbuję twojego kodu.
Viktor Kerkez
@ViktorKerkez: Tak, nie rozumiem, chyba powinienem zgłosić problem ...
Kyle Brandt

Odpowiedzi:

129

Spróbuj wykonać następujące czynności:

import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logging.debug("test")

Zgodnie z logging.basicConfig :

Wykonuje podstawową konfigurację systemu rejestrowania, tworząc StreamHandler z domyślnym programem formatującym i dodając go do głównego programu rejestrującego. Funkcje debug (), info (), warning (), error () i krytyczne () będą wywoływać basicConfig () automatycznie, jeśli dla głównego programu rejestrującego nie są zdefiniowane żadne programy obsługi.

Ta funkcja nic nie robi, jeśli główny program rejestrujący ma już skonfigurowane procedury obsługi.

Wygląda na to, że ipython notebook wywołuje gdzieś basicConfig (lub set handler).

falsetru
źródło
4
To samo dzieje się w normalnej konsoli IPythona: nic nie drukuje, chyba że loggerzostanie utworzony root .
Ioannis Filippidis
1
To rozwiązanie działa ponownie w ipykernel4.5 (prawdopodobnie już w 4.4) github.com/jupyter/notebook/issues/1397
pylang
17
To już nie działa. Nie z Jupyter Notebook 5.3.0
Wesam
64

Jeśli nadal chcesz używać basicConfig, załaduj ponownie moduł logowania w ten sposób

from importlib import reload  # Not needed in Python 2
import logging
reload(logging)
logging.basicConfig(format='%(asctime)s %(levelname)s:%(message)s', level=logging.DEBUG, datefmt='%I:%M:%S')
aksamitka
źródło
16
Dla każdego, kto próbuje to zrobić w Pythonie 3: reloadjest terazimp.reload
kuzzooroo
11
od Pythona 3.5 powinieneś używać importlib.reload, ponieważ moduł imp jest przestarzały.
Webucator
2
Jeśli ktoś ma problemy ze Spyderem z logowaniem (gdzie wszystkie próby modyfikacji zachowania rejestratora kończyły się niepowodzeniem), to właśnie zakończyło całodniową pogoń za gęsią skórką. github.com/spyder-ide/spyder/issues/2572 Wielkie dzięki!
FrenchKheldar
27

Rozumiem, że sesja IPython rozpoczyna rejestrowanie, więc basicConfig nie działa. Oto konfiguracja, która działa dla mnie (chciałbym, żeby nie wyglądała tak obrzydliwie, ponieważ chcę jej używać do prawie wszystkich moich notebooków):

import logging
logger = logging.getLogger()
fhandler = logging.FileHandler(filename='mylog.log', mode='a')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fhandler.setFormatter(formatter)
logger.addHandler(fhandler)
logger.setLevel(logging.DEBUG)

Teraz kiedy biegnę:

logging.error('hello!')
logging.debug('This is a debug message')
logging.info('this is an info message')
logging.warning('tbllalfhldfhd, warning.')

Otrzymuję plik „mylog.log” w tym samym katalogu co mój notatnik, który zawiera:

2015-01-28 09:49:25,026 - root - ERROR - hello!
2015-01-28 09:49:25,028 - root - DEBUG - This is a debug message
2015-01-28 09:49:25,029 - root - INFO - this is an info message
2015-01-28 09:49:25,032 - root - WARNING - tbllalfhldfhd, warning.

Zwróć uwagę, że jeśli uruchomisz to ponownie bez ponownego uruchamiania sesji IPython, zapisze zduplikowane wpisy do pliku, ponieważ byłyby teraz zdefiniowane dwa programy obsługi plików

skulz00
źródło
3
Aby uczynić to mniej „grubym”, umieść kod w module na ścieżce Pythona i zaimportuj go. Ładniejsza i łatwiejsza do rozbudowy w przyszłości.
Alexis
1
Lub użyj logging.config.fileConfig ('logging.conf') i umieść tam wszystkie ustawienia.
K.-Michael Aye
14

Pamiętaj, że stderr jest domyślnym strumieniem dla loggingmodułu, więc w notatnikach IPython i Jupyter możesz nic nie zobaczyć, chyba że skonfigurujesz strumień na stdout:

import logging
import sys

logging.basicConfig(format='%(asctime)s | %(levelname)s : %(message)s',
                     level=logging.INFO, stream=sys.stdout)

logging.info('Hello world!')
Ataxias
źródło
13

Co teraz zadziałało (Jupyter, serwer notebooków to: 5.4.1, IPython 7.0.1)

import logging
logging.basicConfig()
logger = logging.getLogger('Something')
logger.setLevel(logging.DEBUG)

Teraz mogę użyć loggera do wydrukowania informacji, w przeciwnym razie zobaczyłbym tylko komunikat z poziomu domyślnego ( logging.WARNING) lub wyższego.

mcsim
źródło
2
Tak, to działa. Jedna ma biec basicConfig()tp sprawiają, że praca.
Brandt
11

Możesz skonfigurować logowanie, uruchamiając %config Application.log_level="INFO"

Aby uzyskać więcej informacji, zobacz opcje jądra IPython

Garvey
źródło
1
Witamy w StackOverflow i dziękujemy za pomoc. Możesz chcieć ulepszyć swoją odpowiedź, dodając wyjaśnienie.
Elias MP
1
To była dla mnie najbardziej przydatna odpowiedź!
IanS
1
Czy możesz dodać kilka wierszy z przykładem? Jaki jest uchwyt programu rejestrującego do wywołania w celu wydrukowania komunikatów dziennika?
Wesam
Przynajmniej ipython 7.9.0 (lub jupyter 6.0.2) ignoruje sugerowany kod, ponieważ nie obsługuje tej klasy z uruchomionej konsoli. Biegnij, %configaby zobaczyć obsługiwane sklasyfikowane, Applicationnie jest jednym z nich. ipython 7.9.0 tutaj.
stason
4

Ustawiłem rejestrator dla obu plików i chciałem, aby pojawił się na notebooku. Okazuje się, że dodanie obsługi plików usuwa domyślną obsługę strumienia.

logger = logging.getLogger()

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# Setup file handler
fhandler  = logging.FileHandler('my.log')
fhandler.setLevel(logging.DEBUG)
fhandler.setFormatter(formatter)

# Configure stream handler for the cells
chandler = logging.StreamHandler()
chandler.setLevel(logging.DEBUG)
chandler.setFormatter(formatter)

# Add both handlers
logger.addHandler(fhandler)
logger.addHandler(chandler)
logger.setLevel(logging.DEBUG)

# Show the handlers
logger.handlers

# Log Something
logger.info("Test info")
logger.debug("Test debug")
logger.error("Test error")
Bryg
źródło
0

Wygląda na to, że rozwiązania, które działały na starszych wersjach ipython / jupyter, już nie działają.

Oto działające rozwiązanie dla ipythona 7.9.0 (testowane również z serwerem jupyter 6.0.2):

import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logging.debug("test message")

DEBUG:root:test message
stason
źródło