ログの表示、管理及び転送

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【4/18開催】VSCode Dev Containersで楽々開発環境構築祭り〜Python/Reactなどなど〜
Visual Studio Codeの拡張機能であるDev Containersを使ってReactとかPythonとかSpring Bootとかの開発環境をラクチンで構築する方法を紹介するイベントです。
https://tech-lab.connpass.com/event/311864/

こんにちは。サイオステクノロジー OSS サポート担当何敏欽です。

RHEL7/CentOS7 におけるログファイルの表示と管理は rsyslogd デーモンと journald デーモンによって制御されています。デフォルトでは rsyslogd と journald はシステム上で共存しています。

journal ログを不揮発ログに

journald デーモンは、トラブルシューティング用の主要ツールです。デフォルトでは、/run/log/journal にログを保存するように systemd ジャーナルが設定されています。ジャーナルデータベースのログは持続せず、システムを再起動するとなくなります。しかし、この設定は変更可能です。/var/log/journal にジャーナルログを永続的に保存するには以下の 2つ方法があります。

# 方法①:/var/log/journal ディレクトリを作成する
# mkdir -p /var/log/journal

# 方法②:/etc/systemd/journald.conf に Storage=persistent を設定する
# sed -i 's/#Storage=auto/Storage=persistent/' /etc/systemd/journald.conf

# 方法①、方法② の後サービスを再起動する 
# systemctl restart systemd-journald.service

ソースコードからログ出力の仕様を確認

journal ログと messages の両方にシステムログを記録したい場合、上記の設定を行なった後に rsyslog を再起動する必要があります。

# systemctl restart rsyslog.service

systemd と rsyslog のソースコードを確認するとわかりますが、仕様上 rsyslog を再起動しない場合は messages のログ出力が途絶えて、rsyslog を再起動すると messages に再度ログが出力されます。

rsyslog では、imjournal モジュールを使用して journald から情報を受け取ってログを出力しています。方法①、方法② で /var/log/journal に journal ログを保存するようになりますが、rsyslog はまだ以前の保存先を参照しているため、新しいメッセージを取得できません。

rsyslog を再起動すると imjournal モジュールも再起動し、journal の新しい保存先を検索して参照します。journald から情報を取得し始めると、messages に再度ログが出力されるようになります。

systemd-219-19.el7/src/journal/sd-journal.c
…
1508 static int add_search_paths(sd_journal *j) {
1509         int r;
1510         const char search_paths[] =  ← /run/log/journal と /var/log/journal の保存先を検索する。
1511                 "/run/log/journal\0"
1512                 "/var/log/journal\0";
1513         const char *p;
1514
1515         assert(j);
1516
1517         /* We ignore most errors here, since the idea is to only open
1518          * what's actually accessible, and ignore the rest. */
1519
1520         NULSTR_FOREACH(p, search_paths) {
1521                 r = add_root_directory(j, p);
1522                 if (r < 0 && r != -ENOENT) {
1523                         r = set_put_error(j, r);
1524                         if (r < 0)
1525                                 return r;
1526                 }
1527         }
1528
1529         return 0;
1530 }
…
1611 _public_ int sd_journal_open(sd_journal **ret, int flags) {
1612         sd_journal *j;
1613         int r;
1614
1615         assert_return(ret, -EINVAL);
1616         assert_return((flags & ~(SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_RUNTIME_ONLY|SD_JOURNAL_SYSTEM|SD_JOURNAL_CURRENT_USER)) == 0, -EINVAL);
1617
1618         j = journal_new(flags, NULL);
1619         if (!j)
1620                 return -ENOMEM;
1621
1622         r = add_search_paths(j);  ← sd_journal_open() が保存先を検索処理する。
1623         if (r < 0)
1624                 goto fail;
1625
1626         *ret = j;
1627         return 0;
1628
1629 fail:
1630         sd_journal_close(j);
1631
1632         return r;
1633 }
…

rsyslog では、起動後 imjournal プラグインを読み込む時のみ、sd_journal_open() が実行されます。

rsyslog-7.4.7-12.el7/plugins/imjournal/imjournal.c
675 /* open journal */
676 BEGINwillRun
677 CODESTARTwillRun
678         int ret;
679         ret = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
680         if (ret < 0) {
681                 iRet = RS_RET_IO_ERROR;
682         }
683 ENDwillRun

ログを永続的に保存する設定を行なった後、rsyslog を再起動したら、複数日分 (数ヶ月前とか) の古いメッセージがログファイルに再度書き込まれますので、ビックリするかもしれませんが、これも仕様通りの動作です。

現在 journald が保持する過去のメッセージを取得するかどうかは ImjournalIgnorePreviousMessages の設定で決まります。デフォルトでは、ImjournalIgnorePreviousMessages の設定が off であり、現在 journald が保持する過去のメッセージも含めてすべてのメッセー ジを取得する設定になっています。例えば、新しいメッセージのみをインポートしたい場合は ImjournalIgnorePreviousMessages を on に設定すれば、現在 journald が保持する過去のメッセージを無視して、新しいメッセージのみを取得します。

rsyslog を用いて信頼できるログ転送を実現

rsyslog は、reliable (信頼できる) シスログデーモンという意味で、高い信頼性を実現する次世代の syslog です。信頼性のある通信というのは、ログメッセージを確実に転送され、取りこぼしがないことです。

rsyslog は信頼性のあるログ転送を実現できる理由は、主に下記の 2点です。

  • TCP でログメッセージを転送できる。
  • 転送に失敗したログメッセージは転送先が再び到達可能になるまでローカルに保存される。

上記 2点目ですが、これは転送先が利用できない (ダウンしたなど) 場合にログメッセージが失われないように、転送アクションに対するアクションキュー (ActionQueue) を設定することで、転送先が復旧後に転送に失敗したログメッセージが再送されます。

仮に下記のような構成があるとします。

                   [転送元(10.1.100.100)]
                      ↓           ↓
                      ↓           ↓
                      ↓           ↓
                 [転送先_1]      [転送先_2]
               (10.1.100.110)   (10.1.100.120) 

rsyslog で転送先_1(10.1.100.110)、転送先_2(10.1.100.120) へログを転送する場合、以下のように転送先毎に ActionQueue 等の設定を行う必要があります。それぞれの転送は独立して行われるため、1つの転送先がダウンした場合でも他方への転送はブロックされず、転送先が復旧したらログメッセージが転送されるようになります。

転送元と転送先のログ転送設定について、インターネット上にたくさん情報があるため、ここでは記載しません。ActionQueue の設定は /etc/rsyslog.conf ファイルに直接記載するか、または /etc/rsyslog.d/ 配下に ActionQueue の設定内容のファイルを作成します。

# 転送ルール_1
$ ActionQueueType LinkedList #LinkedList インメモリーキューを有効にする。
$ ActionQueueFileName srvrfwd1 #ファイル名の設定、ディスクストレージを定義する。
$ ActionResumeRetryCount -1 #サーバが応答しない場合に接続を再試行する際 rsyslog がメッセージを破棄しないようにする。
$ ActionQueueSaveOnShutdown on #rsyslog がシャットダウンした場合、インメモリデータが保存される
*.* @@10.1.100.110:514 #受信されたすべてのメッセージをサーバに転送する。

# 転送ルール_2
$ActionQueueType LinkedList
$ActionQueueFileName example_fwd2
$ActionResumeRetryCount -1
$ActionQueueSaveOnShutdown on
*.* @@10.1.100.120:514

では、設定通りになるかを確認してみます。

転送先_1 がダウンしたとします。

[root@destination_1]# systemctl stop rsyslog

転送元からメッセージが出力されたとします。

[root@source]# logger "転送先_1がダウンしました。"

転送先_1 がダウンしたから、当然そのログメッセージが転送されません。

[root@destination_1]# tail -f /var/log/messages
(出力なし)

転送先_2 にログが出力されたことを確認できます。転送先_1 と転送先_2 はそれぞれの転送は独立して行われており、転送先_1 がダウンしても転送先_2 は影響されず、ログメッセージが転送されます。

[root@destination_2]# tail -f /var/log/messages
Jun  8 12:06:39 rhel7 root: 転送先_1がダウンしました。

転送先_1 が復旧したとします

[root@destination_1]# systemctl start rsyslog

転送先_1 に復旧前のログが出力されたことを確認できます。

[root@destination_1]# tail -f /var/log/messages
Jun  8 12:06:39 rhel7 root: 転送先_1がダウンしました。

設定通りの動作になっていますね。これこそ、確実な転送ですね。

以上で systemd ジャーナルでログの永続化を有効にする方法、ログ出力の仕様および rsyslog で複数のサーバへの確実な転送方法を説明しました。

アバター画像
About サイオステクノロジーの中の人 14 Articles
サイオステクノロジーで働く中の人です。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

2人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる