(機械翻訳) ロギング

:app: Pyramid`は、Pythonの標準ライブラリmod: logging`モジュールを利用できます。この章では、ロギングを設定する方法と、設定したロガーにログメッセージを送信する方法について説明します。

警告

この章では、:term: cookiecutter`を使って、 development.ini``と `production.ini``ファイルを含むプロジェクトを作成し、ロギングの設定を支援すると仮定しています。 Pylonsプロジェクトによって提供されたピラミッドのcookiecuttersはすべてこれを行います。 cookiecutterを使用していない場合、またはこれらのファイルを作成しないサードパーティのcookiecutterを使用している場合は、この章の設定情報が適用されない場合があります。

ロギング設定

A:app: Pyramid`プロジェクトは:term: cookiecutter`から作成し、あなたにメッセージを送るように設定されています:mod: Python標準ライブラリloggingパッケージ<logging> `あなたのアプリケーション内のロガー。特に、cookiecutterを使用するときに作成される:term: `PasteDeploy` development.ini``と production.ini``ファイルには、Python:mod: logging`パッケージの基本設定が含まれています。

PasteDeploy `` .ini``ファイルはPython標準ライブラリを使います:mod: ConfigParser format <ConfigParser> `。これは、Python:ref: `loggingモジュールの設定ファイルフォーマットと同じフォーマットです<logging-config-fileformat> `。設定ファイルのアプリケーション関連とロギング関連のセクションは平和的に共存でき、 ` pserve``を実行するときにはファイルのログ関連のセクションが使用されます。

`` pserve``コマンドは:func: pyramid.paster.setup_logging`関数を呼び出します。これは指定された .ini`ファイルを使って:func: logging.config.fileConfig`のシンラッパーです。 ` [loggers] ``セクション(cookiecutterによって生成された `` .ini``ファイルのすべてが行います)。 `` setup_logging``は、 `` pserve``が呼び出されたiniファイルからログ設定を読み込みます。

デフォルトのロギング設定は、デフォルトの `` development.ini``と `` production.ini``ファイルの両方で提供されます。 `` pyramid-cookiecutter-starter``を使ってパッケージの名前を `` hello_world``としてPyramidプロジェクトを生成すると、 `` development.ini``ファイルのロギング設定は次のようになります:

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
###
# logging configuration
# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###

[loggers]
keys = root, myproject

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = INFO
handlers = console

[logger_myproject]
level = DEBUG
handlers =
qualname = myproject

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s

`` production.ini``ファイルは `` DEBUG``の代わりに `` WARN``​​レベルをロガー設定で使用しますが、それ以外は同じです。

このロギング構成では、

  • `` root``という名前のロガーが作成されます。このロガーは、 `` INFO``レベル以上のレベルのメッセージをstderrに次の形式で記録します:

    2007-08-17 15:04:08,704 INFO [packagename] Loading resource, id: 86
    
  • `` myproject``という名前のロガーは、ルートロガーと同じフォーマットでstderrに `` DEBUG` &quot;以上のレベルで送られたメッセージを記録します。

`` root``ロガーはPyramidプロセスのすべてのアプリケーションで使用され、プロジェクトのパッケージ名以外のもので始まる名前を持つロガーを( `` logging.getLogger``を介して)尋ねます(例えば、 `` myproject``)。あなたのパッケージ名と同じ名前のロガーは、あなたの:app: `Pyramid`アプリケーションであなた自身の用法のために予約されています。その存在は、cookiecutterを介して生成された:app: `Pyramid`アプリケーションから既知のロギング場所にログインできることを意味します。

:app: Pyramid`と他の多くのライブラリ(Beaker、SQLAlchemy、Pasteなど)はデバッグの目的でいくつかのメッセージをルートロガーに記録します。ルートロガーレベルを ` DEBUG``に切り替えると、それらが明らかになります:

[logger_root]
#level = INFO
level = DEBUG
handlers = console

一部のcookiecuttersは、使用する追加のサブシステム(SQLALchemyなど)用に追加のロガーを構成します。 cookiecutterからプロジェクトを作成するときに表示される `` production.ini``と `` development.ini``ファイルを見てください。

ロギングメッセージの送信

Pythonの特別な `` __name__``変数は、現在のモジュールの完全修飾名を参照します。 `` myproject``という名前のパッケージ内のどのモジュールからでも、 `` __name__``組み込み変数は常に `` myproject`や `` myproject.subpackage``や `` myproject.package.subpackage``のようなものですあなたのプロジェクトの名前が `` myproject``の場合。このロガーにメッセージを送ると、 `` myproject``ロガーに送られます。

あなたの `` .ini``ファイルで設定されたパッケージ固有のロガーにメッセージを記録するには、組み込み関数 `` __name__``を使ってロガーオブジェクトを作成し、メソッドを呼び出します。

1
2
3
4
5
6
7
8
9
import logging
log = logging.getLogger(__name__)

def myview(request):
    content_type = 'text/plain'
    content = 'Hello World!'
    log.debug('Returning: %s (content-type: %s)', content, content_type)
    request.response.content_type = content_type
    return request.response

これによりコンソールに `` stderr``が出力されます:

16:20:20,440 DEBUG [myproject.views] Returning: Hello World!
                   (content-type: text/plain)

ログメッセージのフィルタリング

ルートロガーのレベルを `` DEBUG``に切り替えるときなど、あまりにも多くのログ出力が表示されることがあります。

たとえば、アプリケーションのデータベース接続の問題を診断し、データベース接続プーリングに関連してSQLAlchemyの `` DEBUG``メッセージだけを見たいとします。ルートロガーのレベルをあまり控えめな `` INFO``レベルにしておき、ルートロガーとは別に、特定のSQLAlchemyロガーをそれ自身で `` DEBUG``に設定することができます:

[logger_sqlalchemy.pool]
level = DEBUG
handlers =
qualname = sqlalchemy.pool

ロガーのリストに追加します。

[loggers]
keys = root, myproject, sqlalchemy.pool

このロガーにはハンドラーを設定する必要はありません。デフォルトでは、ルート以外のロガーはログ記録を親ロガーのハンドラーまで伝播します。ルートロガーは、すべてのロガーのトップレベルの親です。

この手法はデフォルトの `` development.ini``で使われます。ルートロガーのレベルは `` INFO``に設定され、アプリケーションのログレベルは `` DEBUG``に設定されます:

# Begin logging configuration

[loggers]
keys = root, myproject

[logger_myproject]
level = DEBUG
handlers =
qualname = myproject

`` myproject`ロガーのすべての子ロガーは明示的に異なって設定されない限り、 `` DEBUG``レベルを継承します。つまり、 `` myproject.views``、 `` myproject.models``、そしてあなたのアプリケーションのすべてのモジュールのロガーは、デフォルトで有効レベルが `` DEBUG``です。

より高度なフィルタリングのために、ロギングモジュールは:class: `logging.Filter`オブジェクトを提供します。ただし、設定ファイルから直接使用することはできません。

高度な設定

ログ出力を別のファイルに取り込むには、class: logging.FileHandler`(または:class: logging.handlers.RotatingFileHandler`)を使用します。

[handler_filelog]
class = FileHandler
args = ('%(here)s/myproject.log','a')
level = INFO
formatter = generic

認識される前に、ハンドラのリストに追加する必要があります。

[handlers]
keys = console, myproject, filelog

最後にロガーによって利用される。

[logger_root]
level = INFO
handlers = console, filelog

これらの最後の3行の設定は、ルートロガーのすべての出力を `` myproject.log``とコンソールに向けます。

例外のロギング

:app: Pyramid`アプリケーションによって生成された例外をログに記録するか電子メールを送るには、:term: pyramid_exclog`パッケージを使用します。その設定の詳細は、 `ドキュメント<https://docs.pylonsproject.org/projects/pyramid_exclog/en/latest/> `_。

ペーストのTransLoggerを使用したロギングのリクエスト

:term: WSGI`デザインはモジュール化されています。ウェイトレスは、エラー状態、デバッグ出力などを記録しますが、Webトラフィックは記録しません。ウェブトラフィックのロギングの場合、Pasteは `TransLogger <http://pythonpaste.org/modules/translogger.html> `_:用語:`ミドルウェア &#39;。 TransLoggerは、 `Apache Combined Log Format <http://httpd.apache.org/docs/2.2/logs.html#combined> `_。しかし、TransLoggerはファイルに書き込みません。これを行うようにPythonロギングシステムを設定する必要があります。 Python:class: `logging.FileHandler`ロギングハンドラは、TransLoggerとともにApacheのような `access.log``ファイルを作成するために使うことができます。

他の標準:term: ミドルウェア`と同様に、Pasteエントリーポイントで、TransLoggerは `.ini`ファイル構文を使ってアプリケーションをラップするように設定できます。まずPyramidの ` .ini``ファイルの `` [app:main] ``セクションの名前を `` [app:mypyramidapp] ``に変更し、 `` [filter:translogger] ``セクションを追加し、 [pipeline:main] `セクションファイルを使用して、transloggerとアプリケーションの両方にWSGIパイプラインを形成します。たとえば、次のように変更します。

[app:main]
use = egg:myproject

これに:

[app:mypyramidapp]
use = egg:myproject

[filter:translogger]
use = egg:Paste#translogger
setup_console_handler = False

[pipeline:main]
pipeline = translogger
           mypyramidapp

このようにPasteDeployを使ってパイプラインを作成して提供することは、プロジェクトの `` __init__``ファイルの `` main``関数の一番下でTransLoggerインスタンスにアプリケーションをラップすることと同じです:

...
app = config.make_wsgi_app()
from paste.translogger import TransLogger
app = TransLogger(app, setup_console_handler=False)
return app

注釈

引数なしで呼び出されると、TransLoggerは自動的にロギングハンドラをコンソールに設定します。したがって、ロギングを設定していない環境では、動作します。ロギングハンドラが設定されているので、 `` setup_console_handler = False``でオートメーションを無効にします。

フィルタを適切に配置すると、TransLoggerのロガー( `` wsgi``ロガー)はログメッセージを親ロガー(ルートロガー)に伝え、ページを要求するときにその出力をコンソールに送ります:

00:50:53,694 INFO [myproject.views] Returning: Hello World!
                  (content-type: text/plain)
00:50:53,695 INFO [wsgi] 192.168.1.111 - - [11/Aug/2011:20:09:33 -0700] "GET /hello
HTTP/1.1" 404 - "-"
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.6) Gecko/20070725
Firefox/2.0.0.6"

TransLoggerを `` access.log``のFileHandlerに向けるには、ハンドラのリストにFileHandler( `` accesslog``という名前)を追加し、 `` wsgi``ロガーが設定され、使用されていることを確認する必要がありますそれに応じてこのハンドラ:

# Begin logging configuration

[loggers]
keys = root, myproject, wsgi

[handlers]
keys = console, accesslog

[logger_wsgi]
level = INFO
handlers = accesslog
qualname = wsgi
propagate = 0

[handler_accesslog]
class = FileHandler
args = ('%(here)s/access.log','a')
level = INFO
formatter = generic

前述したように、非ルートロガーは、デフォルトでログ記録をルートロガーのハンドラー(現在はコンソールハンドラー)に伝播します。ここで `` propagate``を `` 0``( `` False``)に設定すると、これは無効になります。 `` wsgi``ロガーは `` accesslog``ハンドラにのみレコードを送ります。

最後に、TransLogger自体に必要なすべての情報を提供するため、TransLoggerで `` generic``フォーマッタを使用する必要はありません。ログメッセージをそのまま通過させるフォーマッタを使用します。 `` accesslog``と呼ばれる新しいフォーマッタを設定ファイルに追加して追加してください:

[formatters]
keys = generic, accesslog

[formatter_accesslog]
format = %(message)s

最後に、既存の設定を変更して、この新しい `` accesslog``フォーマッタをFileHandlerに接続します:

[handler_accesslog]
class = FileHandler
args = ('%(here)s/access.log','a')
level = INFO
formatter = accesslog