使用 Telegraf 的 Logparser 插件将日志解析到 InfluxDB 中
作者 Cameron Sparr / 产品,公司
2016年6月23日
导航到
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 项目。