Pythonのlogging
モジュールを理解することはできません。私のニーズは非常に単純です。すべてをsyslogに記録したいだけです。ドキュメントを読んだ後、次の簡単なテストスクリプトを思い付きました。
import logging
import logging.handlers
my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)
handler = logging.handlers.SysLogHandler()
my_logger.addHandler(handler)
my_logger.debug('this is debug')
my_logger.critical('this is critical')
ただし、このスクリプトはsyslogにログレコードを作成しません。どうしましたか?
行を次のように変更します。
handler = SysLogHandler(address='/dev/log')
これは私のために働く
import logging
import logging.handlers
my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)
handler = logging.handlers.SysLogHandler(address = '/dev/log')
my_logger.addHandler(handler)
my_logger.debug('this is debug')
my_logger.critical('this is critical')
TCPスタックを介して/ dev/logまたはlocalhostのいずれかに常にログにローカルホストを使用する必要があります。これにより、完全にRFCに準拠した機能的なシステムロギングデーモンがsyslogを処理できます。これにより、リモートデーモンが機能する必要がなくなり、たとえばrsyslogやsyslog-ngなどのsyslogデーモンの拡張機能が提供されます。同じ哲学がSMTPにも当てはまります。それをローカルのSMTPソフトウェアに渡すだけです。この場合、デーモンではなく「プログラムモード」を使用しますが、これは同じ考えです。より高性能なソフトウェアに処理させてください。 syslogのUDPの代わりにTCPを使用した再試行、キューイング、ローカルスプールなどが可能になります。必要に応じて、これらのデーモンをコードとは別に[再]構成することもできます。
アプリケーションのコーディングを保存し、他のソフトウェアが協調して仕事をするようにします。
syslogモジュール を見つけて、説明した基本的なロギング動作を簡単に取得できるようにしました。
import syslog
syslog.syslog("This is a test message")
syslog.syslog(syslog.LOG_INFO, "Test message at INFO priority")
他にもできることはありますが、最初の2行だけでも、私が理解しているように、あなたが求めているものを得ることができます。
ここと他の場所から物をつなぎ合わせて、unbuntu 12.04とcentOS6で動作するようになりました。
.confで終わる/etc/rsyslog.d/
にファイルを作成し、次のテキストを追加します
local6.* /var/log/my-logfile
rsyslog
を再起動します。新しいログファイルでは再読み込みが機能していないようです。たぶん、既存の設定ファイルをリロードするだけでしょうか?
Sudo restart rsyslog
次に、このテストプログラムを使用して、実際に機能することを確認します。
import logging, sys
from logging import config
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(module)s P%(process)d T%(thread)d %(message)s'
},
},
'handlers': {
'stdout': {
'class': 'logging.StreamHandler',
'stream': sys.stdout,
'formatter': 'verbose',
},
'sys-logger6': {
'class': 'logging.handlers.SysLogHandler',
'address': '/dev/log',
'facility': "local6",
'formatter': 'verbose',
},
},
'loggers': {
'my-logger': {
'handlers': ['sys-logger6','stdout'],
'level': logging.DEBUG,
'propagate': True,
},
}
}
config.dictConfig(LOGGING)
logger = logging.getLogger("my-logger")
logger.debug("Debug")
logger.info("Info")
logger.warn("Warn")
logger.error("Error")
logger.critical("Critical")
この交換が便利だと思ったが、それをすべて機能させるためにこの少しの追加情報が必要だったので、それが誰かを助ける場合に備えて、少し余分なコメントを追加します。
SysLogHandlerを使用して特定の施設にログを記録するには、施設の値を指定する必要があります。たとえば、次のように定義したとします。
local3.* /var/log/mylog
syslogで、次を使用します。
handler = logging.handlers.SysLogHandler(address = ('localhost',514), facility=19)
また、/ dev/logの代わりにlocalhostを使用するには、syslogでUDPをリッスンする必要があります。
Syslog.confは、facility = userを処理するように設定されていますか?
pythonロガーで使用される機能は、次のような機能引数を使用して設定できます。
handler = logging.handlers.SysLogHandler(facility=SysLogHandler.LOG_DAEMON)
から https://github.com/luismartingil/per.scripts/tree/master/python_syslog
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
Implements a new handler for the logging module which uses the pure syslog python module.
@author: Luis Martin Gil
@year: 2013
'''
import logging
import syslog
class SysLogLibHandler(logging.Handler):
"""A logging handler that emits messages to syslog.syslog."""
FACILITY = [syslog.LOG_LOCAL0,
syslog.LOG_LOCAL1,
syslog.LOG_LOCAL2,
syslog.LOG_LOCAL3,
syslog.LOG_LOCAL4,
syslog.LOG_LOCAL5,
syslog.LOG_LOCAL6,
syslog.LOG_LOCAL7]
def __init__(self, n):
""" Pre. (0 <= n <= 7) """
try:
syslog.openlog(logoption=syslog.LOG_PID, facility=self.FACILITY[n])
except Exception , err:
try:
syslog.openlog(syslog.LOG_PID, self.FACILITY[n])
except Exception, err:
try:
syslog.openlog('my_ident', syslog.LOG_PID, self.FACILITY[n])
except:
raise
# We got it
logging.Handler.__init__(self)
def emit(self, record):
syslog.syslog(self.format(record))
if __== '__main__':
""" Lets play with the log class. """
# Some variables we need
_id = 'myproj_v2.0'
logStr = 'debug'
logFacilityLocalN = 1
# Defines a logging level and logging format based on a given string key.
LOG_ATTR = {'debug': (logging.DEBUG,
_id + ' %(levelname)-9s %(name)-15s %(threadName)-14s +%(lineno)-4d %(message)s'),
'info': (logging.INFO,
_id + ' %(levelname)-9s %(message)s'),
'warning': (logging.WARNING,
_id + ' %(levelname)-9s %(message)s'),
'error': (logging.ERROR,
_id + ' %(levelname)-9s %(message)s'),
'critical': (logging.CRITICAL,
_id + ' %(levelname)-9s %(message)s')}
loglevel, logformat = LOG_ATTR[logStr]
# Configuring the logger
logger = logging.getLogger()
logger.setLevel(loglevel)
# Clearing previous logs
logger.handlers = []
# Setting formaters and adding handlers.
formatter = logging.Formatter(logformat)
handlers = []
handlers.append(SysLogLibHandler(logFacilityLocalN))
for h in handlers:
h.setFormatter(formatter)
logger.addHandler(h)
# Yep!
logging.debug('test debug')
logging.info('test info')
logging.warning('test warning')
logging.error('test error')
logging.critical('test critical')
import syslog
syslog.openlog(ident="LOG_IDENTIFIER",logoption=syslog.LOG_PID, facility=syslog.LOG_LOCAL0)
syslog.syslog('Log processing initiated...')
上記のスクリプトは、カスタムの「LOG_IDENTIFIER」を使用してLOCAL0ファシリティにログを記録します...ローカルの目的でLOCAL [0-7]を使用できます。
以下は、3.2以降で推奨されるyaml dictConfigの方法です。
ログcfg.yml
:
version: 1
disable_existing_loggers: true
formatters:
default:
format: "[%(process)d] %(name)s(%(funcName)s:%(lineno)s) - %(levelname)s: %(message)s"
handlers:
syslog:
class: logging.handlers.SysLogHandler
level: DEBUG
formatter: default
address: /dev/log
facility: local0
rotating_file:
class: logging.handlers.RotatingFileHandler
level: DEBUG
formatter: default
filename: rotating.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
root:
level: DEBUG
handlers: [syslog, rotating_file]
propogate: yes
loggers:
main:
level: DEBUG
handlers: [syslog, rotating_file]
propogate: yes
以下を使用して構成をロードします。
log_config = yaml.safe_load(open('cfg.yml'))
logging.config.dictConfig(log_config)
Syslogと直接ファイルの両方を構成しました。 /dev/log
はOS固有であることに注意してください。
ノートブックで修正します。 rsyslogサービスはソケットサービスをリッスンしませんでした。
この行を/etc/rsyslog.conf
ファイルで設定し、問題を解決しました。
$SystemLogSocketName /dev/log