87

このコードが画面に印刷されるのにファイルには印刷されない理由がわかりませんか?ファイル「example1.log」が作成されますが、何も書き込まれません。

#!/usr/bin/env python3
import logging

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(message)s',
                    handlers=[logging.FileHandler("example1.log"),
                              logging.StreamHandler()])
logging.debug('This message should go to the log file and to the console')
logging.info('So should this')
logging.warning('And this, too')

ロギングオブジェクトを作成することでこの問題を「バイパス」しましたが、basicConfig()アプローチが失敗した理由を悩ませ続けています。

PS。basicConfig呼び出しを次のように変更した場合:

logging.basicConfig(level=logging.DEBUG,
                    filename="example2.log",
                    format='%(asctime)s %(message)s',
                    handlers=[logging.StreamHandler()])

その後、すべてのログがファイルにあり、コンソールには何も表示されません。

4

5 に答える 5

58

コンソールとファイルの両方でこれを正常に動作させてみてください(Python 2.7でテスト済み)

# set up logging to file
logging.basicConfig(
     filename='log_file_name.log',
     level=logging.INFO, 
     format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
     datefmt='%H:%M:%S'
 )

# set up logging to console
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
# set a format which is simpler for console use
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)

logger = logging.getLogger(__name__)
于 2014-05-15T14:43:49.190 に答える
28

Python3.3では再現できません。メッセージは画面との両方に書き込まれます'example2.log'。Python <3.3では、ファイルは作成されますが、空です。

コード:

from logging_tree import printout  # pip install logging_tree
printout()

FileHandler()Python<3.3のルートロガーに接続されていないことを示しています。

logging.basicConfig()そのhandlers引数のドキュメントはPython3.3で追加されています。このhandlers引数は、Python3.2のドキュメントには記載されていません。

于 2012-11-20T18:14:05.630 に答える
9

以下の例では、レベルに基づいてログの宛先を指定できます。たとえば、以下のコードでは、INFOレベルを超えるすべてのログがログファイルに送られ、 ERRORレベルを超えるすべてのログがコンソールに送られます。

import logging
logging.root.handlers = []
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO , filename='ex.log')

# set up logging to console
console = logging.StreamHandler()
console.setLevel(logging.ERROR)
# set a format which is simpler for console use
formatter = logging.Formatter('%(asctime)s : %(levelname)s : %(message)s')
console.setFormatter(formatter)
logging.getLogger("").addHandler(console)

logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.exception('exp')
于 2016-07-27T12:37:36.400 に答える
7

を使用する別の手法basicConfigは、ステートメント内のすべてのハンドラーを設定し、事後にそれらを取得することです。

import logging

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(levelname)s %(module)s %(funcName)s %(message)s',
                    handlers=[logging.FileHandler("my_log.log", mode='w'),
                              logging.StreamHandler()])
stream_handler = [h for h in logging.root.handlers if isinstance(h , logging.StreamHandler)][0]
stream_handler.setLevel(logging.INFO)

ただし、より賢明なのは、ストリームハンドラインスタンスを外部で構築し、それらをスタンドアロンオブジェクトとして構成して、次のようにハンドラリストに渡すことです...

import logging

stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(levelname)s %(module)s %(funcName)s %(message)s',
                    handlers=[logging.FileHandler("my_log.log", mode='w'),
                              stream_handler])
于 2019-11-13T00:05:41.613 に答える
1

うわぁ!

私はこれに困惑して約20分を過ごしました。

最終的に、が出力されているのではなく、StreamHandlerに出力されていることがわかりました('Doze DOS画面では、これらは同じフォントの色になっています!)。stderrstdout

これにより、コードを完全に正常に実行して適切な結果を得ることができましたが、pytest関数では問題が発生しました。私がこれから変わるまで:

out, _ = capsys.readouterr()
assert 'test message check on console' in out, f'out was |{out}|'

これに:

_, err = capsys.readouterr()
assert 'test message check on console' in err, f'err was |{err}|'

NBStreamHandlerのコンストラクターは

class logging.StreamHandler(stream=None)

また、ドキュメントに記載されているように、「ストリームが指定されている場合、インスタンスはそれをログ出力に使用します。それ以外の場合は、sys.stderrが使用されます。」

注意:levelキーワードの指定はハンドラーでは実行されないようです。重要な場合はsetLevel、結果のハンドラーを繰り返し処理し、それぞれで実行する必要があります。setLevel

于 2021-10-24T11:22:16.657 に答える