【Docker環境】FluentdとMySQLのbulk insertを使用したログ収集【後編】

下記の記事の続きになります。

【Docker環境】FluentdとMySQLのbulk insertを使用したログ収集【前編】 https://www.aska-ltd.jp/jp/blog/60

今回はMySQLコンテナとphpコンテナについて解説して、最後は実際にphpからFluentdを使ってMySQLにログを出力してみたいと思います。

ディレクトリ構成

.
├── docker-compose.yml
├── fluentd    # 前編で説明済み
│   ├── Dockerfile
│   └── conf
│       └── fluent.conf
├── mysql
│   ├── data
│   ├── initdb
│   │   └── create_table.sql
│   └── my.cnf
└── php
    ├── Dockerfile
    ├── php.ini    # 今回は使用しません。
    └── src
        ├── composer.json
        └── index.php

docker-compose.yml

version: '3'

services:
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: test_db
      MYSQL_ROOT_PASSWORD: password
      TZ: 'Asia/Tokyo'
    volumes:
      - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./mysql/data:/var/lib/mysql
      - ./mysql/initdb:/docker-entrypoint-initdb.d
  php:
    build: ./php
    volumes:
      - ./php/src:/src
#      - ./php/php.ini:/usr/local/etc/php/php.ini
    tty: true
  fluentd:
    build: ./fluentd
    volumes:
      - ./fluentd/conf/fluent.conf:/fluentd/etc/fluent.conf

MySQL

MySQL5.7のDockerイメージを使用します。

コンテナで扱うデータベース、rootのパスワード、タイムゾーンの環境変数を設定しています。

また、MySQLの設定(文字コード)、データの永続化、コンテナの初回起動時にテスト用テーブルを作成したいので、マウントの設定も行っています。

PHP

ホストOSの./php/srcの下にcomposer.jsonとテスト用のスクリプト(index.php)を置いています。これをphpコンテナの/srcにマウントしています。

今回は単純な検証しかしないため、php.iniの設定は必要なかったですが、もしphp.iniの設定が必要な場合はコメントを外して下さい。

困ったこと

PHPは「php:7.4-cli-alpine」のDockerイメージを使用しているのですが、最初は「tty: true」を設定していなかったため、コンテナを起動してもすぐに終了してしまいました。

こういう困ったときの基本はググるです!ググってみたら原因がわかりました!

docker-compose up したコンテナを起動させ続ける方法 https://qiita.com/sekitaka_1214/items/2af73d5dc56c6af8a167

(;☉ε ⊙ノ)ノ えっ?もしかして常識的なこと!?

普段はPHP-FPM版のDockerイメージを使用していたため、コンテナが起動し続けていたのですが、CLI版だとポートで待ち受ける必要がないため、すぐに終了していたようです。

とりあえず、Dockerfileで「tty: true」を指定することによって、phpコンテナがずっと起動し続けるようになりました。

my.cnf

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

[client]
default-character-set=utf8mb4

文字コードを「utf8mb4」に変更したいので、MySQLの設定ファイルで指定しています。

create_table.sql

CREATE TABLE IF NOT EXISTS `test_table` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `user_id` INT NOT NULL COMMENT 'ユーザID',
    `name` VARCHAR(45) NOT NULL COMMENT 'ユーザ名',
    `created` DATETIME NOT NULL COMMENT '作成日時',
     PRIMARY KEY (`id`)
) ENGINE = InnoDB;

test_dbデータベースの中に、test_tableテーブルを作成する必要があるため、CREATE TABLE文をcreate_table.sqlの中で定義しています。

MySQLコンテナの/docker-entrypoint-initdb.dの中にcreate_table.sqlを置いているので、コンテナ初回起動時にテーブルが作成されます。

Dockerfile

FROM php:7.4-cli-alpine

RUN curl -sS https://getcomposer.org/installer | php && \
    mv composer.phar /usr/local/bin/composer

RUN composer config -g repos.packagist composer https://packagist.jp && \
    composer global require hirak/prestissimo

PHPでFluentdにログを送るために、次のライブラリが必要になります。

Fluent Logger PHP https://github.com/fluent/fluent-logger-php

fluent-logger-phpはComposerでインストールする必要があるため、PHPコンテナにComposerをインストールしています。

また、Composerコマンドは素だと非常に遅いため、リポジトリを国内ミラーサーバのpackagist.jpに変更して、hirak/prestissimoという並列化プラグインをインストールしています。

composer.json

{
    "require": {
        "fluent/logger": "v1.0.0"
    }
}

fluent-logger-phpをインストールするために、composer.jsonを用意します。

index.php

<?php

require_once __DIR__.'/vendor/autoload.php';

use Fluent\Logger\FluentLogger;
$logger = new FluentLogger('fluentd', '24224');
$logger->post('mysql.input', ['user_id'=>1, 'name'=>'田中太郎', 'created'=>'2010-01-01 00:00:00']);
$logger->post('mysql.input', ['user_id'=>2, 'name'=>'スズキイチロウ', 'created'=>'2010-01-01 00:00:01']);

Fluentdにログを送信する検証用のphpスクリプトになります。

FluentLoggerクラスのコンストラクタの中で、Fluentdのホスト名とポート番号を指定する必要があります。

ホスト名はFluentdのサービス名、ポート番号は24224(デフォルトの待受ポート)を指定しています。

ログはFluentLoggerクラスのpostメソッドを使用して送信します。

postメソッドの最初の引数にはタグを指定します。今はFluentdの設定ファイルでタグが「mysql.input」の時に送信を行うように定義しているので、postメソッドにも「mysql.input」を指定しています。

# Fluentdの設定ファイルから抜粋
<match mysql.input>
  ・・・
</match>

postメソッドの2つ目の引数にはFluentdに送るデータを指定します。

配列形式で [カラム名1 => 値1, カラム名2 => 値2, ・・・] のように指定します。

# Fluentdの設定ファイルから抜粋
<match mysql.input>
  ・・・
  column_names user_id,name,created
  ・・・
</match>

column_namesと同じカラムを指定する必要があるので注意して下さい。

ビルド&コンテナ起動

$ docker-compose build --no-cache
・・・

$ docker-compose up -d
・・・

$ docker-compose ps
        Name                      Command               State                 Ports 
-------------------------------------------------------------------------------------------------
app-docker_fluentd_1   tini -- /bin/entrypoint.sh ...   Up      24224/tcp, 5140/tcp
app-docker_mysql_1     docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp
app-docker_php_1       docker-php-entrypoint php -a     Up

起動後に全てのコンテナのStateがUpになっていれば問題ありません。

fluent-logger-phpのインストール

$ docker-compose exec php /bin/sh -c "cd /src && composer install"
・・・

phpコンテナの/srcの下にcomposer.jsonがあるので、/srcに移動してから「composer install」を実行しています。

これによりfluent-logger-phpが使用できるようになります。

Fluentdのログ監視 ※ログ送信前

$ docker-compose logs -f fluentd
・・・

FluentdがMySQLにログをinsertしたら、Fluentdコンテナでログが流れるので、それを確認するためにログを監視しておきます(ターミナルを一つ専用に立ち上げといて下さい)

Fluentdのログ送信

$ docker-compose exec php php /src/index.php

phpスクリプトを実行して、Fluentdにログを送ります。

Fluentdのログ監視 ※ログ送信後

$ docker-compose logs -f fluentd
・・・
fluentd_1  | 2020-05-02 10:30:12 +0000 [info]: #0 bulk insert values size (table: test_table) => 2

/src/index.phpを実行してから5秒後に上記のログが出力されます。

ログの内容からtest_tableテーブルに2レコードがinsertされたことがわかります。

動作確認

$ docker-compose exec mysql mysql -u root -p
Enter password: 
・・・

mysql> use test_db;
Database changed

mysql> select * from test_table;
+----+---------+-----------------------+---------------------+
| id | user_id | name                  | created             |
+----+---------+-----------------------+---------------------+
|  1 |       1 | 田中太郎              | 2010-01-01 00:00:00 |
|  2 |       2 | スズキイチロウ        | 2010-01-01 00:00:01 |
+----+---------+-----------------------+---------------------+
2 rows in set (0.00 sec)

test_tableの中身を確認すると2レコード作成されています。

また、今回はクエリログを出力する設定はしていませんでしたが、MySQLでは次のようなクエリが発行されています。

2020-05-02T11:51:42.930454Z         3 Connect   root@192.168.16.2 on test_db using SSL/TLS
2020-05-02T11:51:42.931833Z         3 Query     INSERT INTO test_table (`user_id`,`name`,`created`) VALUES ('1','田中太郎','2010-01-01 00:00:00'),('2','スズキイチロウ','2010-01-01 00:00:01')
2020-05-02T11:51:42.983835Z         3 Quit

Kitaru

Programmer

【Docker環境】FluentdとMySQLのbulk insertを使用したログ収集【後編】

お気軽に
お問い合わせください。

お問い合わせ