Dockerのlogdriverを全て試してログの保存方法を考える



## はじめに

dockerを運用していると、docker logコマンドでトラブルシューティングをする機会が多いと思います。開発環境や、少人数の環境ではdocker logコマンドで十分ですが、

- 複数のコンテナで構成されたアプリケーション全体の流れを追いたい
- 複数のホストでコンテナを利用している
- 法令、コンプライアンスでログの保存期間が決まっている場合

などのケースでは、課題が残ります。

**dockerのログはlog driverを変更することで出力先を指定できます。** 想像しやすい例だと`syslog driver`でしょうか。

[公式ドキュメント](https://docs.docker.jp/v19.03/config/container/logging/configure.html)には、サポートされているlog driverの一覧があります。

今回は公式サポートの **ドライバーすべてを試して** 設定方法、使用感をお伝えしたいと思います。

| ドライバ                                                     | 説明                                                         |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| `none`                                                       | コンテナに対するログを記録せず、 `docker logs` は利用できなくなる |
| [local](https://docs.docker.com/config/containers/logging/local/) | 独自のファイル方式で保存され、ドライバの中で一番オーバーヘッドが少ない |
| [json-file](https://docs.docker.com/config/containers/logging/json-file/) | JSON 形式で保存され、**デフォルトのドライバー**              |
| [syslog](https://docs.docker.com/config/containers/logging/syslog/) | Syslogサーバへ転送する                                       |
| [journald](https://docs.docker.com/config/containers/logging/journald/) | ホストマシンのjournaldに保存する                             |
| [gelf](https://docs.docker.com/config/containers/logging/gelf/) | Graylog、 Logstach などのような Graylog Extended Log Format (GELF) エンドポイントに記録 |
| [fluentd](https://docs.docker.com/config/containers/logging/fluentd/) | ログメッセージを `fluentd` に記録（forward input）する       |
| [awslogs](https://docs.docker.com/config/containers/logging/awslogs/) | ログメッセージを Amazon CloudWatch Logs に記録する           |
| [splunk](https://docs.docker.com/config/containers/logging/splunk/) | HTTP Event Collector を使い、 `splunk` にログメッセージを記録する |
| [etwlogs](https://docs.docker.com/config/containers/logging/etwlogs/) | Event Tracing for Windows (ETW) events としてログメッセージを記録する（Windows） |
| [gcplogs](https://docs.docker.com/config/containers/logging/gcplogs/) | Google Cloud Platform (GCP) ロギングにログメッセージを記録する |

## ドライバーの制限

これから紹介するdriverですが、**一部を除き変更すると`docker logs`コマンドでのログが確認できなくなります**。Docker Enterprise のユーザは "dual logging" を利用できるため、`docker logs`コマンドでの確認と、ドライバーへの送信両方使えるドライバーが多いです。

表. ドライバ変更と`docker logs`が両立できるドライバー

|            | Docker Community Engine(無料) | Docker Enterprise(有償) |
| ---------- | ----------------------------- | ----------------------- |
| local      | 〇                            | 〇                      |
| json-file  | 〇                            | 〇                      |
| journald   | 〇                            | 〇                      |
| syslog     | ×→〇 ※2023/10/27検証          | 〇                      |
| gelf       | ×→〇 ※2023/10/27検証          | 〇                      |
| fluentd    | ×→〇 ※2023/10/27検証          | 〇                      |
| awslogs    | ×→〇 ※2023/10/27検証          | 〇                      |
| splunk     | ×→〇 ※2023/10/27検証          | 〇                      |
| etwlogs    | × ※2023/10/27未検証           | 〇                      |
| gcplogs    | ×→〇 ※2023/10/27検証                        | 〇                      |



## ドライバーの設定方法

log driverは以下の通り、個別に設定する方法と、システム全体で指定する方法があります。

1. docker composeファイルに記述（個別）
2. docker runコマンドで起動時に指定（個別）
3. docker daemon.json設定ファイルに記述（システム全体）

以下に指定方法をそれぞれ示します。それぞれ単語の省略、単数複数など若干変換が必要ですが、基本的にはすべて同じように指定ができます。

### 指定方法（compose）

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - 0.0.0.0:30080:80
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      # - ./conf.d:/etc/nginx/conf.d
    logging:
      driver: json-file
      options:
        max-file: '1'
        max-size: 3m
```

### 指定方法（docker run）

```bash
$ docker run --rm  \
  -p 0.0.0.0:30080:80 \
  -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  nginx
```

### 指定方法（システム全体）

ファイルを編集　`sudo vi /etc/docker/daemon.json`

```json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
```

**記事の以降ではcomposeの`logging`セクションのみ記載します。**

## ドライバーの優先順位

それぞれの設定が優先順位は以下の通りです。

1. runやcomposeの個別の指定
2. docker daemon.jsonによる全体の指定
3. デフォルト値 (現在は: json-file)

daemon.jsonで指定したシステム全体の設定をrunやcomposeの個別指定は上書きできます。

同じドライバーを指定することもできるので、何も設定しない場合、全体設定でrsyslogのOOファシリティ、個別に設定してrsyslogのXXファシリティを指定するなどもできます。

## 検証環境

検証環境は、docker composeを用いて構築したNginx Webサーバです。そのNginxコンテナのログを様々な方法で取得し検証していきます。

dockerのインストールは[公式ドキュメント](https://matsuand.github.io/docs.docker.jp.onthefly/engine/install/ubuntu/)に従いました。本記事では、Ubuntu22.04を用いており、Dockerのバージョンは以下の通りです。

```bash
$ docker -v
Docker version 24.0.7, build afdd53b
$ docker compose version
Docker Compose version v2.21.0
```

作業用フォルダに移動します。

```bash
$ mkdir nginx-log
$ cd nginx-log
```

`compose.yaml`を作成します。`docker-compose.yamlから徐々に移行中です`

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - 0.0.0.0:30080:80
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      # - ./conf.d:/etc/nginx/conf.d
```

[公式ドキュメント](https://hub.docker.com/_/nginx)に従い、最新のNginxコンテナから初期状態の設定ファイルを取得します。

docker runコマンドで一時的にコンテナを起動し、その中からnginx.confを取得します。

```bash
$ docker run --name tmp-nginx-container -d nginx
$ docker cp tmp-nginx-container:/etc/nginx/nginx.conf ./nginx.conf
$ docker rm -f tmp-nginx-container
```

`nginx.conf`を修正します。初期設定ではファイルにログを出力しているので標準出力、標準エラーに変更します。これによりdocker経由でログを取得することができます。

> アクセスログを標準出力に流すことについては賛否があります。ファイルとして保存し、従来の方法で収集する方が好まれる印象がありますが、今回の検証では標準出力に流します。

```nginx
user  nginx;
worker_processes  auto;

#標準エラーに出力
error_log /dev/stderr warn;
#error_log  /var/log/nginx/error.log notice;

pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
	#標準出力に出力
    access_log /dev/stdout main;
    #access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
```

コンテナを起動します。

```
$ docker compose up -d
```

コンテナの起動を確認します。

```
$ docker compose ps -a
NAME      IMAGE          COMMAND                                          SERVICE   CREATED          STATUS          PORTS
nginx     nginx:latest   "/docker-entrypoint.sh nginx -g 'daemon off;'"   nginx     58 seconds ago   Up 57 seconds   0.0.0.0:30080->80/tcp
```

ブラウザでコンテナにアクセスします。

![image-20231028074935993.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/df80233d-bb5c-278e-ded4-d7afc4198246.png)


ログを確認してみます。

```
$ docker compose logs 
nginx  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
nginx  | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
nginx  | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
nginx  | /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
nginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
nginx  | /docker-entrypoint.sh: Configuration complete; ready for start up
nginx  | 192.168.144.32 - - [27/Oct/2023:22:47:02 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
nginx  | 2023/10/27 22:47:02 [error] 29#29: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.144.32, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.144.34:30080", referrer: "http://192.168.144.34:30080/"
nginx  | 192.168.144.32 - - [27/Oct/2023:22:47:02 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://192.168.144.34:30080/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
nginx  | 192.168.144.32 - - [27/Oct/2023:22:47:04 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
nginx  | 192.168.144.32 - - [27/Oct/2023:22:47:04 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
nginx  | 192.168.144.32 - - [27/Oct/2023:22:47:04 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
nginx  | 192.168.144.32 - - [27/Oct/2023:22:47:04 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
nginx  | 192.168.144.32 - - [27/Oct/2023:22:49:26 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
nginx  | 2023/10/27 22:49:26 [error] 31#31: *3 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.144.32, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.144.34:30080", referrer: "http://192.168.144.34:30080/"
nginx  | 192.168.144.32 - - [27/Oct/2023:22:49:26 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://192.168.144.34:30080/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
```

現在利用されているlog driverを確認します。json-fileが用いられているようです。

```bash
$ docker info --format '{{.LoggingDriver}}'
json-file
```





## none

コンテナに対するログを記録せず、 `docker logs` は何も出力しないそうです。使う機会があるかは不明ですが。試してみます。

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    # 省略
    logging:
      driver: none
```

logsコマンドで確認すると、想定通り、ログが確認できません。

```
$ docker compose logs nginx 
WARN[0000] Can't retrieve logs for "nginx": Error response from daemon: configured logging driver does not support reading 
```

一方でdocker runの場合、起動したターミナルでログが確認できます。これはログではなく、docker runコマンドの標準出力のため、想定通りの動作となります。

```bash
$ docker run --rm  \
  -p 0.0.0.0:30080:80 \
  -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf \
  --log-driver none \
  nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
192.168.144.32 - - [28/Oct/2023:00:17:08 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
192.168.144.32 - - [28/Oct/2023:00:17:08 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
192.168.144.32 - - [28/Oct/2023:00:17:09 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
```

別のターミナルから起動中のnginxコンテナを見てみると想定通り、ログが確認できません。

```bash
$ docker logs eager_burnell 
Error response from daemon: configured logging driver does not support reading
```



## Local file logging driver

ロギングドライバー`local`は、コンテナーの stdout/stderr を保存します。デフォルトでは、`local`ドライバーはコンテナーごとに 最大100MB のログ メッセージを保存し、自動圧縮を使用してディスク上のサイズを削減します。

> dockerが管理するローカルディスクに独自形式で保存するためパフォーマンスが最も良いです。しかし、ほかのアプリケーションからファイル経由でのアクセスは避けるよう記載があります。

例では、最大サイズを10MBに、ローテーションを3に指定します。

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    # 省略
    logging:
      driver: local
      options:
        max-size: 10m
        max-file: 3
```

動作確認をします。`logs`コマンドでログが取得できています。

```
ubuntu@test-nginx:~/nginx-log$ docker compose logs nginx 
nginx  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
nginx  | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
nginx  | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
nginx  | /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
nginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
nginx  | /docker-entrypoint.sh: Configuration complete; ready for start up
```

利用可能なオプションは以下の通りです。

| オプション | 説明                                                         | 値の例                     |
| :--------- | :----------------------------------------------------------- | :------------------------- |
| `max-size` | ログの最大サイズ。正の整数に、測定単位を表す修飾子 ( `k`、`m`、または`g`) を加えたもの。デフォルトは 20m です。 | `--log-opt max-size=10m`   |
| `max-file` | ログのローテーション数で、超えると最も古いファイルから削除されます。正の整数。デフォルトは 5 です。 | `--log-opt max-file=3`     |
| `compress` | ローテーションされたログ ファイルの圧縮を切り替えます。デフォルトで有効になっています。 | `--log-opt compress=false` |



## JSON File logging driver

デフォルトの設定で、コンテナーの stdout/stderr をJSON形式のファイルに保存します。JSON形式は各行にその出所（stdoutまたはstderr）とタイムスタンプを注釈します。各ログファイルは1つのコンテナに関する情報のみを含みます。

例では、最大サイズを10MBに、ローテーションを3に指定します。

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    # 省略
　　logging:
      driver: json-file
      options:
        max-size: 10m
        max-file: 3
```

動作確認をします。`logs`コマンドでログが取得できています。

```bash
$ docker compose logs 
nginx  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
nginx  | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
nginx  | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
nginx  | /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
nginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
nginx  | /docker-entrypoint.sh: Configuration complete; ready for start up
```

ログの出力先を確認します。

```
$ docker inspect nginx |grep LogPath
        "LogPath": "/var/lib/docker/containers/264dd92738c22bc708d87cb19c2f859972af90ee4e1ae1ab6e60370d0e7f0720/264dd92738c22bc708d87cb19c2f859972af90ee4e1ae1ab6e60370d0e7f0720-json.log",
```

ログファイルを覗いてみます。確かに1行1行Jsonファイルとして保存されています。

```bash
$ sudo cat /var/lib/docker/containers/264dd92738c22bc708d87cb19c2f859972af90ee4e1ae1ab6e60370d0e7f0720/264dd92738c22bc708d87cb19c2f859972af90ee4e1ae1ab6e60370d0e7f0720-json.log
#省略
{"log":"/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh\n","stream":"stdout","time":"2023-10-28T01:07:45.45693319Z"}
{"log":"/docker-entrypoint.sh: Configuration complete; ready for start up\n","stream":"stdout","time":"2023-10-28T01:07:45.46027774Z"}
```

> Jsonファイルは{}のルート要素を1つのファイル1つとしているためこのファイルは正確にはJsonファイルとは言えません。ほかのアプリケーションでパースする際は注意してください。1行1行をJsonとして読み込みましょう。

1行のログは以下のようになっています。ログのほかにも、標準出力/エラー、時刻が記録されています。

```json
{
    "log":"/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh\n",
    "stream":"stdout",
    "time":"2023-10-28T01:07:45.45693319Z"
}
```

利用可能なオプションは以下の通りです。

| オプション     | 説明                                                         | 値の例                                           |
| :------------- | :----------------------------------------------------------- | :----------------------------------------------- |
| `max-size`      | ログの最大サイズ。正の整数に、修飾子 ( `k`、`m`、または`g`) を加えたもの。デフォルトは -1 (無制限) です。 | `--log-opt max-size=10m`                         |
| `max-file`     | ログのローテーション数で、超えると最も古いファイルから削除されます。デフォルトは 5 です。 | `--log-opt max-file=3`                           |
| `compress`     | ローテーションされたログ ファイルの圧縮を切り替えます。デフォルトで有効になっています。 | `--log-opt compress=false`                       |
| `labels`       | ログメッセージをタグで分類する際に使用します。詳細は[ドキュメント](https://docs.docker.com/config/containers/logging/log_tags/)を参照してください。 | `--log-opt labels=production_status,geo`         |
| `labels-regex` | ” | `--log-opt labels-regex=^(production_statusgeo)` |
| `env`          | " | `--log-opt env=os,customer`                      |
| `env-regex`    | " | `--log-opt env-regex=^(oscustomer)`              |





## Syslog logging driver

`syslog`ドライバーはログをサーバーに転送します。オプションパラメータで、サーバアドレス、ファシリティを指定します。

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    # 省略
    logging:
      driver: syslog
      options:
        syslog-address: udp://172.17.0.1:514
        syslog-facility: daemon
        tag: "{{.ID}}_{{.Name}}"
        syslog-format: rfc5424
```

サーバ側はrsyslogを用います。`/etc/rsyslog.conf`

```
# provides UDP syslog reception
module(load="imudp")
input(type="imudp" port="514")
$AllowedSender TCP, 127.0.0.1, 172.17.0.1/16
```

syslogを確認します。`f60d2def811e_nginx`はコンテナのIDと名前になっています。

```
$ sudo tail -f /var/log/syslog 
Oct 28 01:48:33 test-nginx f60d2def811e_nginx[9334] 192.168.144.32 - - [28/Oct/2023:01:48:33 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
Oct 28 01:48:35 test-nginx f60d2def811e_nginx[9334] 192.168.144.32 - - [28/Oct/2023:01:48:35 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
```

コマンドでも確認してみます。以下の通り取得できています。

```
$ docker compose logs -f
nginx  | 192.168.144.32 - - [28/Oct/2023:01:48:33 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
nginx  | 192.168.144.32 - - [28/Oct/2023:01:48:35 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
```

利用可能なオプションは以下の通りです。

| オプション               | 説明                                                         | 値の例                                                       |
| :----------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
| `syslog-address`         | syslogサーバを指定、TCP/UDP/UNIX、TLS有無                    | `--log-opt syslog-address=udp://192.168.1.3:514`<br />`--log-opt syslog-address=tcp+tls://192.168.1.3:514`<br />`--log-opt syslog-address=unix:///tmp/syslog.sock` |
| `syslog-facility`        | syslogのファシリティを名称、または番号で指定                 | `--log-opt syslog-facility=daemon`                           |
| `tag`                    | デフォルトはコンテナ IDの先頭12文字<br />[使える特殊表現](https://docs.docker.com/config/containers/logging/log_tags/) | `--log-opt tag=test-app`<br />`--log-opt tag={{.Name}}`      |
| `syslog-format`          | 指定しない場合は、ローカルの Unix syslog 形式が使用されます。<br />`rfc3164`RFC-3164 互換形式<br />`rfc5424`RFC-5424 互換形式<br />`rfc5424micro ` 形式 | `--log-opt syslog-format=rfc5424`                            |
| `syslog-tls-ca-cert`     | CA によって署名された信頼証明書への絶対パス                  | `--log-opt syslog-tls-ca-cert=/ca.pem`                       |
| `syslog-tls-cert`        | TLS 証明書ファイルへの絶対パス。                             | `--log-opt syslog-tls-cert=/cert.pem`                        |
| `syslog-tls-key`         | TLS キー ファイルへの絶対パス。                              | `--log-opt syslog-tls-key=/key.pem`                          |
| `syslog-tls-skip-verify` | TLS 検証がスキップされます。                                 | `--log-opt syslog-tls-skip-verify=true`                      |

## Journald logging driver

journaldに転送するdriverです。journaldは、Systemdシステム管理デーモンの一部として提供されるログ管理ツールです。システムとサービスのログ情報を効率的に収集、管理、クエリするために設計されています。

伝統的なテキストベースのログファイル（例：/var/log/syslog）とは異なり、バイナリフォーマットでログを保持し、メタデータを活用して高速に検索やフィルタリングが可能です。journaldはログのローテーションや保持期間の設定、自動圧縮もサポートしており、システムのログ管理を中心的に担当します。

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    # 省略
    logging:
      driver: journald
      options:
        tag: "dev"
```

本ドライバーは以下のメタデータをログ本文と合わせてジャーナルに送信します。

| フィールド                                 | 説明                                                         |
| ------------------------------------------ | ------------------------------------------------------------ |
| `CONTAINER_ID`                             | 先頭12文字のコンテナID                                       |
| `CONTAINER_ID_FULL`                        | 完全な64 文字のコンテナ ID                                   |
| `CONTAINER_NAME`                           | 起動時のコンテナ名                                           |
| `CONTAINER_TAG`、<br />`SYSLOG_IDENTIFIER` | コンテナタグ ( [ログタグオプションのドキュメント](https://docs.docker.com/config/containers/logging/log_tags/))<br />ドライバーのオプションで指定したものが送信される |
| `CONTAINER_PARTIAL_MESSAGE`                | ログの整合性を示すフィールド。長いログ行のロギングを改善します。 |

ジャーナルから確認してみます。コンテナ名でも、オプションで指定したタグ`dev`でも検索ができます。

```bash
$ sudo journalctl CONTAINER_NAME=nginx
Oct 28 02:02:53 test-nginx dev[9334]: 192.168.144.32 - - [28/Oct/2023:02:02:53 +0000] "GET / HTTP/>
Oct 28 02:02:53 test-nginx dev[9334]: 192.168.144.32 - - [28/Oct/2023:02:02:53 +0000] "GET / HTTP/>
Oct 28 02:02:53 test-nginx dev[9334]: 192.168.144.32 - - [28/Oct/2023:02:02:53 +0000] "GET / HTTP/>
Oct 28 02:02:54 test-nginx dev[9334]: 192.168.144.32 - - [28/Oct/2023:02:02:54 +0000] "GET / HTTP/>
Oct 28 02:02:54 test-nginx dev[9334]: 192.168.144.32 - - [28/Oct/2023:02:02:54 +0000] "GET / HTTP/>
$ sudo journalctl CONTAINER_TAG=dev
# 同様
```

journalctlはless互換のため、検索や移動が容易です。dockerからもログは確認できます。

```
$ docker compose logs
nginx  | 192.168.144.32 - - [28/Oct/2023:02:02:54 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
nginx  | 192.168.144.32 - - [28/Oct/2023:02:02:54 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "-"
```





## Graylog Extended Format logging driver

本ドライバーはGELF形式での転送を行います。GEFLはGraylogやFluentdが有名です。

GELFのログメッセージはすべて次のフィールドを持つ辞書です。

- バージョン
- ホスト (最初にメッセージを送信した人)
- タイムスタンプ
- メッセージの短いバージョンと長いバージョン
- 自分で設定したカスタムフィールド

### ドライバーの指定方法

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    # 省略
    logging:
      driver: gelf
      options:
        gelf-address: "udp://172.17.0.1:12201"
```

### Graylog構築

```yaml
version: '3'
services:
  mongo:
    image: mongo:5
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2
    environment:
      - http.host=0.0.0.0
      - transport.host=localhost
      - network.host=0.0.0.0
      - "ES_JAVA_OPTS=-Dlog4j2.formatMsgNoLookups=true -Xms512m -Xmx512m"
  graylog:
    image: graylog/graylog:5.1
    environment:
      - GRAYLOG_PASSWORD_SECRET=somepasswordpepper
      # Password: admin
      - GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      - GRAYLOG_HTTP_EXTERNAL_URI=http://127.0.0.1:9000/
    entrypoint: /usr/bin/tini -- wait-for-it elasticsearch:9200 --  /docker-entrypoint.sh
    restart: always
    depends_on:
      - mongo
      - elasticsearch
    ports:
      - 9000:9000 # Graylog web interface and REST API
      - 1514:1514 # Syslog TCP
      - 1514:1514/udp # Syslog UDP
      - 12201:12201 # GELF TCP
      - 12201:12201/udp # GELF UDP
```

古いCPUではMongoDB 5.0系が動かないので注意です。

```
$ docker compose logs mongo  -f
graylog-mongo-1  | 
graylog-mongo-1  | WARNING: MongoDB 5.0+ requires a CPU with AVX support, and your current system does not appear to have that!
graylog-mongo-1  |   see https://jira.mongodb.org/browse/SERVER-54407
graylog-mongo-1  |   see also https://www.mongodb.com/community/forums/t/mongodb-5-0-cpu-intel-g4650-compatibility/116610/2
graylog-mongo-1  |   see also https://github.com/docker-library/mongo/issues/485#issuecomment-891991814
graylog-mongo-1  | 
```

起動後、Graylogダッシュボードにログインし、GELF inputを作成します。

![image-20231028115355326.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/4f5fca00-495a-f4ee-1269-2ddba5e8213c.png)


Nginxのアクセスログを確認します。


![image-20231028115601330.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/d21d06f0-8774-4b58-80f9-c8be9962a75b.png)


コンテナのログとしては検索などが可能ですが、messageフィールドをNginxフォーマットで分析するにはGraylogでの追加設定が必要です。本記事では詳細は扱いません。


![image-20231028115729157.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/0f92f765-a069-e382-fa1b-76702f4036c7.png)




## Fluentd logging driver

Fluentdへログを転送するドライバーです。Fluentdはオープンソースのデータ収集ソフトウェアで、複数のデータソースからのログやイベントデータを効率的に収集、変換、送信することを目的としています。クラウド環境や大規模なシステムでのログ集約や分析のための中心的なツールとして広く利用されています。

1. 多数のプラグインが利用可能で、データの収集、変換、出力先をカスタマイズ
2. データの一時的な保存や再送をサポートし、データの紛失リスクを低減
3. リソースの消費が少なく、大量のデータも効率的に処理

- Input Plugins（Source）
  - ログの入力を定義します
  - `tail`: コマンドのtail -fと同様にファイルを監視し追記分を入力とします
  - `forward`: fluentd形式の入力を受け付けます**Dockerドライバは本形式で出力する**
  - `http`: jsonのPOSTを受け付ける
  - `syslog`: syslogサーバとして機能する
- Filter Plugins（filter）
  - 通過するログをフィルタリングします
  - `grep`: 正規表現などを用いてログをフィルタリングします
  - `geoip`: IPアドレスから地域を判別できます
- Output Plugins（match）
  - フィルタリングやパースを行ったログを出力する
  - `stdout`: デバッグなどに用い、標準出力を利用します
  - `forward`: Fluentd形式で次のFluentd転送する
  - `mongo`: mongoDBに保存する
  - 他にも`s3`, `elasticsearch`などがあります
- その他
  - その他にもログ転送前に様々な処理を行うPluginが存在します。
  - Parser Plugins
  - Formatter Plugins
  - Buffer Plugins
  - Metrics Plugins

### ドライバーの指定方法

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    # 省略
    logging:
      driver: fluentd
      options:
        fluentd-address: "172.17.0.1:24224"
        tag: "docker_{{.Name}}"
```

### Fluent構築

本記事では`input`にドライバーの主力形式である`forward`、処理は行わず`output`に標準出力を用います。

`fluent.conf`を作成します。

```
<source>
  @type forward
</source>

<match docker_**>
  @type stdout
</match>
```

上記設定ファイルを組み込んだDockerイメージを作成するための`Dockerfile`

```dockerfile
FROM fluent/fluentd:v1.16-1

COPY fluent.conf /fluentd/etc
```

`compose.yaml`を作成します。

```yaml
version: '3'
services:
  fluentd:
    build: ./
    ports:
      - 24224:24224
      - 24224:24224/udp
```

Fluentdを起動します。起動後、NginxにアクセスするとFluentdを起動したターミナルの標準出力でログが確認できます。

```
$ docker compose up
[+] Running 2/2
 ✔ Network fluentd_default      Created                                                              0.1s 
 ✔ Container fluentd-fluentd-1  Created                                                              0.0s 
Attaching to fluentd-fluentd-1

~~ 省略 ~~

fluentd-fluentd-1  | 2023-10-28 03:43:30.000000000 +0000 docker_nginx: {"source":"stdout","log":"192.168.144.32 - - [28/Oct/2023:03:43:30 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36\" \"-\"","container_id":"3a8a296963b63a9b0f1d51dd3141749d0812662ace6188f027b9d708c0508c95","container_name":"/nginx"}
fluentd-fluentd-1  | 2023-10-28 03:43:30.000000000 +0000 docker_nginx: {"container_id":"3a8a296963b63a9b0f1d51dd3141749d0812662ace6188f027b9d708c0508c95","container_name":"/nginx","source":"stdout","log":"192.168.144.32 - - [28/Oct/2023:03:43:30 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36\" \"-\""}
fluentd-fluentd-1  | 2023-10-28 03:43:30.000000000 +0000 docker_nginx: {"container_id":"3a8a296963b63a9b0f1d51dd3141749d0812662ace6188f027b9d708c0508c95","container_name":"/nginx","source":"stdout","log":"192.168.144.32 - - [28/Oct/2023:03:43:30 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36\" \"-\""}
```

**注意点としては、コンテナ起動時にFluentdが起動している必要があります。Fluentd側に問題があるとコンテナは起動できません。**

```bash
$ docker compose up -d
[+] Running 2/2
 ✔ Network nginx-log_default  Created                                                     0.1s 
 ✔ Container nginx            Created                                                     0.2s 
Error response from daemon: failed to create task for container: failed to initialize logging driver: dial tcp 192.168.0.5:24224: connect: connection refused
```





## Amazon CloudWatch Logs logging driver

CloudWatchへ転送するdriverです。本章では親和性を考慮してEC2サーバ上のコンテナからの転送を想定します。Amazon CloudWatchは、AWSリソースおよびアプリケーションをモニタリングするサービスです。

1. **リアルタイムモニタリング**: AWSリソースのメトリクスをリアルタイムで収集し、表示
2. **アラーム**: 予め設定したしきい値を超えると、通知や自動アクションをトリガーするアラーム
3. **ダッシュボード**: 複数のメトリクスを一つのビューで見るためのカスタマイズ可能なダッシュボード
4. **ログファイルの統合**: CloudWatch Logsを使用して、アプリケーションのログファイルをモニタリングし、保存、分析
5. **カスタムメトリクス**: 独自のメトリクスをCloudWatchに送信し、モニタリング
6. **イベント管理**: CloudWatch Eventsを使用して、AWSリソースの変更や状態遷移を検出し、応答
7. **トレース**: CloudWatch ServiceLensとX-Rayの統合を通じて、アプリケーションのパフォーマンスボトルネックや問題点を追跡・分析する

### ドライバーの指定方法

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    # 省略
    logging:
      driver: awslogs
      options:
        awslogs-region: ap-northeast-1
        awslogs-group: my-log-group
        awslogs-create-group: "true"
```

### AWS CloudWatchでの設定

IAMからポリシーを作成し、本ポリシーをロール経由でEC2にアタッチします。

CloudWatchへのログ送信のみを許可した最低限のポリシーです。


![image-20231028130956175.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/10815252-f5cc-83c2-79bb-3f4381548e85.png)


```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": ["logs:CreateLogStream", "logs:PutLogEvents", "logs:CreateLogGroup"],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
```

EC2にログインし、Nginxを起動します。セキュリティグループには`30080`を適切に追加します。

```
[ec2-user@ip-XX nginx-log]$ sudo docker-compose up -d
[+] Running 1/1
 ⠿ Container nginx  Started   
```

起動前には、ドライバーがロググループを作成し、認証情報の確認などを行っています。

CloudWatchを確認すると、指定した名称でロググループが作成されています。

![image-20231028140918832.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/f092eee9-1bdc-8173-3419-16d220a0bdb6.png)



ライブテールからログを確認します。


![image-20231028141120209.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/c9f74dae-1942-5aff-fb2b-8c186b065795.png)




## Splunk logging driver

本ドライバーは SplunkへHTTP イベント コレクターとして送信します。Splunk Enterprise と Splunk Cloud に利用可能です。Splunk Cloudはあらゆるニーズに対応する柔軟なデータプラットフォームサービスです。※2

- 機械学習とAI
  - 対応だけでなく予測と防止を視野に入れ、マシンレベルのインテリジェンスをデータに統合して、セキュリティとビジネス成果を向上
- データストリーミング
  - リアルタイムのストリーム処理によってデータをミリ秒単位で収集、処理し、Splunkやその他の送信先に配信
- 拡張可能なインデックス
  - SaaSをはじめとする数千に及ぶデータソースからテラバイト規模のデータを収集、取り込み
- コラボレーションツール
  - モバイル、TV、AR (拡張現実)機能によって、場所に縛られないコミュニケーションとコラボレーションを実現
- 統合サーチ
  - オンプレミスやサードパーティのデータストアを含む多様なデータエコシステムを横断的にサーチしてデータを相関付け、組織レベルで分析
- 強力なダッシュボード
  - 直感的なダッシュボード画面で、複雑なデータストーリーでも簡単に状況を把握

### ドライバーの指定方法

`https://prd-p-XXXXXXX.splunkcloud.com:8080`はインスタンス払い出し時に届くメールアドレスに記載があります。そこにポート番号を付け加えます。今回は検証のため、Splunk Cloudサーバの証明書確認を無効としています。

```yaml
version: "3"
services:
  nginx:
    image: nginx:latest
    # 省略
    logging:
      driver: splunk
      options:
        splunk-token: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
        splunk-url: https://prd-p-XXXXXXX.splunkcloud.com:8088
        splunk-insecureskipverify: "true"
        tag: "{{.Name}}/{{.FullID}}"
        labels: location
```



### Splunk Cloudでの設定

Splunk Cloudは15日の無料トライアルが可能です。制限はありますが、メールアドレスのみで作成可能です。


![image-20231028144556043.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/cc389370-b99d-fc5c-d801-ed311624dbe9.png)



データの追加を行うため、HTTP イベント コレクターを作成します。作成後、テキストトークンが表示されるので保存します。ログ送信時に必要になります。


![image-20231028145852092.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/98784841-c1d9-fb02-c779-2be2689e54dd.png)



設定値が正しい場合、Nginxコンテナが起動できます。Nginxにアクセス後、Splunk Cloudから検索をかけます。ドライバーがログを送信する場合、オリジナルのNginxのログは`line`に表示されるため上手くパースできていませんが、本章では以上となります。



![image-20231028151825687.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/2158b4f9-f385-a36e-2c94-60dc9a0ddb4b.png)



## ETW logging driver

Event Tracing for Windows (ETW) ログ ドライバーは、コンテナー ログを ETW イベントとして転送します。ETW は Windows の Event Tracing の略で、Windows でアプリケーションをトレースするための共通のフレームワークです。各 ETW イベントには、ログとそのコンテキスト情報の両方を含むメッセージが含まれています。その後、クライアントはこれらのイベントをリッスンするための ETW リスナーを作成できます。

ETWはWindows PowerShellのlogmanコマンドを使用して設定を行います。以下のコマンドでイベントのリスナーを起動します。

```
logman start -ets DockerContainerLogs -p {a3693192-9ed6-46d2-a981-f8226c8363bd} 0 0 -o trace
```

公式ドキュメントよりETWとして転送されたログのサンプルを示します。イメージ名からも分かる通りWinsowsコンテナのため本記事での紹介は以上とさせていただきます。

```
container_name: backstabbing_spence,
image_name: windowsservercore,
container_id: f14bb55aa862d7596b03a33251c1be7dbbec8056bbdead1da8ec5ecebbe29731,
image_id: sha256:2f9e19bd998d3565b4f345ac9aaf6e3fc555406239a4fb1b1ba879673713824b,
source: stdout,
log: Hello world!
```

## gcplogs

`Google Cloud Logging`へログを転送します。クラウドベンダーが提供するログ基盤系のドライバーです。

まず、ログ転送用のサービスアカウントを作成します。Cloud Loggingサービスエージェントのロールを付与してください。プロジェクト単位より詳細にアクセス権限をコントロールしたい場合は新たなロールを作成してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/87e2ac03-3c2a-4875-8512-decaabcd220a.png)

作成したサービスアカウントのキーを生成してJSON形式でダウンロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/ddb656a7-a191-5f32-8ca7-13eca6d9eb01.png)

ダウンロードしたキーをログを転送する環境に設置します。

```
vim /etc/docker/gcp_credentials.json
```

Dockerログドライバーにcredentialの場所を渡します。

```
sudo vi /lib/systemd/system/docker.service

~~~ 省略 ~~~
[Service]
Environment=GOOGLE_APPLICATION_CREDENTIALS=/etc/docker/gcp_credentials.json
~~~ 省略 ~~~
```

確認用にNginxを起動します。

```
docker run \
    -p 0.0.0.0:8080:80 \
    --log-driver=gcplogs \
    --log-opt gcp-project=プロジェクトID \
    --log-opt gcp-meta-zone=west1 \
    --log-opt gcp-meta-name=`hostname` \
    nginx:latest
```

GCPログエクスプローラーで以下のクエリを実行します。

```
logName="projects/プロジェクトID/logs/gcplogs-docker-driver"
```

Nginxのログが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324111/66744b27-6eb6-a965-8d66-afefeb9ff687.png)


## おわりに

検証したすべてのドライバーをログの保存先で分類し、使用感をまとめました。

| ドライバ                                                     | 分類                       |                                                              |
| :----------------------------------------------------------- | :------------------------- | ------------------------------------------------------------ |
| `none`                                                       | ローカル系                 | コンテナに対するログを記録しない。ログをボリュームに書き出し、**fluentbit**で転送する場合などに有効 |
| [local](https://docs.docker.com/config/containers/logging/local/) | ローカル系                 | 独自のファイル方式で保存され、ドライバの中で一番オーバーヘッドが少ない※コンテナ再作成で消える |
| [json-file](https://docs.docker.com/config/containers/logging/json-file/) | ローカル系                 | JSON 形式で保存され、**デフォルトのドライバー※コンテナ再作成で消える** |
| [journald](https://docs.docker.com/config/containers/logging/journald/) | ローカル系                 | 検索しやすく、単一ホストでの運用では有力※デフォルトの設定ではホスト再起動で消える |
| [etwlogs](https://docs.docker.com/config/containers/logging/etwlogs/) | ローカル系                 | Windowsサーバなどを運用している場合は有力だが、Windowsコンテナを利用する機会が少なく、判断が難しい |
| [syslog](https://docs.docker.com/config/containers/logging/syslog/) | ログ基盤系                 | **既存のログ基盤と相性が良く**、ファイルに保存する場合は一番制御しやすいと感じた |
| [gelf](https://docs.docker.com/config/containers/logging/gelf/) | ログ基盤系                 | Graylogを採用している場合は最有力                            |
| [fluentd](https://docs.docker.com/config/containers/logging/fluentd/) | ログ基盤系                 | **複数のログ基盤**があり、基本はsyslog、アクセスログなどはsplunkに投げる、等使い分けるときは一元管理できる |
| [splunk](https://docs.docker.com/config/containers/logging/splunk/) | ログ基盤系<br />クラウド系 | Splunkを採用しているプロジェクトでは一択                     |
| [awslogs](https://docs.docker.com/config/containers/logging/awslogs/) | クラウド系                 | AWSを主に採用している場合は有力                              |
| [gcplogs](https://docs.docker.com/config/containers/logging/gcplogs/) | クラウド系                 | GCPを主に採用している場合は有力、Log explorerが使いやすい    |

上記から、ドライバーの選定には以下のケース別に判断すると良いと考えました。

- 単一ホストの場合
  - journaldに格納し、永続化の設定を行う
- 複数ホストの場合
  - syslogドライバーを使用し、ファイルに保存を行う
  - 法令、コンプライアンスでログの保存期間が決まっている場合でも対応が可能
- クラウド基盤を利用している場合
  - 使用しているクラウドに対応するドライバーを使用する

## 参考

1. https://docs.docker.com/config/containers/logging/local/
2. https://www.splunk.com/ja_jp/products/splunk-cloud-platform.html