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

导航到

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

InfluxData 欣喜地宣布,现在它支持将日志事件数据流式传输到 InfluxDB,并提供适用于 Nginx 和 Apache 等流行服务器的开箱即用模式。日志监控支持是 Telegraf 的强大列表中最新添加的,该列表已包含 90 多个输入和输出数据插件。除了标准格式日志外,Telegraf 的 logparser、自定义日志解析以及基于流行的“grok”模式的模式也得到支持。

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

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

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

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 "https://127.0.0.1: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 "https://127.0.0.1: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="https://127.0.0.1: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 = ["https://127.0.0.1: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 https://127.0.0.1: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

71个错误对于总共只有600个请求来说相当多了!让我们通过使用*获取所有字段并使用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 插件

现在我们已经介绍了如何解析标准“组合日志格式”中的数据,接下来让我们看看如何解析可能包含额外字段的日志。Apache和 Nginx 允许对日志输出进行高级自定义,同样,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 = ["https://127.0.0.1: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 命令行界面

$ influx
Connected to https://127.0.0.1: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

>

太好了!看起来好多了。

接下来是什么?

  • 下载 并开始使用 InfluxDB 1.3.1。
  • 在您的基础设施上寻找 InfluxDB 集群?现在可以评估,开始使用 InfluxDB 企业版。
  • 安排一次与解决方案架构师的 免费 20 分钟咨询,以审查您的 InfluxDB 项目。