Help us understand the problem. What is going on with this article?

Fluentdのin_httpプラグインでJSONを受け取るときのTip

More than 1 year has passed since last update.

はじめに

fluentdのin_httpプラグインを使うと、一般的なHTTP POSTメソッドでJSONを投げ込むことでfluentdにデータを送ることができます。
その時に微妙に引っかかった点について書いていきます。

なお、ここではtd-agent-2.3.6-0.el6.x86_64を使用したときの話を書いているので後継バージョンで異なる可能性があります。

in_httpプラグインについて

ビルトインに含まれるプラグインで、HTTPで投げ込めます。

<source>
  @type http
  port 9880
  bind 0.0.0.0
  body_size_limit 32m
  keepalive_timeout 10s
  add_remote_addr true
</source>

上記のような設定時は以下のように投げ込むことでデータを入れられます。

curl -X POST -d 'json={"message":"TEST","user":"cuturn"}' http://example.com:9880/fluentd.tag.to -v

ポイントは、json={JSON} という形で投げ込むことです。また、in_httpプラグインはin_tailやin_tcpと違ってタグを送り元が決めることができることがポイントです。特にヘッダを指定する必要はありません。

ただし、上記設定はJSONデータ部分が誤っていても200OKが返ってしまうという問題があります。

普通にやるとJSONが間違っててもエラーを返さないので、少し設定を修正しましょう

通常通りの設定で動かすと、実はJSON文字列が多少間違っててもエラーレスポンスを返しません。json={}の形でさえあれば、200OKを返します。これはデバッグ上非常に宜しくありません。またlog_level debugとしたとしても、何のログもでてきません。

そこで、以下のようにformatを指定します。

<source>
  @type http
  port 9880
  bind 0.0.0.0
  body_size_limit 32m
  keepalive_timeout 10s
  add_remote_addr true
  format json
</source>

上記のように設定すると、以下のようなCURLで投げ込むことができます。json=は不要になりました。

curl -X POST -d '{"message":"TEST","user":"cuturn"}' http://example.com:9880/fluentd.tag.to -v

間違ったJSONを送った場合は、送信コマンド/応答含めて以下のような感じになります。

$ curl -X POST -d '{"message":"TEST","user":"cuturn",}' http://example.com:9880/fluentd.tag.to -v
...
> POST /log HTTP/1.1
> Host: example.com:9880
> User-Agent: curl/7.56.1
> Accept: */*
> Content-Length: 35
> Content-Type: application/x-www-form-urlencoded
>
...
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 400 Bad Request
< Content-Type: text/plain
< Connection: Keep-Alive
< Content-Length: 80
<
400 Bad Request
Received event is not json: {"message":"TEST","user":"cuturn",}
* STATE: PERFORM => DONE handle 0x600057950; line 1993 (connection #0)
* multi_done
* Connection #0 to host example.com left intact
* Expire cleared

というわけで、必ず安定してjsonを送れる自信があるならいいですが、フォーマット間違えたときにきちんと失敗した旨受け取りたい場合はformatを指定するよう設定しましょう。

HTTPS化したいとき

HTTPSで受け取りたい場合は、同サーバ上にNginxを立ててリバースプロキシするのがオススメになります。以下のような設定を/etc/nginx/conf.d/に置くことで、Nginx経由でfluentdへの通信が通るようになります。cipherとかログ設定とかSSLとかは適宜どうにかしてください。

### /etc/nginx/conf.d/fluentd.conf
server {
    listen                      443;
    server_name                 example.com;

    ssl                         on;
    ssl_certificate             /etc/nginx/ssl/server.crt;
    ssl_certificate_key         /etc/nginx/ssl/server.pem;
    ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers                 HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;

    #charset koi8-r;
    access_log  /var/log/nginx/fluentd.access.log  main;

    location / {
        proxy_set_header Host             $host;
        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_pass http://localhost:9880/;
    }
}

なお、X-Forwarded-Forヘッダを設定することでFluentdはREMOTE_ADDRフィールドにこのヘッダ内容を入れてくれます。これでばっちり送信元情報が使えます。BIG-IPや他のLoadBalancerを導入する場合も、同じ考え方をしてください。

またin_httpプラグインはtd-agent.logにアクセスログを出してくれないので、アクセスログが欲しいというだけであったとしてもNginxを立ててリバースプロキシする価値はあるかもしれません。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away