背景
阿里云的日志服务(Log Service)是针对日志类数据的一站式服务,2013 年研发,至今已有 5 年多线上运行经验,经历双十一、新春红包等考验。其中,Logtail 作为日志服务的采集 Agent,目前已运行在 100W+ 机器上,为万级别应用提供服务。在经历了集团百万服务器、上万应用的锤炼后,Logtail 在性能、稳定性、运维代价上相对于开源 Agent 更为成熟且具有更高的性价比。
但我们也必须承认,相对主流的采集 Agent(如 Logstash、Beats 系列、Fluentd 等),Logtail 在采集功能上有一定的不足,对于输入源、日志的处理方式的支持不够丰富。为了能够更好地实现与开源生态的融合以及弥补这些不足,我们对 Logtail 进行了增强,为其引入了插件系统,目前已通过插件支持了若干输入源,包括 HTTP、MySQL Query、MySQL Binlog 等。
本文将以 syslog 和 lumberjack 两个插件的使用作为示例,介绍在实战中如何进行 Logstash 与日志服务的对接。
实现原理
如图所示,通过两个插件,我们可以将 Logstash 的输出经过 lumberjack (v1) 或 syslog 协议分发给 Logtail,然后由 Logtail 发送到日志服务后端的 LogHub。此后,用户就可以使用日志服务的所有功能,包括对日志的分析、查询、告警、数据投递等。
配置过程
本节将对使用 lumberjack 和 syslog 插件对接 Logstash 的细节进行详细介绍,并对过程中可能遇到的一些常见问题和解决方法进行说明。在介绍过程中,我们假设 Logstash 和 Logtail 运行于同一节点,并且出于简单,我们只给出必要的配置。
Lumberjack 插件
Lumberjack 协议是由 Elastic 公司在实现 Logstash-forwarder 时所设计的 forwarder 与 Logstash 之间的通信协议,后来随着 Beats 系列的推出,forwarder 逐渐被弃用,但这个协议依旧得到了保留,事实上,Beats 和 Logstash 之间的通信依旧使用此协议。
为了能够实现和 Beats 系列以及 Logstash 的对接,我们为 Logtail 实现了 lumberjack 插件,该插件使得 Logtail 具备和 lumberjack 客户端通信并接收数据的能力,因此,它可以实现 Logstash 以及 Beats 系列和日志服务的对接。更多关于此插件的信息,可以查看我们的文档。
Logstash 端配置
Logstash 的 lumberjack 输出插件能够将 Logstash 采集到的日志通过 lumberjack 协议发送给指定的服务端。该插件是 Logstash 安装时携带的默认插件,不需要独立的安装。为了使用该插件,我们需要对 Logstash 的配置文件进行修改(出于简单,我们只给出必要的配置):
output {
lumberjack {
hosts => ["127.0.0.1"]
port => 5044
codec => "json"
ssl_certificate => "/path/to/server_cert.pem"
}
}
需要注意配置中的 ssl_certificate 参数,这是一个必要参数,也就是说 Logstash 的这个插件要求用户必须指定服务端证书。因为我们是本地使用,对安全性的要求相对不高,这么一个参数实在不太友好,好在我们可以通过创建一个本地自签名的证书来解决这个问题,这个我们会在后面进行介绍。另外,我们将 codec 设置为 JSON,这样更有利于后续的解析。
Logtail 端配置
除了直接登录节点修改配置文件的方式外,日志服务支持在控制台进行采集配置,在配置完成后,日志服务会自动地将相应的配置文件分发给 Logtail,免去用户访问节点的麻烦。此处我们简要介绍如何在控制台配置 Logtail 的 lumberjack 插件:
- 首先登录日志服务的控制台,选择相应的 Project,进行到 Logstore 列表页面。
- 找到希望创建采集配置的 Logstore,点击数据接入向导列对应的图标,进入配置页面。
- 在配置页面中的自定义数据中选择 Logtail 自定义插件,点击下一步。
- 在打开的页面中,填写配置名称(这里我们假设填写的是 logstash-lumberjack),然后在插件配置中填入对 lumberjack 插件的配置。
{
"inputs": [
{
"type": "service_lumberjack",
"detail": {
"BindAddress": "127.0.0.1:5044",
"V1": true,
"V2": false,
"SSLCert": "/path/to/server_cert.pem",
"SSLKey": "/path/to/server_key.pem"
}
}
]
}
简单地解释一下:
- inputs 是 Logtail 插件系统中的一部分,用于表示日志的输入(数据源),每个配置可以通过 inputs 同时指定多个输入,这里我们只使用一个输入,它的类型的
service_lumberjack
,detail 表示对它的具体配置。 - BindAddress 表示 lumberjack 插件监听的地址及端口,和 Logstash 配置中的 hosts 和 port 对应。
- V2 和 V1 的设置表示启用 V1 的协议,这是因为 Logstash 的 lumberjack 输出插件仅支持 V1。
- SSLCert 和 SSLKey 是为了应对 Logstash 的插件必须使用 SSL 的要求,其中 Cert 与 Logstash 配置中的 ssl_certificate 对应,而 Key 指的是这个证书中公钥所对应的私钥。
- inputs 是 Logtail 插件系统中的一部分,用于表示日志的输入(数据源),每个配置可以通过 inputs 同时指定多个输入,这里我们只使用一个输入,它的类型的
- 在填写完成后,点击页面中的下一步进行到应用到机器组页面,选择这个配置所要应用的机器组(关于机器组的概念及创建可见文档),然后点击应用到机器组按钮进行查询分析及可视化页面。
- 在这个界面,我们开启一下全文索引,但先不建立任何的索引,点击下一步进入最后的页面。
- 在最后的这个页面中,因为我们不打算进行任何额外的投递或 ETL,可以直接跳过。
当控制台的配置完成后,日志服务会将配置文件分发到所配置机器组的所有节点,并要求 Logtail 根据这些配置进行状态更新。关于配置是否已分发,可以通过查看 Logtail 的配置文件进行确定:
$ cat /usr/local/ilogtail/user_log_config.json
{
"metrics": {
"##version##project$logstash-lumberjack": {
...
}
}
}
使用日志服务
当完成了这些配置后,我们可以重启 Logstash 来使它的配置生效,此后,Logstash 所采集到的日志就会分发到 Logtail 进而发送到日志服务,我们就可以在查询分析控制台(点击 Logstore 列表页面上的查询即可进入)对得到的日志进行操作了。
在这里我们简单地将 Logstash 的输入设置为 stdin,然后随便给了它几条测试消息,接着我们可以到查询分析控制台看看效果,如下:
可以看到,Logstash 将日志以 JSON 格式打包到了 line 这个字段中,Logtail 直接将这个字段及对应的值发送给了日志服务后端。为了进行分析,我们一般需要对日志的字段进行提取,然后建立索引和统计,这一点可以通过日志服务实现,这里我们简要介绍一下:
- 首先点击查询分析属性(图中红色矩形区域),在弹出菜单中选择设置,右侧会出现设置页面。
- 在设置页面的指定字段查询区域,点击 + 号新建字段,创建索引。
- 如上图所示,字段名称使用的是 line,然后对字段内容建立了 JSON 类型的索引,分为四个子字段,其中 @version 选择为 long 类型,并对 host 和 @version 开启了统计。点击确定完成索引创建后,回到之前的页面。
- 因为新建的索引无法应用到旧数据(我们正在开发对旧数据的索引重建功能),我们采用和之前一样的方式,添加几条新的数据,通过 Logstash 采集并经由 Logtail 发送到日志服务后端。
- 可以看到,原先的 line 字段现在展开成了我们所设置的 JSON 形式,而左侧的快速分析,我们也能看到开启统计的 @version 和 host 两个字段的分布情况(因为数据量较小,所以这里都只有一种类型)。
- 进一步地,我们可以在搜索框进行检索,查询符合我们要求的日志,如下图,我们查询了内容中带 again 的日志。
本地自签名证书创建
这里我们简单地讲一下之前提过的自签名证书的创建,在 Linux 下可以通过 openssl 进行创建,命令如下:
$ openssl req -new > cert.csr
$ openssl rsa -in privkey.pem -out server_key.pem
$ openssl x509 -in cert.csr -out server_cert.pem -req -signkey server_key.pem -days 1001
简单地解释一下:
第一步的过程是创建一个证书申请,会产生两个文件,一个是申请证书的请求文件,另一个是这个证书中公钥对应的加密私钥,分别为 cert.csr 和 privkey.pem。这一步会需要输入一些信息,得注意以下两点:
- 一开始会让提供个密码,这个是加密私钥使用的,需要记住,因为第二步要用。
- 接下来会让输入一系列的证书相关信息,除了 Common Name 这一项以下,随便填就好。Common Name 代表使用此证书的服务器对外服务的 host,本地情况下填 127.0.0.1 就好,总之和上述的 Logstash 配置中的 host 以及 Logtail 配置中的 BindAddress 中的 host 部分相同即可。
- 第二步是从加密私钥中提取未加密私钥,得到 server_key.pem 文件,即 Logtail 配置中的 SSLKey,需要输入第一步中提及的那个密码。
- 第三步是使用私钥来签名证书请求,通过证书申请返回证书,即 server_cert.pem,该文件 Logstash 配置中使用的 ssl_certificate 和 Logtail 配置中的 SSLCert。其中,-days 参数用于指定这个证书的有效时间。
Syslog 插件
为了能够满足用户对 syslog 的采集需求,我们为 Logtail 实现了相应的 Syslog 插件,该插件使 Logtail 具备了和 syslog 代理(比如 rsyslog 等)通信的能力,即作为一个服务器接收代理所收集的 syslog 日志。更多关于此插件的内容可见文档。
由于 Logstash 也支持以 syslog 的形式将它采集的日志进行输出,所以我们也能够通过此插件去接入来自 Logstash 的日志。如下图所示,这种途径更用于同时采集 syslog 和 Logstash 的场景,即在使用 rsyslog 等代理采集 syslog 的同时,接入 Logstash 采集的日志。
Logstash 端配置
Logstash 端的配置需要使用到 Logstash 的 syslog 输出插件,这个插件并不是默认安装的,所以需要使用 logstash-plugin 进行安装,命令如下:
$ ./logstash-plugin install logstash-output-syslog
安装完成后,进行如下配置(这里我们同样只给出必要参数):
output {
syslog {
host => "127.0.0.1"
port => 9000
protocol => "tcp"
rfc => "rfc3164"
}
}
配置中的 host、port 和 protocol 指定了连接 Logtail syslog 插件所启动的服务器所需要的信息,rfc 用于指定 syslog 所使用的协议版本,目前支持 RFC3164 和 RFC5424 两个协议。
Logtail 配置
类似之前对 lumberjack 插件的配置过程,我们同样在控制台向 Logtail 配置 syslog 插件,区别仅在于第 4 步所输入的配置文件内容(Address 和 ParseProtocol 分别对应于 Logstash 端的配置):
{
"inputs": [
{
"type": "service_syslog",
"detail": {
"Address": "tcp://127.0.0.1:9000",
"ParseProtocol": "rfc3164"
}
}
]
}
配置中的 Address、ParseProtocol 和 Logstash 中的配置相对应。当配置被下发到 Logtail 后,插件的功能即可生效。
使用日志服务查看效果
同样,我们重启 Logstash 使用我们的新配置,然后构造一些日志,随后即可在日志服务的控制台查看到这些日志,如下图所示,其中的 _program_: LOGSTASH
说明它们来自于 Logstash。
类似地,我们也可以对其中的字段建立索引来辅助统计查询,比如对 _program_
字段建立索引查看有哪些源会发送 syslog,对 _priority_
建立索引以在查询中筛选优先级更高的日志等。
总结及未来展望
在本文中,我们通过简单地示例说明了如何通过 Logtail 的 lumberjack 和 syslog 插件,实现日志服务对 Logstash 的接入,并给出了详细的配置过程以及可能会遇到的问题及其解决办法。
可以看到,通过 Logtail 插件来实现类似的接入过程会非常便捷,但目前依旧存在着一些限制和改进的空间:
- 就地处理。对于示例中的 lumberjack 插件,我们完全可以对 Logstash 所分发的日志进行二次处理,将其中的 @timestamp 字段按照需要转换成时间戳数字。
- 平台支持。Logtail 插件目前仅支持 Linux 系统。
- 插件数量。Logtail 插件尚不丰富,一方面无法对接所有的开源生态,另一方面也无法满足用户的一些定制化需求。
对于这些问题,我们希望未来能够通过以下几方面的措施进行解决:
- 首先,我们将解决 Logtail 插件跨平台的问题,使得同一个插件能够服务不同平台用户的需求。
- 其次,我们将实现更多的 Logtail 插件,从而能够实现与开源生态的进一步对接。
- 最后,我们将在未来开放 Logtail 插件系统(计划以开源的形式),使得用户可以根据自己的需求,实现满足要求的插件,并具有就地处理日志、扩展数据输入源等方面的能力。