以下、Fluentdをインストール・設定してうまくいかなかったメモになります。
今回はfluentdのデータをInfluxDBに保存する設定をしてみます。そしてESP8266の温湿度をfluentに投げるところまで、できるだろうか?
やっとここまで来た。最近はほとんど個人用メモになってしまってスミマセン。
fluentdはうまくいかないのでやめて、InfluxdbのHTTP APIで受け取る。
- ログ収集 Fluentdインストール メモ
- Raspi 3+ Elasticsearch インストール 失敗メモ
- fluentd使わない ESP8266からInfluxDB APIに投げる 失敗メモ (今このページを見ています)
- 定期的に温湿度をFLUENTDに送信してグラフを作る 失敗メモ
fluent-plugin-influxdb Plugin インストール
バージョン確認
こちらを見るとfluentd,rubyのバージョンによってfluent-plugin-influxdbのバージョンも変わってくるようなので確認する。
fluent-plugin-influxdb2以降の場合は、fluentd>=1.0.0,ruby>=2.3
$ apt-cache policy ruby ruby: インストールされているバージョン: 1:2.3.3 候補: 1:2.3.3 バージョンテーブル: *** 1:2.3.3 500 500 http://raspbian.raspberrypi.org/raspbian stretch/main armhf Packages 100 /var/lib/dpkg/status $ gem list *** LOCAL GEMS *** bigdecimal (1.2.8) cool.io (1.5.3) did_you_mean (1.0.0) dig_rb (1.0.1) fluent-plugin-influxdb (2.0.0) fluentd (1.3.3) http_parser.rb (0.6.0) influxdb (0.7.0) io-console (0.4.5) json (1.8.3) minitest (5.9.0) msgpack (1.2.6) net-telnet (0.1.1) power_assert (0.2.7) psych (2.1.0) rake (10.5.0) rdoc (4.2.1) serverengine (2.1.0) sigdump (0.2.4) strptime (0.2.3) test-unit (3.1.7) thread_safe (0.3.6) tzinfo (1.2.5) tzinfo-data (1.2018.9) yajl-ruby (1.4.1)
バージョンは問題なさそうなのでインストールする。
$ sudo gem install fluentd fluent-plugin-influxdb
/etc/fluent/fluent.confの設定 fluentからinfluxdbに保存テスト
自動起動しているのでいったんKillしてストップしてstdout(標準出力)されるように手動で起動させる。
$ ps ax | grep fluent $ sudo kill 1111 1111 $ fluentd -c /etc/fluent/fluent.conf -vv
stdout(標準出力)
まずは簡単にInfluxDBに保存できるかテストする。
$ sudo vim /etc/fluent/fluent.conf <match sensor.**>#テスト的に標準出力に出力してみる @type stdout </match>
初期状態のfluent.confだとhttpを入れると「[error]: #0 fluent/supervisor.rb:723:main_process: suppressed same stacktrace」というエラーが出るので外した。
表示された!↓
$ echo '{"host":"test2","lux":106.56888,"humi":98.19,"temp":13.8}' | fluent-cat sensor.air 2019-02-06 09:28:44.297601960 +0900 sensor.air: {"host":"test2","lux":106.56888,"humi":98.19,"temp":13.8}
fluentからinfluxdbに保存テスト
つづいてInfluxdbに保存する設定、<match sensor.**>は1個しか使えないので同時に標準出力はできないみたい。
$ sudo vim /etc/fluent/fluent.conf <match sensor.**> #influxdb DB=sensor、 measurement=airにインサート @type influxdb host localhost dbname sensor measurement air user root password ****** tag_keys ["place"] time_precision s </match>
テストで以下を投げてみる。
$ echo '{ "lux": 6.0, "humi": 54.19, "temp": 23.8}' | fluent-cat sensor.air
2回投げたらうまくsensor.airに保存されていた! しかしluxが6.0ではなく6になっているのが気になる。いやそんなことはなかった。ちゃんと106.56888などの数値も保存された。
$ influx Connected to http://localhost:8086 version 1.7.3 InfluxDB shell version: 1.7.3 Enter an InfluxQL query > use sensor Using database sensor > select * from air name: air time atmo co2 host humi lux o place temp ---- ---- --- ---- ---- --- - ----- ---- 1549090146000000000 8.33658384 test 1549396471000000000 54.19 6 23.8 1549396742000000000 54.19 6 23.8 1549413205000000000 test2 98.19 106.56888 13.8
以下も投げてみたけどうまくいった。しかしDBに反映されるまで1分くらいかかる様子。すぐに保存されているか見るとまるで入ってないので焦る。1分後くらいにもう一度確認するとちゃんと保存されていた。
$ echo '{ "host": "test2","place": "bath","lux": 6106.56888, "humi": 78.19, "temp": 33.8}' | fluent-cat sensor.air $ echo '{ "lux": 4556.03555, "humi": 99.19, "temp": 43.8}' | fluent-cat sensor.air
ESP8266からサーバー(ラズパイ3+)に温湿度を投げる
タイマー ESP8266(Arduino IDE)
ESP8266で使えるタイマーをインストール。Zipをダウンロードして スケッチ > ライブラリをインクルード > Zip形式のライブラリをインストール でインストールする。
2020 11/7 エラーになる。
指定されたフォルダ/zipファイルには有効なライブラリがありません
C:\Users\go160\Documents\Arduino\libraries\TickerScheduler-master
に解凍して直接フォルダを置いても認識されない???
古いバージョンArduino IDE 1.6.13をDLしてやってみる。

6秒ごとにDHT22の温湿度をシリアルプリント
タイマーの部分のみ抜粋↓6秒ごとにDHT22の温湿度をシリアルプリント
#include <TickerScheduler.h> TickerScheduler ts(1); void fluentTicker() { static char buffer[256]; DynamicJsonDocument doc(1024); JsonObject obj = doc.to<JsonObject>(); obj["temp"] = dht.readTemperature();;//温度 obj["humi"] = dht.readHumidity();;//湿度 serializeJson(obj, buffer); Serial.println(buffer); } void setup() { int arg = 1; ts.add(0, 6000, [&](void* arg) {fluentTicker();}, &arg, true); arg++; } void loop() { ts.update(); }
シリアルモニタに6秒ごとにこのように表示された。
{"temp":19.3,"humi":62.3} {"temp":19.3,"humi":62.2}
あとはこれをサーバー(ラズパイ)に投げてfluentで受け取る。
fluent.conf
fluentはtd-agentでインストールできなかったためか?・・・8888はchronografが使っているので?どうなるんでしょうか?InfluxDBの設定ペーz/etc/fluent/fluent.confにport 8888を書くと以下のようなエラーになる。どうやるの?
2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/root_agent.rb:154:in `block (2 levels) in lifecycle' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/root_agent.rb:153:in `each' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/root_agent.rb:153:in `block in lifecycle' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/root_agent.rb:140:in `each' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/root_agent.rb:140:in `lifecycle' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/root_agent.rb:164:in `start' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/engine.rb:274:in `start' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/engine.rb:219:in `run' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/supervisor.rb:799:in `run_engine' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/supervisor.rb:549:in `block in run_worker' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/supervisor.rb:724:in `main_process' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/supervisor.rb:544:in `run_worker' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/lib/fluent/command/fluentd.rb:316:in `<top (required)>' 2019-02-06 14:54:55 +0900 [error]: #0 /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 2019-02-06 14:54:55 +0900 [error]: #0 /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 2019-02-06 14:54:55 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/fluentd-1.3.3/bin/fluentd:8:in `<top (required)>' 2019-02-06 14:54:55 +0900 [error]: #0 /usr/local/bin/fluentd:22:in `load' 2019-02-06 14:54:55 +0900 [error]: #0 /usr/local/bin/fluentd:22:in `<main>' 2019-02-06 14:54:55 +0900 [error]: #0 unexpected error error_class=Errno::EADDRINUSE error="Address already in use - bind(2) for \"0.0.0.0\" port 8888"
@type forward↑(上のエラー)や@type httpに変えてもport 8888を書くとエラーになる。@type httpに変えるとこんなエラー↓
2019-02-06 16:11:48 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/serverengine-2.1.0/lib/serverengine/socket_manager_unix.rb:53:in `initialize' 2019-02-06 16:11:48 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/serverengine-2.1.0/lib/serverengine/socket_manager_unix.rb:53:in `new' 2019-02-06 16:11:48 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/serverengine-2.1.0/lib/serverengine/socket_manager_unix.rb:53:in `listen_tcp_new' 2019-02-06 16:11:48 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/serverengine-2.1.0/lib/serverengine/socket_manager.rb:121:in `block in listen' 2019-02-06 16:11:48 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/serverengine-2.1.0/lib/serverengine/socket_manager.rb:119:in `synchronize' 2019-02-06 16:11:48 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/serverengine-2.1.0/lib/serverengine/socket_manager.rb:119:in `listen' 2019-02-06 16:11:48 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/serverengine-2.1.0/lib/serverengine/socket_manager.rb:128:in `listen_tcp' 2019-02-06 16:11:48 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/serverengine-2.1.0/lib/serverengine/socket_manager_unix.rb:106:in `send_socket' 2019-02-06 16:11:48 +0900 [error]: #0 /var/lib/gems/2.3.0/gems/serverengine-2.1.0/lib/serverengine/socket_manager.rb:155:in `process_peer' 2019-02-06 16:11:48 +0900 [error]: #0 unexpected error error_class=Errno::EADDRINUSE error="Address already in use - bind(2) for \"0.0.0.0\" port 8888" 2019-02-06 16:11:48 +0900 [error]: #0 suppressed same stacktrace
serverengineはRubyで書かれたマルチプロセス実装のフレームワークみたい。このserverengineがうまく動いてないみたい。
Portを変えてみても無理だった。
[error]: #0 fluent/log.rb:362:error: unexpected error error_class=Errno::EADDRINUSE error="Address already in use - bind(2) for \"0.0.0.0\" port 8888"
$ sudo fluent-gem install fluent-plugin-td
# HTTP input # POST http://localhost:8888/<tag>?json=<json> # POST http://localhost:8888/td.myapp.login?json={"user"%3A"me"} # @see http://docs.fluentd.org/articles/in_http
<source> @type forward @label @influxdb port 8888 </source> <label @influxdb> <filter sensor.*> @type stdout </filter> <match sensor.**> #influxdb DB=sensor、 measurement=airにインサート @type influxdb host localhost dbname sensor measurement air user root password ****** tag_keys ["place"] time_precision s </match> </label>
うまくいかない!Fluentは使わない。
HTTP API
データはこのように↓キーはカンマ区切り2個まで、間にスペースをあけない。
‘air,place=bath,host=NodeMCU,temp=8.70 humi=65.70’
curl -i -XPOST "http://192.168.31.53:8086/write?db=test&u=root&p=****" --data-binary 'testtable,temp=5538251.85 hum=652.5245' curl -i -XPOST "http://192.168.31.53:8086/write?db=sensor&u=root&p=****" --data-binary 'air,place=bath,host=NodeMCU,temp=8.70 humi=65.70' 全部一気には入れられないみたい。KeyはMax2つのみ??
終わったと思って再起動して自動でInfluxdbを立ち上げたらpermission deniedになった・・・
$ curl -i -XPOST "http://localhost:8086/write?db=sensor&u=root&p=gonet1600" --data-binary "air,place=bath,host=NodeMCU temp=8.70 humi=65.70 1549507732165550874" curl: (7) Failed to connect to localhost port 8086: Connection refused go@DESKTOP-KVFQL0O:/mnt/c/Users/go160$ curl -i -XPOST "http://192.168.31.53:8086/write?db=sensor&u=root&p=gonet1600" --data-binary 'air,place=bath,host=NodeMCU,temp=8.70 humi=65.70' HTTP/1.1 500 Internal Server Error Content-Type: application/json Request-Id: 436fed8c-2a9c-11e9-80e6-b827eb9dbfd5 X-Influxdb-Build: OSS X-Influxdb-Error: [shard 28] open /var/lib/influxdb/wal/sensor/autogen/28/_00003.wal: permission denied X-Influxdb-Version: 1.7.3 X-Request-Id: 436fed8c-2a9c-11e9-80e6-b827eb9dbfd5 Date: Thu, 07 Feb 2019 05:50:24 GMT Content-Length: 98 {"error":"[shard 28] open /var/lib/influxdb/wal/sensor/autogen/28/_00003.wal: permission denied"}
/var/lib/influxdb/wal/sensor/autogen/28/_00003.walがrootで保存されていたからこうなった。テスト的にsudoでInfluxdbを起動したからこうなった・・・ドジ
-rw-r--r-- 1 root root 7959 2月 7 14:23 _00003.wal
Ardiuino IDE スケッチ
うまくいったけど・・・host→host_1、 temp→temp_1で保存される???
なのでhost→hosts、temp→temprにする。
最初にカラムまで作っておかないとtemp_1のようになるみたい。あとでtempを作成するといままであったtempはtemp_1に移動する・・・
curl -i -XPOST "http://localhost:8086/write?db=sensor&precision=s" --data-binary 'air_survey,place=test,lux=2568.338384 temp=15.9348' influx use sensor 最初にTableやKey・フィールドを入れておく。 INSERT air2,place=test,host=esp32,temp=17.025213452336 humi=56.0211211356
この後にESP32などでデータを送信する。そうしないとtemp_1ができてしまう・・・
#include <ESP8266WiFi.h> #include <Wire.h> #include <DHT.h>//温湿度 DHT22 #include <Arduino.h>//時計 #include <time.h> #include <ESP8266HTTPClient.h>//HTTPClient #include <ArduinoJson.h> //Display #include "SPI.h" #include "Adafruit_GFX.h" #include "Adafruit_ILI9341.h" #define TFT_DC 2 #define TFT_CS 5 Adafruit_ILI9341 display = Adafruit_ILI9341(TFT_CS, TFT_DC); //Wi-Fi情報 #define WIFI_SSID "Xiaomi_wifi" #define WIFI_PASSWORD "gonet1600" //温湿度 DHT22 #define DHTPIN 12//D7 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE, 15); float humidity, temp_c, temp_f, heatindex; //時計 #define JST 3600*9 //タイマー #include <TickerScheduler.h> TickerScheduler ts(1); //Fluentd #define PLACE "living" #define MEASUREMENT "air" #define HOST "ESP8266" const char* influxUrl = "http://192.168.31.53:8086/write?db=sensor"; const char* influxUser = "root"; const char* influxPassword = "****"; //サーバー ラズパイ3+に接続 void postToInfluxDB() { //カンマ・スペースは厳密に //'air,place=bath,host=NodeMCU,temp=8.70 humi=65.70' String influxData = MEASUREMENT; //MEASUREMENT(table) influxData += ",place=" PLACE ",hosts=" HOST; influxData += ",tempr="; influxData += dht.readTemperature(); influxData += " humi="; influxData += dht.readHumidity(); HTTPClient http; http.begin(influxUrl); http.addHeader("Content-Type", "application/x-www-form-urlencoded"); http.setAuthorization(influxUser, influxPassword); int httpCode = http.POST(influxData); http.end(); if (httpCode == HTTP_CODE_OK) { Serial.print( influxData + "NO \n"); } else { Serial.print( influxData + "OK! \n"); } } void setup() { Serial.begin(115200); //Display display.begin(); // connect to wifi. WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("connecting"); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.println(); Serial.print("connected: "); Serial.println(WiFi.localIP()); //温湿度大気計 DHT22 dht.begin(); //時計 configTime( JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp"); display.setRotation(3); display.fillScreen(ILI9341_BLACK); if (WiFi.status() == WL_CONNECTED) { //タイマー int arg = 1; ts.add(0, 30000, [&](void* arg) { postToInfluxDB(); }, &arg, true); arg++; } } void loop() { //時計 time_t t; struct tm *tm; t = time(NULL);//時計 tm = localtime(&t); display.setTextSize(4); display.setCursor(20, 10); display.setTextColor(ILI9341_CYAN, ILI9341_BLACK);//背景を黒に display.printf("%02d/%02d", tm->tm_mon + 1, tm->tm_mday); //月日 display.setCursor(180, 10); char *dayofweek[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; display.printf("%s", dayofweek[tm->tm_wday]); //tm_wday曜日 display.setCursor(20, 90); display.setTextColor(ILI9341_WHITE, ILI9341_BLACK); display.setTextSize(8); display.printf("%02d:%02d", tm->tm_hour, tm->tm_min); //時分 display.setCursor(260, 130); display.setTextSize(3); display.printf(":%02d", tm->tm_sec); //温湿度大気計 DHT22 humidity = dht.readHumidity();// Read humidity (percent) temp_c = dht.readTemperature();// Read temperature as Celsius temp_f = dht.readTemperature(true);// Read temperature as Fahrenheit display.setTextColor(ILI9341_YELLOW, ILI9341_BLACK); display.setTextSize(3); display.setCursor(30, 205); //display.println("TMP:"); display.print(temp_c, 1);//温度表示 小数点1桁に四捨五入 display.println("C"); display.setTextSize(3); display.setCursor(170, 205); //display.println("HUM:"); display.print(humidity, 1);//湿度表示 小数点1桁に四捨五入 display.println("%"); //タイマー ts.update(); delay(200); }
InfluxDB 不具合
Influx
不具合?Tableを作ったのちにデータは入るけど、atmo,humiしかSelectできない???
> INSERT air4,z=room,temp=17.025213452336 humi=56.0211211356 > INSERT air4,z=esp32,lux=23155.125635 atmo=5312.12345 > select * from air4 name: air4 time atmo humi lux temp z ---- ---- ---- --- ---- - 1549604178340294380 56.0211211356 17.025213452336 room 1549604181287148073 5312.12345 23155.125635 esp32 > select temp from air4 > select lux from air4
そして2つ以上のフィールドではデータは入れられない。↓lux、atmo、temp、humiの4つ同時に入れてみたが???エラーになる。
> INSERT air4,z=esp32,lux=23155.125635 atmo=5312.12345 temp=17.025213452336 humi=56.0211211356 ERR: {"error":"unable to parse 'air4,z=esp32,lux=23155.125635 atmo=5312.12345 temp=17.025213452336 humi=56.0211211356': bad timestamp"}
Curl
こちらもフィールド2つならインサートできるが3つからはBad Requestになる・・・???
$ curl -i -XPOST "http://localhost:8086/write?db=sensor&precision=s" --data-binary 'air4,z=test,lux=23155.125635 atmo=5312.12345 temp=17.025213452336 humi=56.0211211356' HTTP/1.1 400 Bad Request $ curl -i -XPOST "http://localhost:8086/write?db=sensor&precision=s" --data-binary 'air4,z=test,lux=23155.125635 atmo=5312.12345 temp=17.025213452336' HTTP/1.1 400 Bad Request $ curl -i -XPOST "http://localhost:8086/write?db=sensor&precision=s" --data-binary 'air4,z=test,lux=23155.125635 atmo=5312.12345' HTTP/1.1 204 No Content
このままでは到底使えない。
原因は一部がフィールドではなく、TAGになってしまっているから。TagとFieldの間に「,」を入れたのが間違い。スペースで区切る。

でも2個以上のフィールドを一度に送るとエラーになる・・・?
> INSERT air5,place=room humi=56.0211211356 > INSERT air5,place=room temp=17.025213452336 humi=56.0211211356 ERR: {"error":"unable to parse 'air5,place=room temp=17.025213452336 humi=56.0211211356': bad timestamp"}
カンマとスペースの使い方が違う!!!!
INSERT air5,place=living,host=esp322 temp=17.025213452336,humi=56.0211211356,atmo=2155.2546394561,co2=440.456413,o=21.123156131313
Key,Key Field,Field,Field
うまくいった。

このページのExploreで調べる。

InfluxDB 調べる
WALはデータベースをリカバリーする際のみ読込まれる追記のみを行うファイル
InfluxDB LOG
Systemd
sudo journalctl -u influxdb.service

参考


FLUENTDは次ページで挑戦していますが、うまくいきませんでした・・・
コメント