<p>I'd like to parse ingress nginx logs using fluentd in Kubernetes. That was quite easy in Logstash, but I'm confused regarding fluentd syntax.</p>

<p>Right now I have the following rules:</p>

<pre><code>&lt;source&gt;
  type tail
  path /var/log/containers/*.log
  pos_file /var/log/es-containers.log.pos
  time_format %Y-%m-%dT%H:%M:%S.%NZ
  tag kubernetes.*
  format json
  read_from_head true
  keep_time_key true
&lt;/source&gt;

&lt;filter kubernetes.**&gt;
  type kubernetes_metadata
&lt;/filter&gt;
</code></pre>

<p>And as a result I get this log but it is unparsed:</p>

<pre><code>127.0.0.1 - [127.0.0.1] - user [27/Sep/2016:18:35:23 +0000] "POST /elasticsearch/_msearch?timeout=0&amp;ignore_unavailable=true&amp;preference=1475000747571 HTTP/2.0" 200 37593 "http://localhost/app/kibana" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Centos Chromium/52.0.2743.116 Chrome/52.0.2743.116 Safari/537.36" 951 0.408 10.64.92.20:5601 37377 0.407 200
</code></pre>

<p>I'd like to apply filter rules to be able to search by IP address, HTTP method, etc in Kibana. How can I implement that?</p>

<p>Pipelines are quite different in logstash and fluentd. And it took some time to build working Kubernetes -> Fluentd -> Elasticsearch -> Kibana solution.</p>

<p>Short answer to my question is to install <strong>fluent-plugin-parser</strong> plugin (I wonder why it doesn't ship within standard package) and put this rule after <strong>kubernetes_metadata</strong> filter:</p>

<pre><code>&lt;filter kubernetes.var.log.containers.nginx-ingress-controller-**.log&gt;
  type parser
  format /^(?&lt;host&gt;[^ ]*) (?&lt;domain&gt;[^ ]*) \[(?&lt;x_forwarded_for&gt;[^\]]*)\] (?&lt;server_port&gt;[^ ]*) (?&lt;user&gt;[^ ]*) \[(?&lt;time&gt;[^\]]*)\] "(?&lt;method&gt;\S+[^\"])(?: +(?&lt;path&gt;[^\"]*?)(?: +\S*)?)?" (?&lt;code&gt;[^ ]*) (?&lt;size&gt;[^ ]*)(?: "(?&lt;referer&gt;[^\"]*)" "(?&lt;agent&gt;[^\"]*)")? (?&lt;request_length&gt;[^ ]*) (?&lt;request_time&gt;[^ ]*) (?:\[(?&lt;proxy_upstream_name&gt;[^\]]*)\] )?(?&lt;upstream_addr&gt;[^ ]*) (?&lt;upstream_response_length&gt;[^ ]*) (?&lt;upstream_response_time&gt;[^ ]*) (?&lt;upstream_status&gt;[^ ]*)$/
  time_format %d/%b/%Y:%H:%M:%S %z
  key_name log
  types server_port:integer,code:integer,size:integer,request_length:integer,request_time:float,upstream_response_length:integer,upstream_response_time:float,upstream_status:integer
  reserve_data yes
&lt;/filter&gt;
</code></pre>

<p>Long answer with lots of examples is here: <a href="https://github.com/kayrus/elk-kubernetes/" rel="noreferrer">https://github.com/kayrus/elk-kubernetes/</a></p>
