<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Fluentd | 伪架构师</title>
    <link>/tags/fluentd/</link>
      <atom:link href="/tags/fluentd/index.xml" rel="self" type="application/rss+xml" />
    <description>Fluentd</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Wed, 11 Aug 2021 20:06:06 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>Fluentd</title>
      <link>/tags/fluentd/</link>
    </image>
    
    <item>
      <title>（空想场景）使用 Prometheus 监控特定日志行数</title>
      <link>/post/line-count-to-promethes/</link>
      <pubDate>Wed, 11 Aug 2021 20:06:06 +0800</pubDate>
      <guid>/post/line-count-to-promethes/</guid>
      <description>

&lt;blockquote&gt;
&lt;p&gt;感谢 @云原生小白 提供线索&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;在系统的监控过程中，有时我们只是想要知道一些特定内容的出现数量或者频度，并不关心他的具体内容，而且也不想特意部署一个 Loki 或者 Elasticsearch，这时就可以使用 Fluentd 花里胡哨的插件功能来完成任务了。&lt;/p&gt;

&lt;p&gt;Fluentd 有一个 &lt;a href=&#34;https://docs.fluentd.org/monitoring-fluentd/monitoring-prometheus&#34; target=&#34;_blank&#34;&gt;Prometheus 插件&lt;/a&gt;，能够提供 Prometheus 接口提供采集数据，插件需要用 &lt;code&gt;fluent-gem&lt;/code&gt; 进行安装，如果在 Docker 中的话，可以使用下列 Dockerfile：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-dockerfile&#34;&gt;FROM fluentd:v1.9.1-1.0
USER root
RUN fluent-gem install fluent-plugin-prometheus
USER fluent
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这个插件的基本配置方式是，提供一个 &lt;code&gt;promethues&lt;/code&gt; 的类型，包含一个 &lt;code&gt;&amp;lt;metric&amp;gt;&lt;/code&gt; 元素用于对指标结构进行定义。例如文档中使用的：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;  @type prometheus
  &amp;lt;metric&amp;gt;
    name fluentd_input_status_num_records_total
    type counter
    desc The total number of incoming records
    &amp;lt;labels&amp;gt;
      tag ${tag}
      hostname ${hostname}
    &amp;lt;/labels&amp;gt;
  &amp;lt;/metric&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这种指标放在 &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt; 用于指示输入数量，而放在 &lt;code&gt;&amp;lt;match&amp;gt;&lt;/code&gt; 中则可以监控输出数量。&lt;/p&gt;

&lt;p&gt;这里定义了一个名为 &lt;code&gt;fluentd_input_status_num_records_total&lt;/code&gt; 的指标，其类型为 &lt;code&gt;counter&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;定义指标之后，还要将其暴露给 Prometheus：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;&amp;lt;source&amp;gt;
  @type prometheus
  bind 0.0.0.0
  port 24231
  metrics_path /metrics
&amp;lt;/source&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这段配置定义了一个监听 &lt;code&gt;24231&lt;/code&gt; 端口的 Prometheus 端点，路径为 &lt;code&gt;/metrics&lt;/code&gt;。&lt;/p&gt;

&lt;h2 id=&#34;举个栗子&#34;&gt;举个栗子&lt;/h2&gt;

&lt;p&gt;接下来用一个完整场景来展示这个例子，假设我们要监控 &lt;code&gt;/logs/input.txt&lt;/code&gt; 中的 &lt;code&gt;warning&lt;/code&gt; 数量，会采用文末的完整配置，分段解释如下：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;source&amp;gt;&lt;/code&gt; 段定义采集文件名称&lt;/li&gt;
&lt;li&gt;第一个 &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt; 中使用 &lt;code&gt;@type promethues&lt;/code&gt; 来监控输入数量，生成指标 &lt;code&gt;fluentd_input_status_num_records_total&lt;/code&gt;，类型为 &lt;code&gt;counter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;第二个 &lt;code&gt;&amp;lt;filter&amp;gt;&lt;/code&gt; 用 &lt;code&gt;@type grep&lt;/code&gt; 的正则表达式插件对输入进行过滤&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;match&amp;gt;&lt;/code&gt; 节中使用 &lt;code&gt;@type copy&lt;/code&gt; 对输出进行分流&lt;/li&gt;
&lt;li&gt;第一个 &lt;code&gt;&amp;lt;store&amp;gt;&lt;/code&gt; 输出 &lt;code&gt;fluentd_output_status_num_records_total&lt;/code&gt; 的 Promethues 指标，对过滤出来的文本进行计数&lt;/li&gt;
&lt;li&gt;第二个 &lt;code&gt;&amp;lt;store&amp;gt;&lt;/code&gt; 将输出内容展示在 &lt;code&gt;stdout&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;配置结束之后启动采集过程，可以使用类似如下脚本：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;#!/bin/sh
docker run -it --rm \
        -v $(pwd)/etc:/etc/fluentd \
        -v $(pwd)/log:/data \
        -p 12345:12345 \
        fluentd:prom \
        fluentd -c /etc/fluentd/fluentd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;启动之后，我们向日志中输出内容，例如 &lt;code&gt;echo &amp;quot;warn&amp;quot; &amp;gt;&amp;gt; input.txt&lt;/code&gt;，会看到 &lt;code&gt;fluentd&lt;/code&gt; 日志输出了类似 &lt;code&gt;2021-08-14 07:06:55.688191458 +0000 custom.log: {&amp;quot;message&amp;quot;:&amp;quot;warn&amp;quot;}&lt;/code&gt; 的内容，如果使用 &lt;code&gt;curl&lt;/code&gt; 访问开放出来的 &lt;code&gt;:12345/metrics&lt;/code&gt;，会看到输出中的如下内容：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;fluentd_input_status_num_records_total{tag=&amp;quot;custom.log&amp;quot;,hostname=&amp;quot;757214c8a91a&amp;quot;} 2.0      │➜  log  vim fluentd.conf
fluentd_output_status_num_records_total{tag=&amp;quot;custom.log&amp;quot;,hostname=&amp;quot;757214c8a91a&amp;quot;} 1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这是很常见的指标格式，如果在 Kubernetes 中，对 Pod 进行注解，纳入采集范围，就可以像其它监控指标一样使用了。&lt;/p&gt;

&lt;h2 id=&#34;fluentd-conf&#34;&gt;fluentd.conf&lt;/h2&gt;

&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;&amp;lt;source&amp;gt;
  @type tail
  path /data/input.txt
  pos_file /data/input.pos
  tag custom.log
  &amp;lt;parse&amp;gt;
    @type none
  &amp;lt;/parse&amp;gt;
&amp;lt;/source&amp;gt;
&amp;lt;filter custom.**&amp;gt;
  @type prometheus
  &amp;lt;metric&amp;gt;
    name fluentd_input_status_num_records_total
    type counter
    desc The total number of incoming records
    &amp;lt;labels&amp;gt;
      tag ${tag}
      hostname ${hostname}
    &amp;lt;/labels&amp;gt;
  &amp;lt;/metric&amp;gt;
&amp;lt;/filter&amp;gt;
&amp;lt;filter custom.**&amp;gt;
  @type grep
  &amp;lt;regexp&amp;gt;
    key message
    pattern /warn/
  &amp;lt;/regexp&amp;gt;
&amp;lt;/filter&amp;gt;
&amp;lt;match custom.**&amp;gt;
  @type copy
  &amp;lt;store&amp;gt;
    @type prometheus
    &amp;lt;metric&amp;gt;
      name fluentd_output_status_num_records_total
      type counter
      desc The total number of outgoing records
      &amp;lt;labels&amp;gt;
        tag ${tag}
        hostname ${hostname}
      &amp;lt;/labels&amp;gt;
    &amp;lt;/metric&amp;gt;
  &amp;lt;/store&amp;gt;
  &amp;lt;store&amp;gt;
    @type stdout
&amp;lt;/match&amp;gt;

&amp;lt;source&amp;gt;
  @type prometheus
  bind 0.0.0.0
  port 12345
  metrics_path /metrics
&amp;lt;/source&amp;gt;

&amp;lt;source&amp;gt;
  @type prometheus_output_monitor
  interval 10
  &amp;lt;labels&amp;gt;
    hostname ${hostname}
  &amp;lt;/labels&amp;gt;
&amp;lt;/source&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    
  </channel>
</rss>
