使用 Telegraf 的 Logparser 插件将日志解析到 InfluxDB 中

导航至

警告! 这篇文章有点旧了。请查看最新的 Telegraf 文档 以获取完整的更新。

InfluxData 很高兴地宣布,它现在支持将日志事件数据流式传输到 InfluxDB 的功能,并提供适用于 Nginx 和 Apache 等流行服务器的开箱即用模式。日志监控支持是 Telegraf 令人印象深刻的 90 多个输入和输出数据插件列表中的最新成员。除了标准格式日志外,还支持 Telegraf logparser、自定义日志解析和基于流行的“grok”模式的模式。

什么是 Telegraf? Telegraf 是一个指标收集守护程序,可以从各种输入中收集指标,并将它们写入各种输出中。它是由插件驱动的,用于数据的收集和输出,因此易于扩展。它也是用 Go 编写的,这意味着它是一个编译后的独立二进制文件,可以在任何系统上执行,无需外部依赖项,无需 npm、pip、gem 或其他包管理工具。

使用 Telegraf,您不仅可以解析日志以创建指标并将其存储为时间序列数据,InfluxDB 还能够将原始日志行与指标一起存储。我们应该提醒您,这项新功能并非旨在替代全文搜索工具,而是为了在特定的分类窗口期间帮助进行根本原因分析。因此,如果您正在调查某个时间段内的性能指标,则可以通过正则表达式搜索同一时间段内发生的任何日志错误。所有数据都方便地放在一个地方,可以快速查找和关联数据。

logparser 插件可以在 Telegraf 中使用,将任何日志数据结构化为可查询和可搜索的指标。在本指南中,我们将使用 Telegraf 的内置模式之一来解析“组合日志格式”的日志,这是 Apache 和 Nginx 访问日志中的常见设置。它是通用日志格式的扩展,添加了两个带引号的字符串,分别用于“Referrer”和“User-Agent”

lang:default decode:true">127.0.0.1 ident auth [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://localhost:8083/" "Chrome/51.0.2704.84"

在 Nginx 中,配置您的服务器以输出这样的日志,在 /etc/nginx/nginx.conf 中看起来像这样

log_format vhosts '$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';

access_log /var/log/nginx/access.log vhosts;

在 Apache 中看起来像这样(更多详细信息请参见此处)

"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""

步骤 1 -- 安装 Telegraf

Telegraf 软件包可从 InfluxData 下载页面 获取,适用于许多不同的平台

# Install on Ubuntu:
wget https://dl.influxdata.com/telegraf/releases/telegraf_1.0.0_amd64.deb
sudo dpkg -i telegraf_1.0.0_amd64.deb
service telegraf stop

步骤 2 -- 运行测试指标

首先创建一个临时日志文件

touch /tmp/test.log

接下来,通过运行以下 echo 命令来设置简化的 telegraf.conf 文件。

echo '
[[inputs.logparser]]
  ## file(s) to tail:
  files = ["/tmp/test.log"]
  from_beginning = false
  name_override = "test_metric"
  ## For parsing logstash-style "grok" patterns:
  [inputs.logparser.grok]
    patterns = ["%{COMBINED_LOG_FORMAT}"]

[[outputs.file]]
  ## Files to write to, "stdout" is a specially handled file.
  files = ["stdout"]' >> /tmp/telegraf.conf

该文件告诉 Telegraf 使用 logparser 输入插件和 file 输出插件运行。logparser 输入将跟踪 /tmp/test.log 文件,解析并输出名称为 test_metric 的指标。输出将使用 file 输出插件写入 stdout

现在我们将使用该配置文件来运行 Telegraf

telegraf --config /tmp/telegraf.conf

在 Telegraf 运行时,我们将示例日志行回显到 /tmp/test.log 文件。

bash
echo '127.0.0.1 ident auth [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://localhost:8083/" "Chrome/51.0.2704.84"' >> /tmp/test.log

在 Telegraf 输出中,您应该看到上面的日志行被解析为 InfluxDB 行协议 指标并打印到 STDOUT

test_metric,host=localhost,http_method=GET agent="Chrome/51.0.2704.84",auth="auth",client_ip="127.0.0.1",http_status_code=200i,http_version=1,ident="ident",referrer="http://localhost:8083/",request="/apache_pb.gif",response_bytes=2326i 971211336000000000

解析访问日志并将真实数据写入 InfluxDB

接下来的步骤将基于之前的测试数据,并将真实的访问日志数据解析到 InfluxDB 中。

这些步骤将处理解析 Nginx 日志文件。如果您手头没有日志文件,可以从 此处 下载示例。

步骤 3 -- 安装 InfluxDB

InfluxDB 软件包可从 下载页面 获取,适用于许多不同的平台。

# Install on Ubuntu:
wget https://dl.influxdata.com/influxdb/releases/influxdb_1.0.0_amd64.deb
sudo dpkg -i influxdb_1.0.0_amd64.deb
service influxdb start

步骤 4 -- 配置 Telegraf

首先,我们将重命名默认的 Telegraf 配置文件

mv /etc/telegraf/telegraf.conf /etc/telegraf/telegraf.conf.orig

现在编写一个新的配置文件

echo '
[[inputs.logparser]]
  ## files to tail.
  files = ["/var/log/nginx/access.log"]
  ## Read file from beginning.
  from_beginning = true
  ## Override the default measurement name, which would be "logparser_grok"
  name_override = "nginx_access_log"
  ## For parsing logstash-style "grok" patterns:
  [inputs.logparser.grok]
    patterns = ["%{COMBINED_LOG_FORMAT}"]

[[outputs.influxdb]]
  ## The full HTTP or UDP endpoint URL for your InfluxDB instance.
  urls = ["http://localhost:8086"] # required
  ## The target database for metrics (telegraf will create it if not exists).
  database = "telegraf" # required
  ## Write timeout (for the InfluxDB client), formatted as a string.
  timeout = "5s"
' >> /etc/telegraf/telegraf.conf

这次我们的配置文件将假定您正在本地运行 InfluxDB 实例。我们还将跟踪 /var/log/nginx/access.log 中的 nginx 日志文件。如果您手头没有 Nginx 访问日志,可以从 此处 下载示例。

步骤 5 -- 解析 Nginx 访问日志

现在我们可以启动 Telegraf 服务守护程序

service telegraf start

我们不会看到指标写入 STDOUT,但我们应该看到日志行指示指标正在写入 InfluxDB。

Telegraf 服务日志位于 /var/log/telegraf/telegraf.log

2016/06/16 15:32:50 Output [influxdb] buffer fullness: 600 / 10000 metrics. Total gathered metrics: 600. Total dropped metrics: 0.
2016/06/16 15:32:50 Output [influxdb] wrote batch of 600 metrics in 5.809µs

步骤 6 -- 探索 InfluxDB 中的数据

当我们安装 InfluxDB 时,我们还安装了 Influx CLI 客户端,用于连接和查询数据库。我们可以通过简单地运行 influx 并使用 telegraf 数据库来启动它。

$ influx
Connected to http://localhost:8086 version 1.0.0
InfluxDB shell version: 1.0.0
> USE telegraf
Using database telegraf
> precision rfc3339
>

首先,让我们查询解析后的数据,看看我们有多少指标

> SELECT count(resp_code) FROM nginx_access_log
name: nginx_access_log
----------------------
time			           count
1970-01-01T00:00:00Z	           600

完美!这是 示例日志文件 中可解析指标的数量。

现在让我们看看我们返回了多少错误,使用 count() 函数

> SELECT count(resp_code) FROM nginx_access_log WHERE resp_code >= 400
name: nginx_access_log
----------------------
time			           count
1970-01-01T00:00:00Z	           71

对于总共只有 600 个请求来说,71 个错误有点多!让我们使用 * 抓取所有字段,并使用 LIMIT 限制返回的数量,来查看其中的一些错误。

> SELECT * FROM nginx_access_log WHERE resp_code >= 400 LIMIT 5
name: nginx_access_log
----------------------
time				agent			auth	client_ip	host	http_version	ident	referrer	request	resp_bytes	resp_code	verb
2011-08-22T01:02:01.005Z	okhttp/2.4.0		-	192.168.1.2	tars	1.1		-	-		/huh	0		404	GET
2011-08-22T01:02:01.008Z	Python-urllib/2.7	-	127.0.0.1	tars	1.1		-	-		/huh	0		404	GET
2011-08-22T01:02:02.005Z	Firefox/5.0		-	127.0.0.1	tars	1.1		-	-		/huh	0		404	GET
2011-08-22T01:02:03.006Z	Firefox/5.0		-	127.0.0.1	tars	1.1		-	-		/huh	0		404	GET
2011-08-22T01:02:04.009Z	Firefox/5.0		-	127.0.0.1	tars	1.1		-	-		/huh	0		404	GET

看起来我们有一些 404 错误。如果我们仔细观察,我们可以看到每个 404 错误都来自 /huh 端点的请求。让我们看看每个 404 错误是否都在该端点上——为此我们将使用 distinct() 函数。

> SELECT distinct(request) FROM nginx_access_log WHERE resp_code >= 400
name: nginx_access_log
----------------------
time			          distinct
1970-01-01T00:00:00Z	          /huh
1970-01-01T00:00:00Z	          /foo

看起来可能有一些人也从 /foo 端点收到 404 错误,所以让我们看看有多少

> SELECT count(resp_code) FROM nginx_access_log WHERE resp_code >= 400 AND request = '/foo'
name: nginx_access_log
----------------------
time			           count
1970-01-01T00:00:00Z	           1

太棒了!由于只有一个,这意味着主要问题是用户查询 /huh 端点,现在我们可以着手找出该错误端点的来源。

自定义 Logparser 插件

现在我们已经介绍了如何从标准“组合日志格式”解析数据,让我们来看看解析可能具有其他字段的日志。ApacheNginx 允许对其日志输出进行高度自定义,Logparser 也是如此。

假设我们的 Apache 管理员在每个日志行的末尾添加了 2 个字段

  • 请求的 ID 和
  • 响应时间,以微秒为单位。

虽然从分析角度来看,响应时间可能非常有用,但 ID 可能没有那么有用,所以让我们提出一个 grok 模式来处理这个问题。

假设日志行看起来像这样(请参阅 此处 的完整文件)

127.0.0.1 - - [22/Aug/2011:10:02:59 +0900] "GET /huh HTTP/1.1" 404 0 "-" "Firefox/5.0" f18064bf-a4c5-4fd9-9cf8-37aff27382c5 3648

它是组合日志格式,末尾添加了 UUID 和整数。那么,我们如何解析它呢?

Telegraf Grok Logparser

为了解析自定义日志文件,我们必须为 Telegraf 创建自定义“grok”模式。logparser 插件使用略微修改的 logstash “grok” 模式版本,格式为

%{<capture_syntax>[:<semantic_name>][:<modifier>]}

Telegraf 有许多自己的内置模式,并且还支持 Logstash 的 内置模式。了解 grok 模式的最佳方法是阅读 Logstash 文档,该文档可在此处 获取

设置自定义日志模式

Telegraf 允许在单独的文件中或直接在配置文件中指定自定义模式。让我们更改配置文件以包含我们的自定义模式。

service telegraf stop
vim /etc/telegraf/telegraf.conf

telegraf.conf

[[inputs.logparser]]
  ## files to tail.
  files = ["/var/log/myapp/access.log"]
  ## Read file from beginning.
  from_beginning = true
  ## Override the default measurement name, which would be "logparser_grok"
  name_override = "my_log"
  ## For parsing logstash-style "grok" patterns:
  [inputs.logparser.grok]
    patterns = ["%{CUSTOM_LOG}"]
    custom_patterns = '''
      CUSTOM_LOG %{COMBINED_LOG_FORMAT} %{UUID} %{NUMBER:response_time_us:int}
    '''

[[outputs.influxdb]]
  ## The full HTTP or UDP endpoint URL for your InfluxDB instance.
  urls = ["http://localhost:8086"] # required
  ## The target database for metrics (telegraf will create it if not exists).
  database = "telegraf" # required
  ## Write timeout (for the InfluxDB client), formatted as a string.
  timeout = "5s"

请注意,我们需要添加 CUSTOM_LOG 模式,并告诉 Telegraf 在解析时使用 %{CUSTOM_LOG} 模式。

让我们回顾一下此模式中的字段

  • CUSTOM_LOG 是模式的名称。
  • %{COMBINED_LOG_FORMAT} 是内置模式的名称。

  • %{UUID} 使用 Logstash 内置的 UUID 模式来识别日志文件的这部分,但不存储它。
  • %{NUMBER:response_time_us:int} 使用 Logstash 内置的 NUMBER 模式。它将此字段命名为 response_time_us 并将其转换为 int

解析日志和分析数据

现在我们的配置文件已设置好,我们可以再次运行 Telegraf 服务(但首先请确保您在 /var/log/myapp/access.log 中有一个文件,您可以从 此处 获取示例。)

service telegraf start

一旦指标写入,我们可以再次进入 influx CLI

$ influx
Connected to http://localhost:8086 version 1.0.0
InfluxDB shell version: 1.0.0
> USE telegraf
Using database telegraf
> precision rfc3339

现在我们可以访问响应时间了,让我们看看我们的平均值和第 95 个百分位数响应时间是多少

> SELECT mean(response_time_us),percentile(response_time_us,95) FROM my_log
name: my_log
------------
time				mean		percentile
1970-01-01T00:00:00Z	        912411.36	10078023

哎呀,似乎有点高,所以让我们看一下一些响应时间非常长的指标

> SELECT * FROM my_log WHERE response_time_us > 10078023 LIMIT 5
name: my_log
------------
time				agent			auth	client_ip	host	http_version	ident	referrer	request		resp_bytes	resp_code	response_time_us	verb
2011-08-22T01:02:01.008Z	Firefox/5.0		userb	127.0.0.1	tars	1.1		-	-		/large.jpg	10485760	200		10181259		GET
2011-08-22T01:02:04.004Z	Firefox/5.0		usera	127.0.0.1	tars	1.1		-	-		/large.jpg	10485760	200		10110514		GET
2011-08-22T01:02:06.004Z	Python-urllib/2.7	-	127.0.0.1	tars	1.1		-	-		/large.jpg	10485760	200		10132756		GET
2011-08-22T01:02:10.002Z	Firefox/5.0		userb	192.168.1.2	tars	1.1		-	-		/large.jpg	10485760	200		10101485		GET
2011-08-22T01:02:11.006Z	Firefox/5.0		-	127.0.0.1	tars	1.1		-	-		/large.jpg	10485760	200		10144209		GET

啊哈!这些指标正在提供一个非常大的图像文件。让我们忽略这些,看看小请求情况下的响应时间是多少

> SELECT mean(response_time_us),percentile(response_time_us,95) FROM my_log WHERE resp_bytes < 4096
name: my_log
------------
time				mean				percentile
1970-01-01T00:00:00Z	4003.456043956044	7633

>

太棒了!这看起来好多了。

下一步是什么?