ELK Stackでシステム監視 elasticsearchインデックスのスキーマが勝手に変わる対処 テンプレート作成

監視対象ホストの状態をkibanaのダッシュボードで確認していたら昨日まで正常に表示されていた筈のNTPサーバのoffset等のグラフがゼロ(0)で動かなくなっていた。グラフに線が表示されないなら値が取れていないと思われるがゼロに張り付いているということは値が取れていてそれがゼロということ。 では、取得している値が本当にゼロになっているのかとDiscoverから確認するとゼロではない値が取得されている。ただし、1より遥かに小さい値。

これはインデックスで扱っている数値の型が間違っている可能性が高そう。

elasticsearch インデックスのスキーマが勝手に変わる対処 1
上の画像の赤枠のグラフが値がゼロで張り付いてしまっている。

elasticsearch インデックスのスキーマが勝手に変わる対処 2
正常な頃は上の画像の左半分のようなグラフが表示されていた。
それがこの日の午前9時頃を境に全ての値がゼロになっている。

elasticsearch インデックスのスキーマが勝手に変わる対処 3
Kibanaの左列から Dev Tools をクリックし、中央列のテキストボックスにマッピング確認コマンドを入力する。

GET logstash-2018.02.22/_mapping

インデックスlogstash-2018.02.22 (2018年2月22日)のスキーマ(マッピング)を取得。
_mappingの後に ?pretty または ?pretty=1 を付けても付けなくてもJSON Pretty-Printで返されるようだけど何か勘違いしてるかしら。
入力したら (実行)ボタンを押す。結果は右列に表示される。

もちろん、kibanaからじゃなくて従来通りターミナルでコマンド打ちでも良い。

% curl -XGET '127.0.0.1:9200/logstash-2018.02.22/_mapping?pretty=1' 

FreeBSDのports/pkgでインストールしたcurlで実行するならGETの後ろはシングルクォーテーションで囲むこと。

正常な表示だったころ(2018年2月22日)のスキーマでvalueの型を確認。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "logstash-2018.02.22": {
    "mappings": {
      "collectd": {
        "properties": {
          "value": {
            "type": "float"
          }
        }
      }
    }
  }
}

上の結果は関係ない部分を全て省略している。

値が全てゼロになってしまっている日(2018年2月25日)のスキーマでvalueの型を確認。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "logstash-2018.02.25": {
    "mappings": {
      "collectd": {
        "properties": {
          "value": {
            "type": "long"
          }
        }
      }
    }
  }
}

上の結果は関係ない部分を全て省略している。

正常な頃のスキーマはvalueの型がfloat (32bit浮動小数点数)だったので小数点以下があったが、値がゼロになっているスキーマではそれがlong (64bit符号付整数)になっているので整数しか扱われないと見て良さそう。

インデックスの作り直しは面倒なので今回は無しとして、次に作られるインデックスからはvalueがlongではなくdoubleになるようにしておきたい。 (今回は好みでdoubleにしたがfloatでも可)

Kibanaの左列から Dev Tools をクリックし、中央列のテキストボックスにテンプレートを入力する。今回はvalueだけ型を指定する内容にしているが他も同時に指定してもちろんOK.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
PUT /_template/logstash
{
 "template" : "logstash-*",
 "order" : 1,
 "mappings": {
  "collectd": {
   "properties": {
    "value": {
     "type": "double"
    }
   }
  }
 }
}

elasticsearch インデックスのスキーマが勝手に変わる対処 4
入力したら1行目の右端の (実行)ボタンを押す。右列に acknowleded : true の表示が出たら実行が成功している。

新しいインデックスが作られてから確認する。下は2018年2月26日のインデックスのマッピングを確認する内容。
GET logstash-2018.02.26/_mapping
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "logstash-2018.02.26": {
    "mappings": {
      "collectd": {
        "properties": {
          "value": {
            "type": "double"
          }
        }
      }
    }
  }
}

上の結果は関係ない部分を全て省略している。

elasticsearch インデックスのスキーマが勝手に変わる対処 5
指定したとおりvalueがdouble型になっている。これで安心。

ちなみにインデックスをデータごと一掃したいという場合は同様にDev Toolsで DELETE logstash-* を実行する。

関連記事:

NanoPi NEO2(arm64)用にFilebeatをビルド

「がとらぼ」ではホスト(サーバ)からの情報収集にcollectdを使ってたけど、collectdばかりでは面白くないのでElastic社の軽量エージェントBeatsも使ってみたいかなと。
Beatsはいろいろな機能別beatのシリーズ名みたいなものなのでBeatsという名前のアプリがあるわけではない。今回はログファイルを監視して追加されたログ(行)を送信するFilebeatをNanoPi NEO2 (arm64)用にビルドしてみたい。
ちなみにcollectdでログファイルを監視するならtailプラグインが似たようなもの。ただし、collectdでは基本的に(絶対的に?)文字列の値は送れなくて該当するログの行のカウントや数値だけなので文字列の値(ログそのもの)を送りたいならcollectdは外れるかな。

以下、コマンドの前(行頭)が $ のコマンドは一般ユーザーで実行、 # のコマンドは管理者として実行。(コマンドの前に sudoを付けるか su - でrootになってから実行)
また、この記事ではNanoPi NEO2のOSはarmbianのdebian stretch。違うディストリビューションでは標準で入っているパッケージがarmbianとは違うかもしれないので必要に応じて足す。

ビルド準備

BeatsはGo言語で書かれているということなので先ずはGoのインストール。

# apt-cache search golang
# apt install golang-go

apt-cache searchでGo言語のパッケージ名のキーワードとして golang を探す。表示されたリストにそれらしきパッケージ名が存在すればOK.
apt-get install でパッケージ名を指定してインストール。


~/.bashrc (追記)
export GOPATH=$HOME/.go

GOPATHを指定しておく。場所はどこでも良いので今回は自身のユーザーディレクトリ下の.goということにする。ディレクトリそのものは後で勝手に作られる(筈)。

Beatsの入手

$ go get github.com/elastic/beats
$ cd ~/.go/src/github.com/elastic/beats

$ cd filebeat
$ git checkout v5.6.7
(または最新v6.2.2ならgit checkout v6.2.2)

ビルドとインストール

上から引き続きで実行
$ GOARCH=arm64 go build
$ cp -p filebeat /usr/local/bin/
# cp filebeat.yml /etc/
# mkdir /var/log/filebeat
# mkdir /var/lib/filebeat

FreeBSDに慣れてるので/usr/local/bin にしたけどfilebeatの置き場所は好みで。下のサービス設定用ファイルのfilebeatのpathも置き場所に合わせる。

/lib/systemd/system/filebeat.service (新規)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[Unit]
Description=filebeat
Documentation=https://www.elastic.co/guide/en/beats/filebeat/5.6/index.html
Wants=userwork-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/filebeat -c /etc/filebeat.yml -path.data /var/lib/filebeat -path.logs /var/log/filebeat
Restart=always

[Install]
WantedBy=multi-user.target

設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
### 入力 ###
filebeat.prospectors:
    -
        input_type: log
        paths:
            - /var/log/*.log

### 出力 ###
#elasticsearhに送る場合 (送信先 ホスト192.168.0.2 ポート9200)
#output.elasticsearch:
#  hosts: ["192.168.0.2:9200"]

#logstashに送る場合 (送信先 ホスト192.168.0.2 ポート5043)
output.logstash:
  hosts: ["192.168.0.2:5043"]

テストなので/var/logにあるファイル名が.logで終わるファイル全部を監視する。

Filebeat起動

# systemctl enable filebeat.service   #←サービスを有効化 (最初の1回のみ)
# service filebeat start              #←サービスを開始

データ受信側 Logstashの設定

/usr/local/etc/logstash/test.conf (テスト用設定ファイル)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
input {
    beats {
        port => 5043
    }
}

output {
    stdout {
        codec => rubydebug
    }
}
テスト用の出力先は標準出力とする。

テスト用Logstashの実行

# /usr/local/logstash/bin/logstash  --path.data /tmp -f /usr/local/etc/logstash/test.conf

既に動いているLogstashと別にLogstashを実行するときは--path.data でどこか書き込み可能なディレクトリを指定する。
コマンド実行から暫くは反応が無いように見えるかもしれないけど待っていればlogstashのメッセージの後にfilebeatからのデータが表示されるようになる筈。
なお、ログの表示が停まった場合はログが追加されるようなこと(例えばNanoPi NEOにログインし直すなど)をすると新たなログの行が追加されてそれが表示される(筈)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
    "@timestamp" => 2018-02-27T11:55:04.563Z,
        "offset" => 77635,
      "@version" => "1",
    "input_type" => "log",
          "beat" => {
            "name" => "nanopineo2",
        "hostname" => "nanopineo2",
         "version" => "5.6.7"
    },
          "host" => "nanopineo2",
        "source" => "/var/log/auth.log",
       "message" => "Feb 27 11:55:01 localhost CRON[1753]: pam_unix(cron:session): session opened for user root by (uid=0)",
          "type" => "log",
          "tags" => [
        [0] "beats_input_codec_plain_applied"
    ]
}

こんな感じのが次々に出力される。

関連記事:
Up