Pythonのloggingを使って、用途別に複数のログファイルにログ出力する

phtyonロゴ

Pythonでは、ログ出力については標準機能として「logging」が準備されています。
実際のシステムでログ出力をおこなう場合、ログファイルが一種類であることは少なく、用途によってログファイルを分ける事が通常であると思います。


今回は、loggingを使って用途別に複数のログファイルにログ出力する方法を紹介します。


環境情報


  • Python 3.4.1

ログ管理クラス


ログファイルは以下の3種類を出力することを想定して、ログ出力クラスを作成していきます。

  • アプリケーションログ
  • SQLログ
  • エラーログ

この3つのログファイルを出力するログ管理クラスを作成します。


#!/usr/local/bin/python3.4
# coding: utf-8
import logging
from logging import getLogger, FileHandler

#
# ログクラス
#
class Log:

    # -------------------------------------
    # コンストラクタ
    # -------------------------------------
    def __init__(self):

        # 1.アプリケーションログ
        l = logging.getLogger('APL')
        formatter = logging.Formatter(
            '%(asctime)s <%(levelname)s> : %(message)s')
        fileHandler = 
            logging.FileHandler('./logs/APL.log', mode='a')
        fileHandler.setFormatter(formatter)
        l.setLevel(logging.INFO)
        l.addHandler(fileHandler)

        # 2.SQLログ
        l = logging.getLogger('SQL')
        formatter = logging.Formatter(
            '%(asctime)s <%(levelname)s> : %(message)s')
        fileHandler = 
            logging.FileHandler('./logs/SQL.log', mode='a')
        fileHandler.setFormatter(formatter)
        l.setLevel(logging.INFO)
        l.addHandler(fileHandler)

        # 3.エラーログ
        l = logging.getLogger('ERROR')
        formatter = logging.Formatter(
            '%(asctime)s <%(levelname)s> : %(message)s')
        fileHandler = 
            logging.FileHandler('./logs/ERROR.log', mode='a')
        fileHandler.setFormatter(formatter)
        l.setLevel(logging.INFO)
        l.addHandler(fileHandler)

        Log.__instance = self

    # -------------------------------------
    # 4.アプリケーションログにINFOでログ出力
    # -------------------------------------
    def aplInfo(self, msg):
        log = logging.getLogger('APL')
        log.info(msg)

    # -------------------------------------
    # 5.SQLログにINFOでログ出力
    # -------------------------------------
    def sqlInfo(self, msg):
        log = logging.getLogger('SQL')
        log.info(msg)

    # -------------------------------------
    # 6.エラーログにERRORでログ出力
    # -------------------------------------
    def errorError(self, msg):
        log = logging.getLogger('ERROR')
        log.error(msg)

順番に説明していきます。
まずは「1.アプリケーションログ」です。


‘APL’という名前のロガーを作成し、ログファイルの出力先パスや、ログファイルの出力フォーマット、ログ出力のモードを指定して、ログファイル出力のためのファイルハンドラを作成します。


l = logging.getLogger('APL')
formatter = logging.Formatter('%(asctime)s <%(levelname)s> : %(message)s')
fileHandler = logging.FileHandler('./logs/APL.log', mode='a')
fileHandler.setFormatter(formatter)

次に、ロガーのログレベルを設定し作成したファイルハンドラもロガーに設定すれば完了です。


l.setLevel(logging.INFO)
l.addHandler(fileHandler)

「2.SQLログ」「3.エラーログ」も、設定するロガーが「SQL」「ERROR」といったように異なるだけで、「1.アプリケーションログ」と同様の作りです


4~6はログ出力のメソッドになります。


「4.アプリケーションログにINFOでログ出力」のメソッドである「aplInfo」はAPLロガーを使っています。
つまり、APL.logにログレベルINFOでログ出力をおこないます。


「5.SQLログにINFOでログ出力」のメソッドである「sqlInfo」も「aplInfo」と同様です。
異なる部分はSQLロガーを使っているということのみであり、SQL.logにログレベルINFOでログ出力をおこないます。


「6.エラーログにERRORでログ出力」は、ERRORロガーを使い、ERROR.logにログレベルERRORでログ出力をおこないます。


今回のサンプルでは3つのログ出力メソッドしか用意していませんが、必要であれば”アプリケーションログにERRORでログ出力””エラーログにINFOでログ出力”といったログ出力も可能な事がわかると思います。


ログを出力する


ログクラスを呼び出せば、ログクラスのコンストラクタでログ出力に必要なインスタンスを使ってくれるので、ログ出力をおこなう方の実装は極めてシンプルです。
以下のログ出力処理を、ログ出力したい箇所に実装すればログ出力がおこなわれます。


# インスタンス作成
log = Log()

# アプリケーションログをINFOで出力
log.aplInfo("アプリケーションログ")

# SQLログをINFOで出力
log.aplInfo(SQLログ")

# エラーログをERRORで出力
log.aplInfo(エラーログ")


ApacheのログにPOSTで送信された内容をログ出力する方法

apache


Apacheのアクセスログには、デフォルトでGET形式で送信されたきたデータはログ出力されます。
しかし、POST形式で送信されたきたデータはログ出力されません。


実際には、Apacheが受信した時点でのHTTPリクエストにおけるPOSTデータを確認した場合があるかと思います。


というわけで今回は、POST形式のHTTPで送信されたきたデータをApacheのログに出力する方法を紹介します。


Apacheの設定を追加するだけで、ApacheのログにPOST形式で送信されたきたデータをログ出力できるようになります。


環境情報


  • OS:Windows10
  • Apache:Apache 2.4.41

mod_dumpioモジュールの有効化


POST形式で送信されたきたデータをログ出力するためには、「mod_dumpio」というApacheモジュールを有効にする必要があります。
「<Apacheインストールフォルダ>\conf」下の「httpd.conf」について、「mod_dumpio」を検索し、コメントアウトをはずして有効化します。


LoadModule dumpio_module modules/mod_dumpio.so

このモジュールを有効化することにより、HTTPリクエストの内容がログ出力されるようになります。


ログ出力設定の有効化


POST形式で送信されたきたデータをログ出力するためには、mod_dumpioモジュールの有効化以外に、httpd.confに3つの設定をおこなう必要があります。


  • 「DumpIOInput」ディレクティブの追記
  • 「DumpIOOutput」ディレクティブの追記
  • ログレベルを「dumpio:trace7」にする

「DumpIOInput」ディレクティブを追記します。
これを追記することで、HTTPリクエストの内容がログ出力されるようになります。

DumpIOInput On

「DumpIOOutput」ディレクティブを追記します。
これを追記することで、HTTPレスポンスの内容がログ出力されるようになります。

DumpIOOutput On

ログレベルを「dumpio:trace7」にします。

LogLevel dumpio:trace7

最後にApacheを再起動して、ログ出力の準備完了です。


POSTデータのログ出力


POST形式のリクエストがログ出力されるようになったのですが、具体的には「error.log」にログ出力されます。
以下のような感じです。

mod_dumpio:  dumpio_in (data-HEAP): Referer: http://localhost:81/test/post.html?query=1\r\n
mod_dumpio: dumpio_in [getline-blocking] 0 readbytes
mod_dumpio:  dumpio_in (data-HEAP): 36 bytes
mod_dumpio:  dumpio_in (data-HEAP): Accept-Encoding: gzip, deflate, br\r\n
mod_dumpio: dumpio_in [getline-blocking] 0 readbytes
mod_dumpio:  dumpio_in (data-HEAP): 42 bytes
mod_dumpio:  dumpio_in (data-HEAP): Accept-Language: ja,en-US;q=0.9,en;q=0.8\r\n
mod_dumpio: dumpio_in [getline-blocking] 0 readbytes
mod_dumpio:  dumpio_in (data-HEAP): 2 bytes
mod_dumpio:  dumpio_in (data-HEAP): \r\n
mod_dumpio: dumpio_in [readbytes-blocking] 25 readbytes
mod_dumpio:  dumpio_in (data-HEAP): 25 bytes
mod_dumpio:  dumpio_in (data-HEAP): address=address&name=name