9

logging.fileConfig()を使用してロギングを構成しました。SysLogHandler('/ dev / log'、handlers.SysLogHandler.LOG_USER)を使用するハンドラーに移動するルートロガーがあります

これはすべて完全にうまく機能し、/ var / log/user.logにログエントリが表示されます

問題は、syslog ident文字列をpython以外に設定するにはどうすればよいですか?標準ライブラリのsyslogモジュールでは、ログを開くときにこれを設定できるようですが、ログハンドラーはこの機能を提供していません。

解決策は、SysLogHandlerをサブクラス化し、emitメソッド内でsyslogライブラリを使用することでしょうか?これはUNIXのみのプログラムであるため、syslogを直接使用しても移植性の問題は発生しません。

4

4 に答える 4

9

これは少し古いですが、新しい情報をここに記録して、ユーザーが独自のsyslogハンドラーを作成する必要を感じないようにする必要があります。

Python 3.3以降、SysLogHandler.identには、まさにこの目的のためのクラス属性があります。デフォルトは''です。

例:

import logging
from logging.handlers import SysLogHandler

h = SysLogHandler(address=('some.destination.com',514), facility=SysLogHandler.LOG_LOCAL6)
h.setFormatter(
    logging.Formatter('%(name)s %(levelname)s %(message)s')
)
h.ident = 'conmon'

syslog = logging.getLogger('syslog')
syslog.setLevel(logging.DEBUG)
syslog.addHandler(h)

syslog.debug('foo syslog message')
于 2013-10-26T20:02:52.877 に答える
8

RFC3164メッセージを受け入れるSyslog実装は、メッセージの最初の部分("foo:"例では)をTAGとして認識する必要があります。

MSGパーツには、TAGフィールドとCONTENTフィールドと呼ばれる2つのフィールドがあります。TAGフィールドの値は、メッセージを生成したプログラムまたはプロセスの名前になります。

Pythonコード。

import logging
from logging.handlers import SysLogHandler

h = SysLogHandler(address='/dev/log')
h.setFormatter(logging.Formatter('foo: %(message)s'))
logging.getLogger().addHandler(h)

logging.error('bar')

..これをsyslogソケットに送信します

connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 10) = 0
sendto(3, "<11>foo: bar\0", 13, 0, NULL, 0) = 13
close(3)

これは、systemdのジャーナルでこれを生成します。

Dec 13 14:48:20 laptop foo[1928]: bar

ジャーナルメッセージの詳細:

{
  ..
  "PRIORITY" : "3",
  "SYSLOG_FACILITY" : "1",
  "SYSLOG_IDENTIFIER" : "foo",
  "MESSAGE" : "bar",
  "_PID" : "1928",
}

Py2.6、2.7、3.4、3.5およびSystemdのsyslogサーバーで動作します。他のsyslog実装(RFC3164を受け入れる場合)メッセージでも機能する可能性があります。PythonのSysLogHandlerがデフォルトで新しいRFC5424になると、このソリューションはおそらく壊れます。

于 2016-12-13T16:58:22.943 に答える
4

AFAIK、ident文字列はsyslogAPIのアーティファクトです。このページを参照してください。もちろん「python」であるCargv[0]を使用しているだけです。

SysLogHandlerドメインソケットまたはTCPソケットを介してsyslogデーモンに送信されるメッセージは、<山括弧>の優先度の後にフォーマットされたメッセージとNULバイトが続く文字列であるため、ドメインソケットでこれを使用していることに驚いています。で指定されたID文字列SysLogHandlerはありません。これは、syslog APIを使用しないためです(一部のバージョン、IIRCではスレッドセーフの問題があります)。

于 2010-11-23T22:16:52.393 に答える
2

Python 2.7の場合、次のようなことができます。

class MySysLogHandler(logging.handlers.SysLogHandler):
    def __init__(self):
        super(MySysLogHandler, self).__init__(address='/dev/log')
    def emit(self, record):
        priority = self.encodePriority(self.facility, self.mapPriority(record.levelname))
        record.ident = "My[" + str(priority) + "]:"
        super(MySysLogHandler, self).emit(record)

handler = MySysLogHandler()
handler.formatter = logging.Formatter(fmt="%(ident)s %(levelname)s: %(message)s")
logging.root.addHandler(handler)
logging.info("hello world")

これにより、syslogで次のように生成されます。

Sep 3 16:28:53 hostname My[14]: INFO: hello world

于 2015-09-03T23:03:48.363 に答える