ブログ
これまでに経験してきたプロジェクトで気になる技術の情報を紹介していきます。
【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
コメントはありません。