Grafana/InfluxDB/Fluentdでログを可視化する
monitoringコードはここ。
InfluxDB
Golangで書かれた時系列データベース。今回使うのはv0.13
。前のバージョンと結構違うので注意。
デフォルトでは無効になっている認証を有効にするために設定ファイルを編集して設置する。
$ brew install influxdb # OSX
$ influxd config > influxdb.conf
[http]
...
auth-enabled = true
...
FROM influxdb:0.13
VOLUME /var/lib/influxdb
ADD influxdb.conf /
ENV INFLUXDB_CONFIG_PATH /influxdb.conf
$ docker run -p 8083:8083 -p 8086:8086 myinfluxdb
influxd
コマンドや
:8083
のWebインタフェースの他に
:8086
にHTTP APIが用意されている。
$ curl -i -XPOST http://localhost:8086/query --data-urlencode "q=CREATE USER root WITH PASSWORD 'root' WITH ALL PRIVILEGES"
$ curl -i -XPOST http://localhost:8086/query -u root:root --data-urlencode "q=CREATE DATABASE mydb"
{"results":[{}]}
# Line Protocol(https://docs.influxdata.com/influxdb/v0.13/write_protocols/line/)
$ curl -i -XPOST 'http://localhost:8086/write?db=mydb' -u root:root --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'
(204 No Content)
$ curl -GET 'http://localhost:8086/query?db=mydb' -u root:root --data-urlencode 'q=SELECT * FROM "cpu_load_short"' | jq
{
"results": [
{
"series": [
{
"name": "cpu_load_short",
"columns": [
"time",
"host",
"region",
"value"
],
"values": [
[
"2015-06-11T20:46:02Z",
"server01",
"us-west",
0.64
]
]
}
]
}
]
}
fluent-plugin-influxdb
設定はこんな感じ。
<source>
type tail
path /usr/src/app/test.log
pos_file /etc/td-agent/test.log.pos
tag something.log
format json
</source>
<match *.log>
@type influxdb
host influxdb
port 8086
dbname mydb
user root
password root
</match>
5秒ごとにランダムな値valueのログを出力し続ける。
from twisted.internet import task, reactor
import logging
import json
import random
INTERVAL = 5 # sec
logging.basicConfig(filename='test.log', format='%(message)s', level=logging.INFO)
def somethingHappend():
data = {
"value": random.randint(0, 100),
"event": "something"
}
logging.info(json.dumps(data))
if __name__ == '__main__':
instance = task.LoopingCall(somethingHappend)
instance.start(INTERVAL)
reactor.run()
Grafana
可視化ツール。データソースとしてInfluxDB、Garaphite、Elasticsearchなどが使える。
Kibana(+Elasticsearch)だと 認証するのに有償のShieldプラグインが必要だが、 こちらは最初からできて手軽。
これらのDockerイメージを作って、minikubeで立ち上げてみた。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
grafana-1386260931-lq8wh 1/1 Running 0 2m
influxdb-2543054961-yj1bd 1/1 Running 0 2m
testapp-532457622-269qo 1/1 Running 0 2m
$ curl -i -XPOST http://192.168.99.100:30005/query?db=mydb -u root:root --data-urlencode 'q=SELECT * FROM "something.log" LIMIT 1'
{"results":[{"series":[{"name":"something.log","columns":["time","event","value"],"values":[["2016-08-31T08:38:37Z","something",23]]}]}]}
http://192.168.99.100:30003
admin/adminでログインしてDataSourceにhttp://192.168.99.100:30005
のInfluxDBを設定すると、
Dashboardにグラフやテーブルなどを置いて表示させることができるようになる。
1秒以内に複数のログが発生する場合 (2016-11-07)
時系列DBであるinfluxdbは同じタイムスタンプで複数のデータを持つことができない。 fluentdはv0.14からナノ秒でタイムスタンプを持つようになったので、これを利用することで1秒以内に発生するログも 正常に処理できるようになる。
td-agentをビルドしてfluentdのバージョンを上げる
fluent-plugin-influxdbのtime_precisionはデフォルトでs(秒)になっているが、 これをns(ナノ秒)にしただけでは、(現時点では)秒のままのタイムスタンプが送られるのでうまくいかない。 そのため、以下のようにナノ秒を取れる場合はそれを使い、そうでない場合は無視するように修正した。
nstime = time * (10 ** 9) + (defined?(Fluent::EventTime) ? time.nsec : 0)
プルリクは出した。 自分のプラグインはこんな感じで使うことができる。
td-agent-gem install specific_install && \
td-agent-gem specific_install https://github.com/sambaiz/fluent-plugin-influxdb.git