使用Fluentd从日志中生成Prometheus指标 (2/2)

这是上次发布的续篇。(我完全忘记了…)
根据预定计划,我们将从WAS Liberty的访问日志中生成响应时间的指标,不仅要生成平均响应时间,还要生成计算响应时间分位数所需的指标。
此外,我们将使用扩展了WAS Liberty默认格式的访问日志格式。

生成指标

我們決定從訪問日誌中生成以下指標。

元データメトリクス名メトリクス・タイプ付加するラベルレスポンス・サイズliberty_response_sizesummaryステータス・コード、パスの一部レスポンス時間liberty_response_timehistogramステータス・コード、パスの一部

我们之前使用的是计数器类型的度量指标,但这次我们将尝试使用摘要和柱状图。
当指定为摘要/柱状图类型时,将生成以下信息。

    • liberty_response_size

liberty_response_size_count: レスポンス・サイズの件数 (アクセス数に相当)
liberty_response_size_sum: レスポンス・サイズの合計値

liberty_response_time

liberty_response_time_count: レスポンス時間の件数 (アクセス数に相当)
liberty_response_time_sum: レスポンス時間の合計値
liberty_response_time_bucket: レスポンス時間のパーセンタイル(quantile,分位数)の算出に使用するデータ

自由威斯敏斯特事务部的准备工作

将访问日志的格式更改为在默认格式的末尾添加以微秒为单位的响应时间的格式。
与上次相同,将访问日志的输出路径/logs/http_access.log放置在Fluentd可以读取的卷内。

<httpEndpoint host="*" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint">
    <accessLogging enabled="true"
                   filePath="/logs/http_access.log"
                   logFormat='%h %u %{t}W "%r" %s %b %D'/>
</httpEndpoint>

准备Fluentd部分

构建形象

这一次,我们决定构建并使用一个仅包含所需功能的镜像,而不是使用之前的Kubernetes Fluentd DaemonSet镜像。只需添加Prometheus插件,我们可以使用以下简单的Dockerfile进行构建。

FROM fluent/fluentd:v1.12.4-debian-1.0
USER 0
RUN gem install fluent-plugin-prometheus -v 2.0.0
USER fluent

流畅.conf 的定义

为了从访问日志中生成上述指标,我们将定义一个名为fluent.conf的文件。
创建的fluent.conf文件如下,但我们会略微补充前一次的差异。

    • regexp パーサーを使用してアクセス・ログをパースしています。

今回は、WAS Liberty のデフォルトのアクセス・ログのフォーマットを拡張しているので、前回使用した apache2 パーサーが使用できません。
apache2 パーサーの実装を参考に、regexp パーサーの定義を作成しました。

前述のように、summary / histogram タイプを使用しています。
histogram タイプの場合、パーセンタイルの計算に使用するバケット(buckets)を定義する必要があります。

バケットの範囲が元データの分散にあっていて、バケットの区切りが細かいほど、より正確なパーセンタイルが算出できると考えられます。
今回は、10000マイクロ秒(=10ミリ秒)から500000000マイクロ秒(500秒)の範囲で、倍々の間隔にしました。

全てのメトリクスに同じラベルを付与するので、labels の指定個所を移動しました。

<source>
  @type prometheus
  @id in_prometheus
  bind "0.0.0.0"
  port 24231
  metrics_path "/metrics"
</source>
<source>
  @type prometheus_output_monitor
  @id in_prometheus_output_monitor
</source>
<source>
  @type tail
  follow_inodes
  # read_from_head true
  path     /logs/http_access.log
  pos_file /logs/http_access.log.pos
  tag *
  <parse>
    # @type apache2
    @type regexp
    expression /^(?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>(?:[^\"]|\\.)*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<res_size>[^ ]*) (?<res_time>[^ ]*)$/
    time_format %d/%b/%Y:%H:%M:%S %z
    types code:integer, res_size:integer, res_time:integer
  </parse>
</source>
<filter logs.http_access.log>
  @type parser
  key_name path
  reserve_data true
  <parse>
    @type regexp
    expression /^(?<path_head>.*\/)(?<path_rest>.*)$/
  </parse>
</filter>
<filter logs.http_access.log>
  @type prometheus
  <metric>
    name liberty_response_size
    desc summary of response size
    type summary
    key res_size
  </metric>
  <metric>
    name liberty_response_time
    desc histogram of response time
    type histogram
    key res_time
    buckets 10000, 50000, 100000, 500000, 1000000, 5000000, 10000000, 50000000, 100000000, 500000000
  </metric>
  <labels>
    code ${code}
    path ${path_head}
  </labels>
</filter>
<match logs.http_access.log>
  @type null
</match>

确认动作

启动WAS Liberty和Fluentd,并访问WAS Liberty上的应用程序。
通过curl访问Fluentd的Prometheus插件端口,并提取指标,可以确认以下信息。

bash-4.4$ curl -s http://localhost:24231/metrics | grep liberty
# TYPE liberty_response_size summary
# HELP liberty_response_size summary of response size
liberty_response_size_sum{code="200",path="/InfraTest/"} 7688.0
liberty_response_size_count{code="200",path="/InfraTest/"} 5.0
liberty_response_size_sum{code="200",path="/ResourceEater/"} 548.0
liberty_response_size_count{code="200",path="/ResourceEater/"} 2.0
liberty_response_size_sum{code="200",path="/ResourceEater/faces/javax.faces.resource/"} 4818.0
liberty_response_size_count{code="200",path="/ResourceEater/faces/javax.faces.resource/"} 2.0
liberty_response_size_sum{code="200",path="/ResourceEater/faces/"} 235822.0
liberty_response_size_count{code="200",path="/ResourceEater/faces/"} 40.0
# TYPE liberty_response_time histogram
# HELP liberty_response_time histogram of response time
liberty_response_time_bucket{code="200",path="/InfraTest/",le="10000.0"} 3.0
liberty_response_time_bucket{code="200",path="/InfraTest/",le="50000.0"} 4.0
liberty_response_time_bucket{code="200",path="/InfraTest/",le="100000.0"} 4.0
liberty_response_time_bucket{code="200",path="/InfraTest/",le="500000.0"} 4.0
liberty_response_time_bucket{code="200",path="/InfraTest/",le="1000000.0"} 5.0
liberty_response_time_bucket{code="200",path="/InfraTest/",le="5000000.0"} 5.0
liberty_response_time_bucket{code="200",path="/InfraTest/",le="10000000.0"} 5.0
liberty_response_time_bucket{code="200",path="/InfraTest/",le="50000000.0"} 5.0
liberty_response_time_bucket{code="200",path="/InfraTest/",le="100000000.0"} 5.0
liberty_response_time_bucket{code="200",path="/InfraTest/",le="500000000.0"} 5.0
liberty_response_time_bucket{code="200",path="/InfraTest/",le="+Inf"} 5.0
liberty_response_time_sum{code="200",path="/InfraTest/"} 587766.0
liberty_response_time_count{code="200",path="/InfraTest/"} 5.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="10000.0"} 1.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="50000.0"} 2.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="100000.0"} 2.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="500000.0"} 2.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="1000000.0"} 2.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="5000000.0"} 2.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="10000000.0"} 2.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="50000000.0"} 2.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="100000000.0"} 2.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="500000000.0"} 2.0
liberty_response_time_bucket{code="200",path="/ResourceEater/",le="+Inf"} 2.0
liberty_response_time_sum{code="200",path="/ResourceEater/"} 15154.0
liberty_response_time_count{code="200",path="/ResourceEater/"} 2.0
・・・以下省略・・・

使用Grafana进行显示

这次,我为了确认起见,将使用 Prometheus 收集指标,并在 Grafana 上显示图形。

使用rate()函数处理liberty_response_time_count可以轻松地将访问量的图表化。
以下的PromQL示例获取了每秒的访问次数,时间范围为5分钟。

rate(liberty_response_time_count{path!="/"}[5m])

平均的响应时间和响应大小,同样可以通过rate()函数进行图形化表示。以下是平均响应时间的PromQL示例。

rate(liberty_response_time_sum{path!="/"}[5m]) / rate(liberty_response_time_count{path!="/"}[5m])

使用rate()函数处理liberty_response_time_bucket之后的结果可通过histogram_quantile()函数进行图形化,从而得到响应时间的百分位数。
例如,若要计算90%分位数,可以采用以下的PromQL语句。

histogram_quantile(0.9, rate(liberty_response_time_bucket{path!="/"}[5m]))
grafana.png

结束了

我已经确认通过WAS Liberty输出的日志可以生成指标。

如果要分析容器的日志,我认为常见的模式是将日志转发到 Elasticsearch 等地方,并在 Kibana 等工具中进行分析和显示。然而,将像访问日志这样大量输出的日志转发和存储到 Elasticsearch 等地方,可能会在容量和性能方面存在问题。

如果使用 Fluentd 来执行高频率的常规分析,并将结果收集和积累为 Prometheus 指标,然后在 Grafana 中查看,这可能会降低一些门槛。

从应用程序生成的日志中提取指标等,可以在各种场景中使用。

    • 参考

Fluentd: Monitoring by Prometheus
GitHub: fluent / fluent-plugin-prometheus
GitHub: fluent / fluentd-docker-image

广告
将在 10 秒后关闭
bannerAds