ビックデータ時代のログ収集管理ツールFluentdのインストールと使い方


投稿日:2014年9月11日
  • 15
  • 1
  • 41



前回に続いて第3弾、ログ収集ツールFluentdをインストール

fluentd

Fluentd(フルエントディー)とはTreasure Data社が開発するログ収集管理ツールです。

ログ収集と言えばsyslogや当サイトでも紹介したsyslogの強化版「rsyslog、またはsyslog-ng」が有名です。

近年ビックデータ、ビックデータと声高に叫ばれていますが、その名前の示す通り、データ量や形式が増えており効率的に収集・分析する手段が求められていました。
その現場の声から生まれたのFluentdです。


目次

Fluentdの特徴とメリット
Fluentdのインストール
Fluentdの設定ファイルについて
fluent-plugin-dstatとfluent-plugin-mapをインストール
fluent-plugin-growthforecastをインストール
dstatのデータをGrowthForecastに渡す設定
nginxのログをGrowthForecastに渡す設定
dfコマンドでディスク使用量をGrowthForecastに渡す設定
MySQLのスロークエリをGrowthForecastに渡す設定


Fluentdの特徴とメリット

1.ログデータをJSON形式で扱う

ログ収集で困るのがソフトによって形式がバラバラで、データを加工するには、それぞれの形式に合わせた専用のプログラムを作成する必要がありました。
Fluentdでは全てのログをJSON形式にするため、データを構造的に把握することができ、後のデータ交換が容易です。

fluentd01

2.プラグインで柔軟に拡張できる

Fluentdはコミュニティが活発で、公式プラグインの他に、有志によるプラグインが豊富に用意されています。
プラグインは以下の構成から成っています。

  • ●入力するログの形式をJSONに変換するInputプラグイン
  • ●出力する対象に合わせた形式に変換するOutputプラグイン
fluentd02

一般的なログ収集に必要なプラグインは大抵用意されています。
公式プラグインページ

fluentd03

3.リアルタイムに収集できる

ビックデータからリアルタイムに行動分析を行うという需要も増えてきました。
今までのシステムでは、1度各サーバに保存したデータをログサーバに集約・収集してから分析していたため、どうしてもタイムラグがありました(レイテンシが大きかった)。

Fluentdには大量のデータを安全でリアルタイムに処理する仕組みが備わっています。
日本を代表するWebサービスでも広く採用されており「100台あるWebサーバのログを1台のログサーバに集約する」という事例でも安定して稼働しています。

fluentd04

4.導入・運用が容易である

個人的には一番重要な項目です。多機能でも使いこなせなければ無いのと同じです。
導入方法はこのページで解説します。手軽で理解しやすく、それでいて細かな調整も可能な拡張性を併せ持っていることを理解していただけると思います。


Fluentdのインストール

公式のドキュメントにありますが、yumを利用したシェルスクリプトを実行するだけです。
(前回の解説で触れましたがCentOS6を想定して解説を進めます)

# curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh | sh
(省略)
Dependencies Resolved

================================================================================
 Package                Arch       Version                    Repository   Size
================================================================================
Installing:
 kernel                 x86_64     2.6.32-431.23.3.el6        updates      28 M
 kernel-devel           x86_64     2.6.32-431.23.3.el6        updates     8.8 M
Updating:
 avahi-libs             x86_64     0.6.25-12.el6_5.1          updates      54 k
 ca-certificates        noarch     2014.1.98-65.0.el6_5       updates     1.1 M
 coreutils              x86_64     8.4-31.el6_5.2             updates     3.0 M
 coreutils-libs         x86_64     8.4-31.el6_5.2             updates      50 k
 cups-libs              x86_64     1:1.4.2-52.el6_5.2         updates     316 k
 dovecot                x86_64     1:2.0.9-7.el6_5.1          updates     1.9 M
 gdb                    x86_64     7.2-64.el6_5.2             updates     2.3 M
 glibc                  x86_64     2.12-1.132.el6_5.3         updates     3.8 M
 glibc-common           x86_64     2.12-1.132.el6_5.3         updates      14 M
 glibc-devel            x86_64     2.12-1.132.el6_5.3         updates     978 k
 glibc-headers          x86_64     2.12-1.132.el6_5.3         updates     609 k
 gnutls                 x86_64     2.8.5-14.el6_5             updates     346 k
 grub                   x86_64     1:0.97-84.el6_5            updates     933 k
 httpd-tools            x86_64     2.2.15-31.el6.centos       updates      73 k
 initscripts            x86_64     9.03.40-2.el6.centos.3     updates     940 k
 iproute                x86_64     2.6.32-32.el6_5            updates     365 k
 kernel-firmware        noarch     2.6.32-431.23.3.el6        updates      13 M
 kernel-headers         x86_64     2.6.32-431.23.3.el6        updates     2.9 M
 libtasn1               x86_64     2.3-6.el6_5                updates     238 k
 net-snmp               x86_64     1:5.5-49.el6_5.2           updates     306 k
 net-snmp-libs          x86_64     1:5.5-49.el6_5.2           updates     1.5 M
 nspr                   x86_64     4.10.6-1.el6_5             updates     113 k
 nss                    x86_64     3.16.1-4.el6_5             updates     832 k
 nss-sysinit            x86_64     3.16.1-4.el6_5             updates      41 k
 nss-tools              x86_64     3.16.1-4.el6_5             updates     360 k
 nss-util               x86_64     3.16.1-1.el6_5             updates      64 k
 openssl                x86_64     1.0.1e-16.el6_5.15         updates     1.5 M
 openssl-devel          x86_64     1.0.1e-16.el6_5.15         updates     1.2 M
 plymouth               x86_64     0.8.3-27.el6.centos.1      updates      89 k
 plymouth-core-libs     x86_64     0.8.3-27.el6.centos.1      updates      88 k
 plymouth-scripts       x86_64     0.8.3-27.el6.centos.1      updates      31 k
 ql2400-firmware        noarch     7.03.00-1.el6_5            updates      94 k
 ql2500-firmware        noarch     7.03.00-1.el6_5            updates     118 k
 tzdata                 noarch     2014e-1.el6                updates     453 k

Transaction Summary
================================================================================
Install       2 Package(s)
Upgrade      34 Package(s)

Dependencies Resolved

================================================================================
 Package               Arch       Version                Repository        Size
================================================================================
Installing:
 td-agent              x86_64     1.1.20-0               treasuredata      64 M
Installing for dependencies:
 compat-libtermcap     x86_64     2.0.8-49.el6           base              16 k
 compat-readline5      x86_64     5.2-17.1.el6           base             130 k
 openssl098e           x86_64     0.9.8e-18.el6_5.2      updates          761 k
 td-libyaml            x86_64     0.1.4-1                treasuredata     126 k

Transaction Summary
================================================================================
Install       5 Package(s)

これだけでインストールは完了です。
まずは開発用のツールをインストールした後に本体をインストールしているみたいですね。

これで以下のコマンドを利用できます。

# /etc/init.d/td-agent start
# /etc/init.d/td-agent stop
# /etc/init.d/td-agent restart
# /etc/init.d/td-agent status
td-agentとは

このコマンドでインストールされるのはFluentdの安定版である「td-agent」です。
FluentdはRubyで書かれていますが、RHELで公式にサポートされているRubyのバージョンにはバグがあり、正常に動作しません。FluentdのためだけにRubyをアップデートするとなると敷居が高くなります。

そこでFluentdの安定動作するRubyのバージョンとセットになったtd-agentをインストールしています。

Fluentdの設定ファイルについて

Fluentdの設定ファイルは「source、match、include」という3つのディレクティブから構成されています。
各プラグインの詳細については公式のドキュメントが充実しているのでそちらをご覧ください。

sourceディレクティブについて

source(ソース)ディレクティブ入力元を決定します。
inputプラグインを指定することで入力されるログを制御します。inputプラグインはtypeパラメータで設定します。

例)httpのポート80に関するデータを収集

<source>
  type http
  port 80
  tag access
</source>

代表的なInputプラグイン

in_forward TCP/IPを使ってイベントを受け取る。他のfluentdからイベントログを受信する。
in_http HTTP POSTからレコードを取得する。
in_tail テキストファイルの末尾からイベントを読み込む。再起動時に読み込んだ位置を記録するためにpos_fileを設定する。
in_exec イベントログを受け取りまたは取得するための外部プログラムを実行する。
in_syslog FluentdがUDP上のsyslogプロトコル経由でレコードを取得する。
in_scribe Scribeプロトコルでレコードを取得する。

公式:インプットプラグイン概要

matchディレクティブについて

matchディレクティブではoutputプラグインを選択・設定します。
まずmatchで一致するtagのパターンを指定。一致したログを出力をするoutputプラグインを指定する。

例)sourceディレクティブで設定したtagにマッチするログをファイルに書き出す

<source>
  type http
  port 80
  tag access
</source>

<match access>
  type file
  path /var/log/fluent/access
</match>

matchパターンのルール

これは少し特殊ですが、慣れれば簡単です。公式の解説をそのまま流用します。

* は1つのtag要素に合致します。

例えば、 a.* というパターンは a.b には合致しますが、 a や a.b.c には合致しません。
** は0個以上のtag要素に合致します。

例えば、 a.** というパターンは a, a.b, a.b.c に合致します。
{X,Y,Z} は X, Y, Z にマッチします、なお X, Y, Z はmatchパターンです。

例えば、 {a,b} というパターンは a や b には合致しますが、 c には合致しません。
これは * パターンや ** パターンと組み合わせて使うこともできます。例えば a.{b,c}.* や a.{b,c.**} です。

簡単に補足すれば以下のようになります。

  • <match hoge> 一致するパターン:hoge
  • <match hoge.*> 一致するパターン:hoge.01、hoge.02
  • <match hoge.**> 一致するパターン:hoge、hoge.01、hoge.01.02

代表的なOutputプラグイン

Outputプラグインには「Buffered、Time Sliced、Non-Buffered」タイプがあります。

out_forward Buffered 別のFluentdにログを転送する。
out_mongo Buffered ログを引数として、指定したプログラムに渡す
out_file Time Sliced 指定したファイルにログを記録する
out_s3 Time Sliced Amazon S3ストレージにログを記録する
out_copy Non-Buffered 一つのログを複数の出力先に転送する
out_null Non-Buffered なにも出力しない

公式:アウトプットプラグイン概要

Bufferの種類

予めプラグイン側で推奨される値で設定されているので、意識することはあまりないと思いますが、以下の様な仕組みになっています。

Bufferedは一時的にメモリやファイルにデータを保存して、一定の値に達したら出力する仕組みです。デフォルトはメモリ上にデータを保存します。一定量で書き込むのでデータベース向き。

Time Slicedは一定の時間が来たら出力する仕組みです。こちらはデータ量が多くなることもあるのでデフォルトはファイルに保存します。複数のサーバから転送されたログを決まった時間で一纏めに保存するので、時間ごとの数をカウントしたり、ディスクへの保存向き。

Non-Bufferedは名前の通りバッファをしない仕組みです。Fluentd内部で複数の出力先を指定したり、ログを破棄する際に利用する。

includeディレクティブについて

他の設定ファイルを読み込みます。

例)/config.dというサブディレクトリにある.confで終わるファイルを読み込む

include config.d/*.conf

fluent-plugin-dstatとfluent-plugin-mapをインストール

fluent-plugin-dstatはdstatのデータをfluentで扱えるようにするプラグインです。
fluent-plugin-mapはイベントログを加工するためももの。

fluent-plugin-dstatプラグインページ

fluent-plugin-mapプラグインページ

# gem install fluent-plugin-dstat fluent-plugin-map
Fetching: fluent-mixin-rewrite-tag-name-0.1.0.gem (100%)
Fetching: fluent-plugin-dstat-0.2.5.gem (100%)
Successfully installed fluent-mixin-rewrite-tag-name-0.1.0
Successfully installed fluent-plugin-dstat-0.2.5
Fetching: fluent-plugin-map-0.0.4.gem (100%)
Successfully installed fluent-plugin-map-0.0.4
3 gems installed
Installing ri documentation for fluent-mixin-rewrite-tag-name-0.1.0...
Installing ri documentation for fluent-plugin-dstat-0.2.5...
Installing ri documentation for fluent-plugin-map-0.0.4...
Installing RDoc documentation for fluent-mixin-rewrite-tag-name-0.1.0...
Installing RDoc documentation for fluent-plugin-dstat-0.2.5...
Installing RDoc documentation for fluent-plugin-map-0.0.4...

-bash: gem: command not found」とエラーが出る場合は、以下の手順でパスを通します。

# vi ~/.bash_profile

PATH=$PATH:$HOME/bin
↓「/usr/lib64/fluent/ruby/bin/」を「:」で繋いで追加
PATH=$PATH:$HOME/bin:/usr/lib64/fluent/ruby/bin/

# source ~/.bash_profile ← 再読み込み

または「/usr/lib64/fluent/ruby/bin/gem」でも可能です。好みの方法でインストールしてください。


fluent-plugin-growthforecastをインストール

fluent-plugin-growthforecastはfluentdのデータをGrowthForecastに渡すためのOutputプラグインです。

fluent-plugin-growthforecastプラグインページ

# gem install fluent-plugin-growthforecast
Fetching: uuidtools-2.1.5.gem (100%)
Fetching: fluent-mixin-config-placeholders-0.3.0.gem (100%)
Fetching: resolve-hostname-0.0.4.gem (100%)
Fetching: fluent-plugin-growthforecast-0.2.8.gem (100%)
Successfully installed uuidtools-2.1.5
Successfully installed fluent-mixin-config-placeholders-0.3.0
Successfully installed resolve-hostname-0.0.4
Successfully installed fluent-plugin-growthforecast-0.2.8
4 gems installed
Installing ri documentation for uuidtools-2.1.5...
Installing ri documentation for fluent-mixin-config-placeholders-0.3.0...
Installing ri documentation for resolve-hostname-0.0.4...
Installing ri documentation for fluent-plugin-growthforecast-0.2.8...
Installing RDoc documentation for uuidtools-2.1.5...
Installing RDoc documentation for fluent-mixin-config-placeholders-0.3.0...
Installing RDoc documentation for resolve-hostname-0.0.4...
Installing RDoc documentation for fluent-plugin-growthforecast-0.2.8...

dstatのデータをGrowthForecastに渡す設定

それでは準備が整ったので設定をします。
この例では自分のサーバのdstatの出力を、自分のサーバに設置されたGrowthForecastでグラフ化する設定です。

まずはお決まりのバックアップ。

# cp /etc/td-agent/td-agent.conf /etc/td-agent/td-agent.conf.org
# vi /etc/td-agent/td-agent.conf

以下「td-agent.conf」の内容。
コメントでしつこいくらい解説したので読んでいただければ理解できると思います。さらに細かく知りたい場合はプラグインページのREADMEを参照してください。

# dstatからイベントログを取得
<source>
    type dstat # dstatプラグインを指定
    tag dstat # ログに付けるタグを指定
    option -cdnm --tcp --udp # dstat実行時のオプション(グラフ化するデータ)を指定
    delay 3 # 何秒おきにデータを出力するかを指定
</source>

# GrowthForecast用にメッセージを加工する
<match dstat> # 対象とするタグを指定
    type copy # out_copyプラグインを指定(複数の出力をする場合に使う)

    # CPU関連の結果だけを取り出す
    # 後にmatchディレクティブでperf.**で一致させるようにtagに接頭辞perfを付ける
    <store> # match dstatの出力を受ける一つ目の受け皿
        type map # mapプラグインを指定
        tag "perf.cpu" # ログに付けるタグを指定(URLにもなるので/などは使えない)
        time time # ログのイベント日時の指定
        record record['dstat']['total cpu usage'] # 対象となるレコードの指定(dstatプラグインでJSONに変換されたレコード)
    </store>

    # ディスクIO関連の結果だけを取り出す
    <store>
        type map
        tag "perf.dsk"
        time time
        record record['dstat']['dsk/total']
    </store>

    # メモリ関連の結果だけを取り出す
    <store>
        type map
        tag "perf.mem"
        time time
        record record['dstat']['memory usage']
    </store>

    # ネット関連の結果を抜き出す
    <store>
        type map
        tag "perf.tcp-sockets"
        time time
        record record['dstat']['tcp sockets']
    </store>

    # 通信量関連の結果を抜き出す
    <store>
        type map
        tag "perf.network"
        time time
        record record['dstat']['net/total']
    </store>

    <store>
        type map
        tag "perf.udp"
        time time
        record record['dstat']['udp']
    </store>
</match>

# GrowthForecastに転送する(ローカル用)
<match perf.**> # 上で設定した接頭辞perfをまとめて設定
    type growthforecast
    gfapi_url http://127.0.0.1:5125/api/ # GrowthForecastのURLを指定
    service dstat # service名を入力(カテゴリ)
    tag_for section # sectionとすると接頭辞(tag)が入る(項目名)
    remove_prefix perf # matchのために付けたperfという接頭辞を削除
    name_key_pattern .* # パターンを使えるname_keyにあたるもの。この例では全て
</match>

インストールしたプラグインの読み込みなどもあるので再起動

# /etc/init.d/td-agent restart

そしてGrowthForecastのアドレスへアクセス

(198.162.0.1の部分は自分のIPに合わせてください)

http://198.162.0.1:5125/

無事に動作していれば以下の様なグラフが表示されるはずです。

fluentd05

最後に自動起動を設定します。

# chkconfig --list td-agent
# chkconfig td-agent on
growthforecast  0:off   1:off   2:on    3:on    4:on    5:on    6:off
td-agentの自動起動に関して注意

CentOS6で上記自動起動を設定すると再起動時にエラーが起きて起動できない不具合が発生しました。
massageに起動時のエラーすら書き込まれない重症だったので、原因の究明に非常に手間取りました。

そこで一旦サーバが正常に起動した後にrc.localで読み込むようにしたところ正常に動作するようになりました。一応参考までに設定を紹介します。

# vi /etc/rc.local
(以下2行を追加)
/etc/init.d/growthforecast start
/etc/init.d/td-agent start

以上で3回に分けて解説したdstatによるサーバリソースの把握、FluentdとGrowthForecastによるグラフ化は終了です。
解説も含めたので長くなりましたが、設定自体はどれも簡単で手軽に導入できることを理解していただけたと思います。

せっかくなのでdstat以外のログをグラフ化する設定も合わせて解説します。


nginxのログをGrowthForecastに渡す設定

サーバの状態を把握する上でよくあるのがWebトラフィックの把握です。今回はnginxのログをグラフ化する方法も解説します。

上の例ではdstatの出力をInputプラグインでJSONに直接変換しました。今回はnginxのログをFluentdが公式でサポートしているLTSV形式に変換して取り込むという方法を採用します。

# vi /etc/nginx/nginx.conf

httpコンテキストに追加してください。log_formatの定義を追加してaccess_logの形式でltsvを指定しています。

    log_format  ltsv  'time:$time_local\t'
                      'host:$remote_addr\t'
                      'request:$request\t'
                      'status:$status\t'
                      'size:$body_bytes_sent\t'
                      'referer:$http_referer\t'
                      'ua:$http_user_agent\t'
                      'reqtime:$request_time\t'
                      'upsttime:$upstream_response_time';

#    access_log  /var/log/nginx/access.log  main;
    access_log  /var/log/nginx/access.log  ltsv;

設定できたらnginxを再起動

# /etc/init.d/nginx restart
nxinxのmain形式とltsv形式のログの違い

main形式
127.0.0.1 - - [31/Aug/2014:15:45:05 +0900] "GET /index.php?FrontPage HTTP/1.0" 200 26121 "-" "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)" "68.180.225.35"

ltsv形式
time:31/Aug/2014:15:47:40 +0900	host:127.0.0.1	request:GET / HTTP/1.0	status:200	size:206570	referer:-	ua:Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36	reqtime:0.209	upsttime:0.208

fluent-plugin-datacounterプラグインをインストール

datacounterとは指定したパターンに一致したログの数をカウントするプラグインです。このプラグインを利用して、ステータスコードごとにカウントします。

# /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-datacounter
1 gem installed
Installing ri documentation for fluent-plugin-datacounter-0.4.3...
Installing RDoc documentation for fluent-plugin-datacounter-0.4.3...

Fluentdの設定を編集

今回もコメントで詳しく解説したので、読んでいただければ理解できると思います。

かつてはLTSV形式のログを取得するのに「tail_labeled_tsv」というプラグインを利用していましたが、現在では公式でサポートされているため、tailプラグインで「format ltsv」とすることで取得します。

注意点としては、この方法では時間に関するフォーマットを自動で解析できないようで、「time_key」と「time_format」を追加しないと正しく動作しません。

# vi /etc/td-agent/td-agent.conf
<source>
	type tail # tailプラグインを指定。Fluentdがイベントログをテキストファイルの末尾から読み取れる。
	path /var/log/nginx/access.log # 読み込むログファイルを指定
	pos_file /var/log/td-agent/fluent.log.pos # 停止後、再開時に正常に読み込めたログから再開するための情報を書き込むファイル。指定しないとwarningが出る。なぜか公式に解説がない。追加してもrestartするとwarnが出るがそれは気にしない。
	tag nginx.access # ログにタグを指定
	format ltsv # ltsv形式を読み込む公式プラグイン
	time_key time # nginxで定義したltsvの時間にあたる部分
	time_format %d/%b/%Y:%H:%M:%S %z # ltsvの時間形式を指定
</source>

<match nginx.access> # 上で定義したタグにマッチする
	type copy # マッチしたログを複数の形式で書き出すためのプラグイン
	<store> # copyプラグインの1つ目の出力先
		type file # fileプラグイン(ファイルにログを出力する)
		path /var/log/td-agent/nginx.access
	</store>
	<store> # copyプラグインの2つ目の出力先
		type growthforecast
		gfapi_url http://127.0.0.1:5125/api/
		service   nginx # カテゴリ
		section   response # 項目名
		name_keys reqtime,upsttime # ltsvで設定したレコードを指定
	</store>
	<store>
		type datacounter # datacounterプラグインでカウントする
		unit minute # 1分ごとに取得
		tag nginx.access.status_count # タグを付ける
		count_key status # ltsvで設定したレコードを指定
		pattern1 3xx ^3\d\d$ # 右辺のパターンで一致したものを左辺の形式でカウントする。Rubyの正規表現が使える。301でも302でも3xxとしてカウントされる。形式は[tag]_3xx_countとなる。
		pattern2 4xx ^4\d\d$
		pattern3 5xx ^5\d\d$
		pattern4 200 ^200$
	</store>
</match>

<match nginx.access.status_count>
	type growthforecast
	gfapi_url http://127.0.0.1:5125/api/
	service   nginx # カテゴリ
	section   status_codes # 項目名
	name_keys nginx.access_5xx_count,nginx.access_4xx_count,nginx.access_3xx_count,nginx.access_200_count # datacounterで変換したレコードを指定
</match>

td-agentをリスタート

# /etc/init.d/td-agent restart

以上の設定で以下の様なWebサーバのログが出力できると思います。

fluentd06

dfコマンドでディスク使用量をGrowthForecastに渡す設定

サーバのディスク使用量の把握はサーバ運営の基本ですね。
dfコマンドの内容を入力できるプラグインがで公開されています。

fluent-plugin-dfのインストール

# gem install fluent-plugin-df

fluent-plugin-dfの設定

# vi /etc/td-agent/td-agent.conf
# dfからディスク容量を取得
<source>
    type df
    option -k              # dfコマンドのオプション
    interval 30            # 実行間隔。そんな頻繁に書き換わらないので30秒
    tag_prefix df          # 接頭辞デフォルトのdfで良い
    target_mounts /        # マウントの指定。普通に/のみなのでこのまま
    replace_slash true     # スラッシュをアンダーバーに置き換えるようだ
    # tag free_disk        # tag (default is nil)
    rm_percent true        # パーセンテージマークを削除する
    hostname false         # ホストネームを追加する(GFに書きだすのでいらない)
</source>

# GrowthForecastに転送する(ローカル用)
<match df.**> # 上で設定した接頭辞perfをまとめて設定
    type growthforecast
    gfapi_url http://127.0.0.1:5125/api/ # GrowthForecastのURLを指定
    service df # service名を入力(カテゴリ)
    tag_for section # sectionとすると接頭辞(tag)が入る(項目名)
    name_key_pattern .* # パターンを使えるname_keyにあたるもの。この例では全て
</match>

Filesystemが/dev/vda1なら「Home » df » df._dev_vda1」となる。

dfコマンドと同じだが、GrowthForecastで表示される項目はそれぞれ以下の意味になる。
available が残り容量。
capacity が使用割合。
size が全容量。
used が使用容量。


MySQLのスロークエリをGrowthForecastに渡す設定

サーバリソースやWebサーバのステータスをグラフ化できました。他にサーバのボトルネックを把握する上で欠かせないのがMySQLのスロークエリです。

MySQLのスロークエリを出力する

まずはMySQLのスロークエリをlogファイルに出力します。

# vi /etc/my.cnf

[mysqld]セクションに追加

# スロークエリのログを出力する
slow_query_log=ON
slow_query_log_file=/var/log/mysql-slow.log
long_query_time=0.1

ファイル作成して権限変更

# echo -n > /var/log/mysql-slow.log
# chown mysql.mysql /var/log/mysql-slow.log
# chmod 644 /var/log/mysql-slow.log

MySQLの再起動

# /etc/rc.d/init.d/mysqld restart

fluent-plugin-mysqlslowqueryのインストール

こちらは名前の通りMySQLのスロークエリをJSON形式にして取り込んでくれるInputプラグインです。

fluent-plugin-mysqlslowqueryプラグインのページ

プラグインページにある入力形式のサンプル

{
    "user": "root[root]",
    "host": "localhost",
    "host_ip": "",
    "query_time": 0.200270,
    "lock_time": 0.000097,
    "rows_sent": 1,
    "rows_examined": 0,
    "sql": "SET timestamp=1317619058; SELECT * FROM life;"
}
# /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-mysqlslowquery
2 gems installed
Installing ri documentation for myslog-0.0.10...
Installing ri documentation for fluent-plugin-mysqlslowquery-0.0.5...
Installing RDoc documentation for myslog-0.0.10...
Installing RDoc documentation for fluent-plugin-mysqlslowquery-0.0.5...

fluent-plugin-amplifier-filterプラグインをインストール

amplifierは入力されたデータの桁数を変更するプラグインです。

fluent-plugin-amplifier-filterのプラグインページ

なぜ桁数の変更が必要かというと、JSON形式にしたスロークエリのサンプルをご覧ください。query_timeの項目が「0.200270」となっています。GrowthForecastは整数しか扱えないので、このままではグラフ化できません。

そこでamplifierを利用して桁数を変更します。「0.200270」を例にすれば、1000000倍することで「200270」に変更します。つまりクエリタイムが1秒の時は1Mとなります。
# /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-amplifier-filter
Successfully installed fluent-plugin-amplifier-filter-0.1.6
1 gem installed
Installing ri documentation for fluent-plugin-amplifier-filter-0.1.6...
Installing RDoc documentation for fluent-plugin-amplifier-filter-0.1.6...

Fluentdの設定を編集

# vi /etc/td-agent/td-agent.conf
<source>
        type mysql_slow_query
        path /var/log/mysql-slow.log
        tag mysqld.slow_query
        pos_file /var/log/td-agent/mysql-slow.log.pos # 本来要らないはずだがwornが出るので書く。
</source>

<match mysqld.slow_query>
	type amplifier_filter # amplifier_filterプラグインで小数点の位置を変更
	ratio 1000000 # 1000000倍にする
	add_prefix amplifier # タグを付ける
	remove_prefix mysqld.slow_query # タグが増えすぎるとややこしいので削除していく
	key_pattern .*(query_time|lock_time)$ # パターンに一致するレコードの値に適用する
</match>

<match  amplifier.**>
	type numeric_counter # numeric_counterプラグインで範囲を取得する
	unit minute # 1分ごとに取得
	input_tag_remove_prefix amplifier
	aggregate tag
	tag responsetime # タグを付ける
	count_key response
	pattern1 0-1s 0 1000000 # 1秒以下
	pattern2 1s- 1000000 # 1秒以上
</match>

<match responsetime.**>
	type copy
	<store>
		type file
		path /var/log/td-agent/slow
	</store>
	<store>
		type growthforecast
		gfapi_url http://127.0.0.1:5125/api/
		service   mysql # カテゴリ
		section   slow_query # 項目名
	        remove_prefix responsetime
		name_key_pattern .*(query_time|lock_time|rows_examined)$ # クエリタイム、ロックタイム、参照した行数をグラフ化
	</store>
</match>

td-agentを再起動

# /etc/init.d/td-agent restart

スロークエリが記録されてしばらく待つと以下の様なグラフが表示されると思います。

fluentd07

と、順調に設定できたはずのスロークエリですがtd-agentのログを確認すると以下のエラーが…。

# tail -f /var/log/td-agent/td-agent.log
2014-09-03 09:19:01 +0900 [warn]: emit transaction failed  error_class=Encoding::UndefinedConversionError error=#<Encoding::UndefinedConversionError: "\xE3" from ASCII-8BIT to UTF-8>
2014-09-03 09:19:01 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluent-plugin-amplifier-filter-0.1.6/lib/fluent/plugin/out_amplifier_filter.rb:102:in `encode'

う~ん、スロークエリのログがASCII-8BITになっててエンコードエラーになるってことかな?
それくらいなら自力で何とか…force_encoding(“UTF-8”)を使って…なんとか…なりませんでしたorz
当方の設定ミスなのか、Rubyのバグなのか、プラグインのバグなのか、はたまた本体のバグかは判然としませんが、一応グラフ化もできているので、一先ずほっときますw

解決策分かる方、教えてくださいw


以上、サーバのリソースをリアルタイムにグラフ化することができました。

これで全てのツールが無料とは信じられませんね。偉大な開発者の方々に感謝です。



現在のページを共有する



現在のページに関連する記事


おすすめの記事


コメントを残す

プログラミングに関する質問は「日本語でプログラミングの悩みを解決するQ&Aサイト sukegra」をご利用ください。面倒な登録なしでご利用になりれます。