年末ですね!
体調を崩してしばらくブログを放置してましたが(※コロナではないです)
久しぶりに頑張って書きたいと思います◎
今回は前回の記事の続き(?)で、Linuxのログ管理について。
そもそもなぜログが必要なのか?は、前回の記事でまとめています。
なお確認環境は、CentOS8です。
もくじ
2.journaldについて ( 概要 / 設定ファイル / journal ログを直接確認する方法 )
3.rsyslogについて ( 概要 / 設定ファイル / モジュール / グローバルディレクティブ / ルール / おさらい )
1.Linuxでのログ管理のしくみ
Linux OSでは、syslogまたはrsyslogという機能によって、ログ管理が行われていることが多い。
syslogは古くからある機能で、rsyslogはsyslogのパワーアップ版である。
CentOS7や8では、rsyslogがデフォルト利用されている。
CentOS7や8のログ管理は、デフォルトで以下2つの仕組みにより成り立っている。
・ログ収集: journaldが担当
・jounarldが収集したログを、変形し、ログファイルに出力: rsyslogが担当
システムでイベント(システムの何らかの動き)が起きると、
journaldという名前のデーモンがそのイベントを逐一記録して、journalログとしてjournal databaseに蓄積する。
rsyslogdはjounal databaseの内容を確認し、あらかじめ決められたルールに従って、
記録されたログを整形・分類して、ログファイルに出力する。
なおryslogは、自身のサーバ(ローカルサーバ)でのjounalログを確認することはもちろん、
設定によっては別のサーバのjournalログも確認することができる。
さらに、整形・分類したログを自サーバ内のログファイルに出力する以外に、
他のサーバに出力するよう設定することもできる。
ログの集中管理をしたい時に便利である。
journaldとrsyslogについて、以下で詳しく仕組みを見ていきたい。
2.journaldについて
◎概要
1.Linuxでのログ管理のしくみ にも書いた通り、イベントを逐一記録する役割を果たすのが、
jounaldというデーモンである。
↓図のオレンジの部分の話
※ちなみに、journaldは、それ単体でログ出力・管理を行う機能も持っている。
ただし、Linuxの代表格であるRedHat系やUbunts系では、デフォルトで、
journaldでログ収集、rsyslog(またはsyslog)でログ出力・管理とし、ログ関連の機能を分業している。
そのため、この記事でも、journaldがログ収集というデフォルトの役割を果たすものとして見ていく。
CentOS8のデフォルトでは、
journaldはログ収集を行い、収集したログ(journalログ)を、バイナリ状態でjournal databaseに保管する。
journal databaseの実体、すなわち物理的なログの保管先は、
設定ファイル(後述)の「Storage」パラメータの値によって以下のように変わってくる。
Storage パラメータ値 |
保管先(journal databaseの在り処) | 備考 |
---|---|---|
auto |
/var/log/journal |
デフォルト設定 |
volatile | /run/log/journal | 保管先となるファイルが無い場合、 作成される |
persistent | /var/log/journal(無い場合作成) ただし書き込めなかった場合は /run/log/journal |
autoとの違いは、 /var/log/journalを作成するかどうか |
none | なし | jounarlログをすべて廃棄する設定。 よほどのことがない限り設定しない |
/run/log/journalと/var/log/journalが出てくるが、それらの違いについて確認しておきたい。
まず、/runディレクトリは揮発性ストレージとして利用される場所である。
従ってjournalログは、システムをシャットダウンすると消えてしまう。
しかもメモリが急に落ちると、最後らへんのログが最悪残らなかったりする…。
ただし、シャットダウンによりjournaldログが消えたとしても、
消える前にrsyslogできちんと処理された分までのログは、ログファイルとして残る。
一方、/var/log/journalは永続ファイルである。
そのため、ログローテーションやファイルサイズの最大値指定などをせずに放っておくと、ディスク容量の圧迫につながる。
以上を踏まえ、journalログの保管先は、
状況に応じて、/run配下と/var配下、どちらが良いか検討し、journaldの設定ファイルに明記しておくと良い。
◎設定ファイル
journaldの設定ファイルは以下に配置されている。(CentOS8の場合)
/etc/systemd/journald.conf
内容は以下の通り。コメントアウトされているが、記載値はすべてデフォルトで設定されている値となる。
(オレンジのコメント部分は筆者追記)
$ cat /etc/systemd/journald.conf
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See journald.conf(5) for details.
[Journal]
#Storage=auto //journaldログの保管先
#Compress=yes //journaldログを圧縮して保管するか
#Seal=yes //FSSの有効化設定
#SplitMode=uid //journalファイルをユーザ毎に作るか
#SyncIntervalSec=5m //journaldファイルへのログ同期までの時間
#RateLimitIntervalSec=30s //この間隔内にRateLimitBurstを超えてログがあると廃棄する
#RateLimitBurst=10000 //RateLimitIntervalSecの間隔内にこの値を超えてログがあると廃棄する
#SystemMaxUse= //journalが使えるディスク最大容量
#SystemKeepFree= //journalが他システムのために空けておくべき容量
#SystemMaxFileSize= //journalファイル(永続)の最大サイズ
#SystemMaxFiles=100 //journalファイル(永続)の最大数
#RuntimeMaxUse= //ランタイムのjournalが使えるメモリ容量
#RuntimeKeepFree= //ランタイムのjournalが他システムのために空けておくべき容量
#RuntimeMaxFileSize= //ランタイムのjournalファイルの最大サイズ
#RuntimeMaxFiles=100 //ランタイムのjournalファイルの最大数
#MaxRetentionSec= //journalエントリを廃棄するまでの最大時間(超えると廃棄する)
#MaxFileSec=1month //journalエントリを1つのjournalファイルに格納する最大時間
#ForwardToSyslog=no //syslogにjounalログを転送するか
#ForwardToKMsg=no //カーネルログバッファにjounalログを転送するか
#ForwardToConsole=no //コンソールにjounalログを転送するか
#ForwardToWall=yes //全ログインユーザにログを転送するか
#TTYPath=/dev/console //使用するコンソールのパス(ForwardToConsole=yesで有効)
#MaxLevelStore=debug //保管対象の最大ログレベル(デフォルトではdebug以上)
#MaxLevelSyslog=debug //syslogに転送する最大ログレベル(ForwardToSyslog=yesで有効)
#MaxLevelKMsg=notice //カーネルに転送する最大ログレベル(ForwardToKMsg=yesで有効)
#MaxLevelConsole=info //コンソールに転送する最大ログレベル(ForwardToConsole=yesで有効)
#MaxLevelWall=emerg //全ログインユーザに転送する最大ログレベル(ForwardToWall=yesで有効)
#LineMax=48K //最大ログ長
前述の通り、Storageの値は必要に応じて変更することを推奨する。
その他、基本的にはデフォルト値を変更する必要はないと思うが、
容量圧迫回避のためにSystemMaxUseやRuntimeMaxUseなどの値(上限値を設ける)変更、
同じく容量圧迫回避のためにdebugレベルのログを出さない(MaxLevelStore=infoなど)とすることは検討しても良いと思う。
パラメータのより詳細情報を知りたい方は以下をご参照のこと。(英語です)
https://www.freedesktop.org/software/systemd/man/journald.conf.html
パラメータを変更した後は、忘れずにjournaldを再起動して、変更を反映すること。
$ systemctl restart systemd-journald
◎journalログを直接確認する方法
journal databaseに格納されるログ情報は、バイナリであるため、catコマンドなどで直接中身を確認することはできない。
直接確認したい場合は、以下のコマンドを使う。
$ journalctl [オプション] [フィールド=値]
引数無しでもjournalログの確認は可能だが、そうするとすべてのjournalログ表示となり、膨大な量となるため、通常は引数を指定して確認する。
例えばこんな感じ。
--since、--untilオプションで、確認したいログの時間範囲を指定し、PRIORITYフィールドの値を5とすることで、noticeレベルのログだけを出力する設定としている。
$ journalctl --since="2020-12-13 10:00:00" --until="2020-12-13 10:30:00" PRIORITY=5
-- Logs begin at Sat 2020-11-21 19:10:26 JST, end at Sun 2020-12-13 10:26:50 JST. --
Dec 13 10:01:01 localhost run-parts[13869]: (/etc/cron.hourly) starting 0anacron
Dec 13 10:01:01 localhost run-parts[13875]: (/etc/cron.hourly) finished 0anacron
Dec 13 10:11:01 localhost anacron[13064]: Job `cron.weekly' started
Dec 13 10:11:01 localhost anacron[13064]: Job `cron.weekly' terminated
Dec 13 10:11:01 localhost anacron[13064]: Normal exit (2 jobs run)
3.rsyslogについて
◎概要
rsyslogdは、古くから利用されているログ管理デーモンsyslogdの拡張版であり、
各ログを分類・整形し、指定されたディレクトリにログファイルとして出力してくれる。
その他、1.Linuxでのログ管理のしくみ でも述べたように、外部サーバのログを出力するといったことも、rsyslogの仕組みで可能となっている。
↓図の色がついてる部分の話。
◎設定ファイル
rsyslogの設定は以下に記述する。
/etc/rsyslog.conf
CentOS8での設定ファイルのデフォルトは以下の通り。
設定ファイル内のコメントにも書かれているが、設定は3つ(モジュール、グローバルディレクティブ、ルール)のパートに分かれている。
$ # rsyslog configuration file
# For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html
# or latest version online at http://www.rsyslog.com/doc/rsyslog_conf.html
# If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html
#### MODULES ####
module(load="imuxsock" # provides support for local system logging (e.g. via logger command)
SysSock.Use="off") # Turn off message reception via local log socket;
# local messages are retrieved through imjournal now.
module(load="imjournal" # provides access to the systemd journal
StateFile="imjournal.state") # File to store the position in the journal
#module(load="imklog") # reads kernel messages (the same are read from journald)
#module(load"immark") # provides --MARK-- message capability
# Provides UDP syslog reception
# for parameters see http://www.rsyslog.com/doc/imudp.html
#module(load="imudp") # needs to be done just once
#input(type="imudp" port="514")
# Provides TCP syslog reception
# for parameters see http://www.rsyslog.com/doc/imtcp.html
#module(load="imtcp") # needs to be done just once
#input(type="imtcp" port="514")
#### GLOBAL DIRECTIVES ####
# Where to place auxiliary files
global(workDirectory="/var/lib/rsyslog")
# Use default timestamp format
module(load="builtin:omfile" Template="RSYSLOG_TraditionalFileFormat")
# Include all config files in /etc/rsyslog.d/
include(file="/etc/rsyslog.d/*.conf" mode="optional")
#### RULES ####
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.* /dev/console
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none /var/log/messages
# The authpriv file has restricted access.
authpriv.* /var/log/secure
# Log all the mail messages in one place.
mail.* -/var/log/maillog
# Log cron stuff
cron.* /var/log/cron
# Everybody gets emergency messages
*.emerg :omusrmsg:*
# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler
# Save boot messages also to boot.log
local7.* /var/log/boot.log
# ### sample forwarding rule ###
# 以降すべてコメントのため省略
モジュール、グローバルディレクティブ、ルールの各設定について、詳細は以下の通りである。
◎設定1:モジュール
rsyslogは最低限の機能だけが実装されている。
そのため、journaldや外部サーバなどからのログ収集、ファイルや外部サーバへのログ出力、
ログの解析、整形(マスキングやフォーマッティング等)、監視などの各機能の利用には、
モジュールと呼ばれるオプション機能を読み込む必要がある。
イメージ↓
設定できるモジュールは多数ある(公式参照)が、デフォルトでは以下の2つが追加されている。
・imjournal
・imuxsock
imjournalは、journalログを収集するためのモジュールであり、
このモジュールがロードされていることで、journald + rsyslogによるログ管理を実現できるようになっている。
imuxsockは、自サーバのログを、rsyslogで受け取れるようにするためのモジュール。
といってもjournaldがログ収集の役割を担ってくれるので、必要なければロードしなくても良い。
その他、設定ファイルには明示されていないが、以下のモジュールが最初からロードされている。
・omfile(ログをファイルに出力するためのモジュール)
・ompipe(ログを名前付きパイプ(fifos)に出力するためのモジュール)
(あと2つくらい最初からロードされているものがあったような気がしますが忘れました、ごめんなさい(-_-;))
モジュールを追加する書式は以下の通り。
$ module(load="モジュール名" [[パラメータ=値] ...])
上述の設定ファイル(デフォルト)から抜き出すと、例えばこのような感じ。
$ module(load="imjournal" StateFile="imjournal.state")
各モジュールにどのようなパラメータを渡せるかも、公式ドキュメントに細かく記載されているのでご参照のこと。
◎設定2:グローバルディレクティブ
rsyslog設定ファイルの2つ目のパート。
グローバルディレクティブは、簡単にいうと、rsyslogのログ管理全体に関わる設定ができるようになっている。
ただ、グローバルディレクティブが、具体的にどこまでの設定内容を示しているのかは、ドキュメント等によって異なっており、ぶっちゃけよく分からない。。(ご存じだったら教えてください)
参考までに…
・RedHatのドキュメント(redhat7)
global() で渡せるパラメータがグローバルディレクティブという書かれ方をしている。
(↓ドキュメントを抜粋。青字の部分注目)
・デフォルトの設定内容
先ほど出したデフォルトの設定内容の一部を再掲すると、「global()」で渡せるパラメータの他、module()やらinclude()やらが書かれている。前述のRedHatドキュメントとは矛盾しているように見える…。
#### GLOBAL DIRECTIVES ####
# Where to place auxiliary files
global(workDirectory="/var/lib/rsyslog") # ←global()の部分は確かにあるが…
# Use default timestamp format # ↓最初からロードされているomfileモジュールの設定
module(load="builtin:omfile" Template="RSYSLOG_TraditionalFileFormat")
# Include all config files in /etc/rsyslog.d/ # ↓設定ファイルとして別ファイルも含む記述あり
include(file="/etc/rsyslog.d/*.conf" mode="optional")
どこまでがグローバルディレクティブなのか謎(^-^;
・rsyslogのドキュメント
「global()」は、RainerScriptというやつに含まれてる模様。スクリプトで記述できる特別なオブジェクトのような…(なんだそれ)
ちなみにRainerScriptのさらに大きなくくりは、Configuration(設定)となっていた。
(ドキュメントの目次を抜粋↓)
・・・ということで、何をもってグローバルディレクティブというのかは曖昧だが、
rsyslogのログ管理全体に関わる設定というふうに考えておけば、ひとまずOKだと思う。(たぶん)
いずれにせよ、「global()」のくくりで、各種パラメータを渡して、rsyslog全体に関する設定が出来るのは事実。
「global()」でどんなパラメータを渡せるかは、rsyslogのドキュメントに一覧があるのでご参照のこと。
◎設定3:ルール(ファシリティとプライオリティとアクション)
rsyslogの設定3つめ、ルールについて。
ルールとは、何に関するログを、どれくらい細かいレベルで、どこに出力するかという話。
例えば、カーネルに関するログを、infoレベル以上まで、/var/log/kernel.logに出力したい場合、
/etc/rsyslog.conf に以下の通り記載する。
kern.info /var/log/kernel.log
# 何に関するログか.ログレベル 出力先
これらの各設定内容について、以下のように名前がついている。
内容 | 名称 | 例の対象箇所 |
---|---|---|
何に関するログか | ファシリティ | kern |
ログレベル | プライオリティ(重要度、優先度) | info |
出力先 | アクション | /var/log/kernel.log |
アクションに設定する値は任意だが、ファシリティ、プライオリティの値は、rsyslogによって予約されている。
ファシリティとプライオリティの一覧は「rsyslog ファシリティ プライオリティ」とかでググれば、すぐにわかると思うのでここでは割愛…。
ちなみに、、
ファシリティ、プライオリティには、正規表現「*」も設定することができる。
例えば以下のようにした場合、userに関するログであれば、どのようなプライオリティであっても出力する設定となる。
user.* /var/log/user.log
また、ファシリティは複数を明示指定することもできる。
以下のようにした場合、uucpに関するログと、newsに関するログの、それぞれcrit以上のレベルを出力する設定となる。
uucp,news.crit /var/log/spooler
◎ということで、おさらい
rsyslogに関して長くなったのでまとめておく。
・rsyslogのログの収集先は、デフォルトではローカルのjournaldデータベースとなっているが、
モジュールの読み込み次第では、journald以外からも収集することができる。
・モジュールは、ログの収集だけでなく、出力先やログメッセージの整形などなど、拡張機能を多く提供しており、必要な機能をロードして利用することができる。
・グローバルディレクティブでは、rsyslog全般に関する設定を行う。
・ファシリティ×プライオリティ×アクションで、ログの出力ルールを決めることができる。
以上を踏まえて、再度、rsyslogの設定ファイルのデフォルト値を見て頂ければ、ある程度意味がつかめるはず。
図も再掲しておく。
4.ログローテーションとは
最後に。
ログファイルのローテーションについてもちょっとだけ…。
※ここまで説明してきたjournald + rsyslogdによるログ管理とは別の話となる。
rsyslogでログメッセージをログファイルに出力する場合、
何もせず放っておくと、過去のログが大量に残り、ディスク容量を圧迫してしまう。
そのため一定のタイミングで過去のログを削除し、不要なログがどんどん蓄積されることを防ぐ仕組みがある。この仕組みをログローテーションという。
Linuxではlogrotateコマンドとcron(ジョブ管理)の仕組みを利用したログローテーションが可能となっている。
…ただ記事が長くなってきたので、ローテーションに関しては次回記事とします!