1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PythonのloggingモジュールでシスログにNOTICEレベルのログを出力する方法

Posted at

PythonをLinux環境で使用していて、ログをLinuxのシステムログに出力したいと思ったことがありました。
しかし、Linuxで使用できるNOTICEレベルのログを出力できない等、実環境で使うのに少し不便に思うことがあったので、使いやすいようカスタマイズすることにしました。

この記事では、loggingモジュールを使ってログをLinuxのシステムログに出力する方法と、ログレベルNOTICEを追加する方法を紹介します。

Python Logger Class

printでコンソールにメッセージを出力してもいいけれど、システムログに出力したい時や、レベルによって出力を絞りたい時等、色々便利です。

基本的な使い方はドキュメントにも書いてある通りになります。


import logging

logging.warning('出力したい文字列')

Linuxのシスログにログを出力する方法

handlersの設定を行い、出力先をLinuxのログデバイスに設定します。

サンプルコード:


import logging
from logging import handlers

LOG_DEVICE = "/dev/log" #LinuxOSのログデバイス
LOG_LEVEL = "debug" #実際に出力されるログはシスログプロセスが管理するので、debugにして全てのログを出力するようにします。

logger = logging.getLogger(name)
logger.setLevel(LOG_LEVEL)
logging.handlers.SysLogHandler(LOG_DEVICE) #出力先をLinuxのログデバイスに設定します。大体/dev/logになっています
ch.setLevel(LOG_LEVEL)
formatter = logging.Formatter('%(name)s [%(process)d]: %(message)s') #シスログの出力メッセージの形式に合わせて調整します
ch.setFormatter(formatter)
logger.addHandler(ch)

logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

これでログがシステムログに出力されるようになりました。
システムログに出力されるログのレベルはシステムログ側の設定で絞ることができますので、Python側のレベル設定はdebugにしておきます。

Loggerのログレベルについて

現在loggingモジュールに用意されているログレベルは下記の5つだけ。
DEBUG
INFO
WARNING
ERROR
CRITICAL

Linuxのシステムログを使用するにあたって、もう少しログレベルを調整できるようにします。サンプルではNOTICEレベルを追加します。
ログレベルを追加するには、既存のloggerクラスを継承したクラスを作成してログレベルを追加していきます。

サンプルコード:


import logging
from logging import handlers

LOG_DEVICE = "/dev/log" 
LOG_LEVEL = "debug"
NOTICE = 25 # ログレベルinfo(20), warning(30)の間の数にします

class UnixLogger(logging.Logger): # Loggerクラスを継承したクラスを作成
    def __init__(self, name, level=logging.NOTSET):
        super().__init__(name, level)
    
    def notice(self, msg, *args, **kwargs): # noticeメソッドを定義
        """
        Log 'msg % args' with severity 'NOTICE (25)'.
        To pass exception information, use the keyword argument exc_info with
        a true value, e.g.
        logger.notice("Houston, we have a %s", "thorny problem", exc_info=1)
        """

        if self.isEnabledFor(NOTICE):
            self._log(NOTICE, msg, args, **kwargs)

# 追加部 ログレベルを追加してメソッドを追加したloggerクラスをセットする
logging.addLevelName(NOTICE, "NOTICE")
logging.handlers.SysLogHandler.priority_map.update({"NOTICE" : "notice"})
logging.setLoggerClass(UnixLogger)

logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)
logging.handlers.SysLogHandler(LOG_DEVICE) 
ch.setLevel(LOG_LEVEL)
formatter = logging.Formatter('%(name)s [%(process)d]: %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)

logger.debug('debug message')
logger.info('info message')
logger.notice('notice message') # 追加したログレベルのメッセージを出力
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

これでnoticeレベルのログを簡単に出力できるようになりました。
他のレベルや、独自にログレベルをカスタマイズしたい場合でも同様に設定することができます。

サンプルコード公開

本記事のサンプルコードは、Github上に公開しています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?