Linux システムログ syslog

LPIC 学習記録として

# はじめに

Linux には **`syslog`** というログに関するプロトコルを実装したプログラムが複数存在する。

- [`syslogd`](#syslogd)
- [`rsyslog`](#rsyslog)
- [`syslog-ng`](#syslog-ng)
- [`systemd-journald`](#systemd-journald)

これらのプログラムは [デーモン](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9--%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3) として稼働し、アプリケーションは C 言語の [`glibc`](https://qiita.com/AsahinaKei/items/22d9fae93cabfbf137ee#%E6%A8%99%E6%BA%96c%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA) のログ送信関数 `syslog()` を使用してデーモンに対してメッセージを送信する。

また、`systemd` を使用する環境では、`libsystemd` に含まれる `sd_journal_send()` 関数を使用することで、ログをネイティブに `systemd-journald` に送ることができる。

「syslog」 という言葉は「仕様（プロトコル）名」「関数名」「デーモン」「実装名」 として使われているため、単に `syslog` といった場合、何を指しているのかが分かりづらいことがある。

アプリケーションから送信されるログには以下の情報が含まれている。

- [ファシリティ](#ファシリティ)
- [プライオリティ](#プライオリティ)
- [出力先](#出力先)

`ファシリティ.プライオリティ` で構成される設定フィールドは **セレクタフィールド**、`出力先` 設定は **アクションフィールド** と呼ばれる。

## ファシリティ
facility

ログメッセージの生成元。

| ファシリティ | 内容 | ファシリティコード |
|:-|:-|:-|
| `kern` | [カーネル](https://qiita.com/AsahinaKei/items/22d9fae93cabfbf137ee#%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB) | `0` |
| `user` | ユーザーアプリケーション | `1` |
| `mail` | メールシステム | `2` |
| `daemon` | [デーモン](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9--%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3) | `3` |
| `auth` | 認証関連 | `4` |
| `cron` | [`cron`](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#cron) | `9` |
| `local0` ~ `local7` | ユーザ定義 | `16` ~ `23` |

## プライオリティ

ログの優先度、重要度。

| プライオリティ | 内容 |
|:-|:-|
| `emerg` | 緊急事態、システム使用不能（emergency） |
| `alert` | 即時対応が必要 |
| `crit` | 重大な事態（critical） |
| `err` | 一般的なエラー（error） |
| `warning` | 警告 |
| `notice` | 特記事項、通知 |
| `info` | 通常の情報（information） |
| `debug` | デバッグ情報 |
| `none` | **記録しない** |

## 出力先

ログの出力先ファイル（出力先が [デバイスファイル](https://qiita.com/AsahinaKei/items/09ee7ce55b1a0be01ff0#%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB) である場合もある）。

| 出力先 | 設定値 |
|:-|:-|
| `/var/log/messages` | ログファイル |
| `/dev/tty1` ~ `/dev/tty6` | [コンソール](https://qiita.com/AsahinaKei/items/22d9fae93cabfbf137ee#%E7%8F%BE%E4%BB%A3%E3%81%AE%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E4%BB%AE%E6%83%B3%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%ABtty) |
| `@ホスト名` | ホストに対して [UDP](https://qiita.com/AsahinaKei/items/627f0076fecc107ac686#udp) 送信 |
| `@@ホスト名` | ホストに対して [TCP](https://qiita.com/AsahinaKei/items/627f0076fecc107ac686#tcp) 送信 |
| `*` | ログイン中のすべてのユーザの端末 |
| `ユーザ名` | 指定されたユーザの端末 |

# `syslogd`

古い `syslog` の実装プログラム。

現在ではほとんどの Linux ディストリビューションで使用されていない。構成が非常にシンプル。

## `/etc/syslog.conf`

`syslogd` の設定ファイル。

# `rsyslog`
rocket-fast System for log processing

`syslogd` の後継版。

TCP でログを別のサーバに転送することができる。

## `/etc/rsyslog.conf`

`rsyslog` に関する設定ファイル。

以下に関する設定を行うことができる。

- モジュール
    - 各種機能をプラグインモジュールとして拡張できる
- [ファシリティ](#ファシリティ)
- [プライオリティ](#プライオリティ)
- [出力先](#出力先)

```text:/etc/rsyslog.conf
ファシリティ.プライオリティ 出力先
```

`;` を使用することで、同じ `出力先` に対して複数の組み合わせを列挙することができる。

```text:複数列挙
ファシリティ1.プライオリティ1;ファシリティ2.プライオリティ2 出力先
```

`*` を使用することで「全て」を対象にすることもできる。

```text:* を使用する
ファシリティ.* 出力先
*.プライオリティ 出力先
```

`none` を使用することで特定の組み合わせを除外することもできる。

```text:特定の組み合わせを除外する
*.*;ファシリティ.プライオリティ.none 出力先
```

<details><summary>/etc/rsyslog.conf</summary>

```text:/etc/rsyslog.conf（例）
# /etc/rsyslog.conf configuration file for rsyslog
#
# For more information install rsyslog-doc and see
# /usr/share/doc/rsyslog-doc/html/configuration/index.html
#
# Default logging rules can be found in /etc/rsyslog.d/50-default.conf


#################
#### MODULES ####
#################

module(load="imuxsock") # provides support for local system logging
#module(load="immark")  # provides --MARK-- message capability

# provides UDP syslog reception
#module(load="imudp")
#input(type="imudp" port="514")

# provides TCP syslog reception
#module(load="imtcp")
#input(type="imtcp" port="514")

# provides kernel logging support and enable non-kernel klog messages
module(load="imklog" permitnonkernelfacility="on")

###########################
#### GLOBAL DIRECTIVES ####
###########################

# Filter duplicated messages
$RepeatedMsgReduction on

#
# Set the default permissions for all log files.
#
$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
$PrivDropToUser syslog
$PrivDropToGroup syslog

#
# Where to place spool and state files
#
$WorkDirectory /var/spool/rsyslog

#
# Include all config files in /etc/rsyslog.d/
#
$IncludeConfig /etc/rsyslog.d/*.conf
```
</details>

設定ファイルを編集した場合、[`$ systemctl`](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#-systemctl) によって `rsyslog.service` を再起動させる必要がある。

```console:rsyslog.service の再起動
$ systemctl restart rsyslog
```

:::note info
編集後はサービスの再起動が必要
:::

## `$ logger`

`rsyslog` にログを送信することができるコマンド。

`/etc/rsyslog.conf` の設定確認をすることもできる。 

```console:メッセージを syslog に送信する
$ logger メッセージ
```

```console:ファシリティ、プライオリティを指定してメッセージを syslog に送信する
$ logger -p ファシリティ.プライオリティ メッセージ
```


# `syslog-ng`
Syslog Next Generation

`rsyslog` 同様に、`syslogd` の後継版として開発されたデーモン。

`rsyslog` よりも柔軟な設定が可能で **大規模なシステムに向いている**。高度なフィルタ機能を持ち、メッセージの内容、送信元IP、ログレベル、ファシリティなど複雑な条件でログを分けられる。

多彩な出力先を設定することができる（ファイル、データベース、TCP/UDP ソケット、リモートサーバ）。また、出力形式として JSON や CSV が使用できる。


## `/etc/syslog-ng/syslog-ng.conf`

`syslog-ng` の設定ファイル。



# `systemd-journald`

[`systemd`](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#systemd) が提供する機能の一つ。

デーモンとして稼働し、収集されたログは **バイナリデータ** として保存される。

保村されるログは **ジャーナル** と表現される。

## `/etc/systemd/journald.conf`

`systemd-journald` の設定ファイル。

```text:/etc/systemd/journald.conf
項目=値
```

設定を編集した場合、[`$ systemctl`](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#-systemctl) によって `systemd-journald` を再起動させる必要がある。

```console:systemd-journald の再起動
$ systemctl restart systemd-journald
```


<details><summary>/etc/systemd/journald.conf</summary>

```text:/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. Local configuration
# should be created by either modifying this file (or a copy of it placed in
# /etc/ if the original file is shipped in /usr/), or by creating "drop-ins" in
# the /etc/systemd/journald.conf.d/ directory. The latter is generally
# recommended. Defaults can be restored by simply deleting the main
# configuration file and all drop-ins located in /etc/.
#
# Use 'systemd-analyze cat-config systemd/journald.conf' to display the full config.
#
# See journald.conf(5) for details.

[Journal]
#Storage=auto
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitIntervalSec=30s
#RateLimitBurst=10000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
#SystemMaxFiles=100
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMaxFiles=100
#MaxRetentionSec=
#MaxFileSec=1month
#ForwardToSyslog=no
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes
#TTYPath=/dev/console
#MaxLevelStore=debug
#MaxLevelSyslog=debug
#MaxLevelKMsg=notice
#MaxLevelConsole=info
#MaxLevelWall=emerg
#LineMax=48K
#ReadKMsg=yes
#Audit=yes
```
</details>

## `/var/log/journal/`

`systemd` が保存するジャーナルの保存先。

`/etc/systemd/journald.conf` の設定が `Storage=persistent` の場合に使用され、`persistent` が指定されたログは **永続的に保存** される（シャットダウン後も残る）。

```text:/etc/systemd/journald.conf
Storage=persistent
```

`Storage` が `auto` で設定されている場合、`/run/log/journal/` が使用される。その場合、ログはメモリに保存され **一時的な保存** になる。



## `/run/log/journal/`

`systemd` が保存するジャーナルの保存先。

`/etc/systemd/journald.conf` の設定項目 `Storage` が `auto` で設定されている場合に使用される。

```text:/etc/systemd/journald.conf
Storage=auto
```

ストレージ（ハードディスク）上ではなく **メモリ上へ保存される** ため、`/run/log/journal/` に保存されたジャーナルはシャットダウンにより失われる。

## `$ systemd-cat`

`systemd-journald` にジャーナルを送信することができるコマンド。

```console:コマンドの実行結果をジャーナルに書き込む
$ systemd-cat コマンド
```

```console:標準入力をジャーナルに書き込む
$ コマンド | systemd-cat
```

```console:プライオリティを指定してジャーナルに書き込む
$ systemd-cat -p プライオリティ
$ systemd-cat --priority=プライオリティ
```
※ [プライオリティ](#プライオリティ)


## `$ journalctl`

`systemd-jounald` デーモンが収集したバイナリ形式のジャーナルを表示するコマンド。

`rsyslog` や `syslog-ng` が保存したテキスト形式のログは表示できない。

```console:ジャーナルを確認する
$ journalctl
```

```console:ジャーナルを追加説明付き（-x）で確認する
$ journalctl -xe   # -e で less によって最後のジャーナルに移動するので、最新行から見れる
```

```console:ファシリティ を指定する
$ journalctl SYSLOG_FACILITY=ファシリティコード
```
※ [ファシリティコード](#)

```console:プライオリティ を指定する
$ journalctl -p プライオリティ
$ journalctl --priority=プライオリティ
```

```console:Unit を指定する
$ journalctl -u ユニット
```
※ [ユニット](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#%E3%83%A6%E3%83%8B%E3%83%83%E3%83%88)

```console:日時 を指定する
$ journalctl --since "YYYY-MM-dd HH:mm:ss" --until="YYYY-MM-dd HH:mm:ss"
```


# ログローテート

ログファイルを定期的に整理したり管理したりするための一連の処理。

`$ logrotate` によって手動実行することもできるが、通常は [`cron`](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#cron) や [`systemd`](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#systemd) などによって自動化されている。具体的には `cron.daily` や `systemd timer` により 1日1回自動で実行されることが多い。

## `/etc/logrotate.conf`

ログローテーションの設定ファイル。

ログファイルが肥大化しないようにし、一定期間で保存・圧縮・削除するルールを記述する。

```text:グローバル設定（全ログに共通のルール）
ディレクティブ
```

```text:例（グローバル設定）
weekly              # ログを毎週ローテート
rotate 4            # ローテートファイルは4世代まで保持
create              # ローテート後に新しいログファイルを作成
compress            # ローテートされたログを圧縮（gzip）
include /etc/logrotate.d  # 個別設定をこのディレクトリから読み込む
```

```text:特定のログファイルに対するルール
対象ログファイルパス {
    ディレクティブ
}
```

```text:例（特定のログファイルに対するルール）
/var/log/sample.log {
    dayly
    create 0600 root root
}
```

| ディレクティブ | 説明 |
|:-|:-|
| `daily` / `weekly` / `monthly` | ローテートの頻度 |
| `rotate 数値` | 保持するログの世代数（削除は古い順に実行される） |
| `compress` | ローテートされたログを [gzip](https://qiita.com/AsahinaKei/items/c8fe67bd4c37af96f2d9#-gzip---bzip2---xz) 圧縮する |
| `nocompress` | 圧縮しない |
| `create 権限 所有者 所有グループ` | ローテート後に新規ファイルを作成（ファイル権限も指定可） |
| `missingok` | 書き込み先ログファイルが存在しなくてもエラーにしない |
| `notifempty` | 空ファイルならローテートしない |
| `ifempty` | 空でもローテートする（デフォルト） |
| `delaycompress` | 前回のローテート分だけ圧縮を遅らせる |
| `dateext` | ローテートファイル名に日付をつける |
| `postrotate / endscript` | ローテート後に実行するスクリプト（例: サービス再起動） |


<details><summary>/etc/logrotate.conf</summary>

```text:/etc/logrotate.conf
# see "man logrotate" for details

# global options do not affect preceding include directives

# rotate log files weekly
weekly

# use the adm group by default, since this is the owning group
# of /var/log/.
su root adm

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
#dateext

# uncomment this if you want your log files compressed
#compress

# packages drop log rotation information into this directory
include /etc/logrotate.d

# system-specific logs may also be configured here.

```

</details>

## `/etc/logrotate.d/`

個別の [サービス](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9--%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3) の設定ファイルを置くディレクトリ。

## `$ logrotate`

```console:ログローテートを実行する
$ logrotate 設定ファイル
```

```console:ログローテートのシミュレーション（表示のみで実行はしない）を行う（debug）
$ logrotate -d 設定ファイル
```

`$ logrotate` コマンドは通常 [`/etc/cron.daily/logratate`](https://qiita.com/AsahinaKei/items/e354a3814639aeac4138#%E9%96%A2%E9%80%A3%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA) によって 1 日 1 回実行される。

# テキスト操作

ログ閲覧時に利用することがある。

https://qiita.com/AsahinaKei/items/161674f16b6c849fbf17