/dev/logに書き込むとき、syslog()はどの形式を使用しますか?

/dev/logに書き込むとき、syslog()はどの形式を使用しますか?

私の興味は主にプログラミングに焦点を当てているので、もともとこの記事をStackOverflowに投稿したかったのですが、読んだ後は歴史タグ(そしてそれがつながる質問)、私Softwareengineering.seに投稿してください。実用的な/今日の「ソフトウェアエンジニアリング」の側面について深く理解してください。しかし、私の質問の根本的に歴史的な性格は避けられないので、今はここにあります。


現在、Linuxでロギングがどのように機能するかを学んでいますが、扱っていないような実装の詳細のために少し混乱しています。RFC 5424またはRFC 3164:データの書き込みに使用される形式です/dev/log

簡単に言うと:私はa)「形式/dev/log」とは何ですか、b)その意味が正式に指定されている場所を決定しようとしています。 RFCまたは他の引用可能な参照を識別できません。特定のルールを実装するコードにすぎず、韻や理由はありません。

syslog()他のロギング戦略(stdout / stderrおよび/またはファイルへの書き込み、他の種類のログサーバーへの送信など)と比較して長所と短所を評価している間、最初はこのトピックに興味がありましたが、ある瞬間は完全に自信がないことに気づきました。 「/dev/log形式」がより大きい映像にいかに/どこに当てはまるか。 syslog形式またはプロトコルに関するすべての質問は、RFCについて議論し、syslog()データがsyslogサーバーに送信され送信される方法を制御する規則を完全に無視します。

この「フォーマット」(?)を使用して毎日数兆のログメッセージが記録されている間、UNIXのこの特定の部分は、もはや存在しないかのように木工業の中に完全に消えたようです。

したがって、この質問は、この特定の詳細を明確にし、フォーマットを説明し、引用可能な参考文献を特定する試みです。


ログ行は、許可されるには非常に特定の方法でフォーマットする必要があるようです(私の場合はsystemd-journald - 最初に優先順位/施設情報(に含まれています<>)、それから一般的に使用されるように見える非常に特定の形式のタイムスタンプです。商標、次のメッセージは次のとおりです。

#ロガー - こんにちは
<13> 3月5日 14:04:11 i336: こんにちは

#Journalctl -qn1 -o 短い ISO 精密
2021-03-05T14:04:11.430504+1100 h0nk i336[2505]: こんにちは
#logger-s-tタグこんにちは
<13>3月5日 14:04:37商標:こんにちは

#Journalctl -qn1 -o 短い ISO 精密
2021-03-05T14:04:37.050891+1100 h0nk商標[3151]:こんにちは
#logger-s-tタグ -私こんにちは
<13>3月5日 14:04:40商標[3248]:こんにちは

#Journalctl -qn1 -o 短い ISO 精密
2021-03-05T14:04:40.278630+1100 h0nk商標[3248]:こんにちは

(stderrに送信する内容をコピーし、-sラベルの使用を私のユーザー名から私が指定したように変更し、PIDを追加します。)logger-t taglogger-i

提供されたタイムスタンプとPID(提供されている場合)を解析して削除し、この情報自体を決定することを確認しましたsystemd-journald(これがPIDが常に存在する理由であり、short-iso-precise提供されていない場合はミリ秒を要求できる理由です)。

#eco'<13>1月1日 00:00:00テスト[1234]:こんにちは'| ncat -uU /dev/log

#journalctl-qn1
3月5日 14:06:12ㅋㅋㅋテスト[5593]:こんにちは

#Journalctl -qn1 -o 短い ISO 精密
2021-03-05T14:06:12.538712+1100 h0nkテスト[5593]: こんにちは

セキュリティの観点からは、これは意味があります。

しかし、、私が次から外れたとき少しフォーマットから

<p>Mmm _d HH:MM:SS tagwithnospaces: message

これはすべてが非常に速く悪くなります。

loggerUDPまたはTCPを介してsyslogサーバーに接続するための外観とオプション。データの送信時にこれらのオプションを使用すると、悲惨な結果が生じる可能性があります。--rfc5424--rfc3164/dev/log

RFC 5424形式(ヘッダーは次に定義されています)セクション6) 最初から爆発しました。

# logger -s --rfc5424 hi
<13>1 2021-03-05T15:05:04.773304+11:00 h0nk i336 - - [timeQuality tzKnown="1" isSynced="1" syncAccuracy="648500"] hi

# journalctl -qn1 -o short-iso-precise
2021-03-05T15:05:04.773384+1100 h0nk logger[29306]: 1 2021-03-05T15:05:04.773304+11:00 h0nk i336 - - [timeQuality tzKnown="1" isSynced="1" syncAccuracy="648500"] hi

奇妙なことに、RFC 3164フォーマット(セクション4.1.2)は次のように似ています...どのlogger形式を使用してもいいえRFCオプションを指定してRFC 3164のホスト名フィールドを追加するだけで問題が発生する可能性があります。

#logger-s --rfc3164 こんにちは
<13> 3月5日 14:20:51 h0nk i336: こんにちは

#Journalctl -qn1 -o 短い ISO 精密
2021-03-05T14:20:51.638518+1100 h0nk 不明[27148]:h0nk i336:こんにちは
                                     ^ああ

<nnn>追加の質問:RFC形式は、ステータス情報(「緊急」、「緊急」など)が常に正しく送信されるように、主な優先順位フィールドを維持するようです。そうですか?

日付自体も特に敏感な値のようです。少し変更しても、すぐにsystemd-journald行全体が破損していると見なされます。

#echo '<13> 1月1日00:00:00 test [1234]:こんにちは' |
               ^2つのスペース
#Journalctl -qn1 -o 短い ISO 精密
2021-03-05T14:17:04.484309+1100 h0nkテスト[21585]: こんにちは
#echo '<13> 1月1日00:00:00 test [1234]:こんにちは' |
               ^宇宙
#Journalctl -qn1 -o 短い ISO 精密
2021-03-05T14:06:23.414986+1100 h0nk ncat[5877]: 1月1日 00:00:00 テスト[1234]: こんにちは

興味深いことに、BusyBoxのsyslogdは日付(syslog.c:829)特定の文字の位置について正確でハードコーディングされた仮定をするために:

/* 1月18日 00:11:22 ニュース... */
/* 01234567890123456 */
if (len >= 16 && msg[3] == ' ' && msg[6] == ' '
 && メッセージ[9] == ':' && メッセージ[12] == ':' && メッセージ[15] == ' '
){

(Busybox syslogdにも15文字の長さがあります。L286.)

なぜ日付を注意深く指定するのか疑問に思います。

glibcの実装を見つけましたsyslog()syslog.c:223)洞察力のある研究:

  • %h %e %T""形式を使用してください。

    • %h-> %b; %b= ロケールによる略月名
    • %e=日付、前にスペースを含める
    • %T=時間は同じです%H:%M:%S
    • タイムスタンプの後の末尾のスペースはmsg[15] == ' 'BusyBox syslogd の check(!) と一致します (完全に気まぐれ)。
  • これは(glibc-internal?)関数を使用しますstrftime_l()時間.h:101)、「グローバルロケールの代わりに提供されたロケールから情報を取得する";strftime_l()ここに渡されます_nl_C_locobj_ptr(で定義されています)locale.h:17)、これは内部ポインタです_nl_C_locobj(で定義されています)。xlocale.c:34)Cロケール定義(内部)glibcへのグローバル参照。

logger呼び出されるモードに応じて、さまざまなヘッダ書式設定機能が使用されます。syslog_rfc3164_header()syslog_rfc5424_header()syslog_local_header()。重要な部分syslog_local_header()は次のとおりです。

if(ctl->pid)
        snprintf(pid, sizeof(pid), "[%d]", ctl->pid);
...
xasprintf(&ctl->hdr, "<%d>%s %s%s: ", ctl->pri, rfc3164_current_time(),
        ctl->ラベル、pid);

この形式を再利用してください。優先順位、時間、タグ、PID。

rfc3164_current_time()glibcロケールダンスのポータブル代替として、短縮された英語の月名のリストを囲むgettimeofday()ラッパーです。localtime()

RFC 3164の日付書式が「デフォルト」「書式」で使用される書式と非常に似ていることを考慮すると、日付書式/dev/log設定機能を再利用することが合理的です。しかし、全体的に「ネイティブ」形式はまだRFC 3164形式とは異なるため、これが再利用できる唯一の形式であることは注目に値します。

Q:/dev/logこの形式の起源は何ですか?

logger「ネイティブ」正規化は、/dev/logWeb/RFC 形式とは異なる名前で形式を明確にするのに最も近い方法です。私はこの区別を命名しようとする他の場所を見つけることができず、単にそれを使用します。

他のsyslogデーモン(rsyslog、syslog-ngなど)をテストしておらず、それらがRFC形式のテキスト行を受け入れるかどうかはわかりませんが、/dev/logBusyBoxの精度を考慮すると驚くことはありません。一種の違反ですね…

...しかし、同時にこの行動を最初に違反として定義する標準または方針は何ですか?

私の印象は、これが「慣習による」標準であり、実際に使用されている正確な特定のパーサーによって明示的な承認が回避されたことです。

この仮定は正しいですか?

気づく私は偶然偶然発見した/dev/logこれはファイル自体の意味に関する質問に対する良い答えです。、これはchrootで実行されているアプリケーションが相対パス/dev/logで送信できることを示します。良い指摘です。/dev/log正しい名前を指定する必要があるため、「形式」を非常によく使用します。

答え1

おそらくman rsyslogd重要なヒントが与えられます:

      /dev/log
              The  Unix  domain socket to from where local syslog messages are
              read.

ノート"地元のsyslogメッセージ"。これはRFC 3164のHOSTNAMEがありませんが、残りはその形式に従うことを示します。また、syslogデーモンはメッセージを記録する前に欠落しているホスト名フィールドを追加するようです。

アプリケーションがsyslogメッセージを生成している場合は、次のstrace内容が表示されます(からstrace -f logger -t demo foobar)。

...
socket(AF_UNIX, SOCK_DGRAM, 0)          = 3
connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 110) = 0
...
sendto(3, "<13>Apr 28 11:34:21 demo: foobar", ...) = 32
...

正確な効果systemd-journaldは文書化されておらず、おそらく標準ではないでしょう(Lennart Poetteringがメーリングリストのトピック「Q:Non-ASCII in syslog」で認めたように)。

関連情報