Logstash 基础

介绍 Logstash 的相关基础知识

Logstash 架构

本节内容参考于 TheLogStashBook。这里不是简单的指 Logstash 这个应用的架构,而是基于 Logstash 建立的整个日志收集处理的架构

基于 Logstash 构建的日志收集处理体系是基于消息的,整个系统分别由四个组件组成。

  1. Shipper: 搬运者,将事件发送到 Logstash 。一般来说在应用服务所在的机器上只需要部署该组件。
  2. Broker and Indexer: 收集事件并进行处理,完成如数据过滤,数据格式化等,然后传输到指定存储系统或是进行在本地数据持久化等。
  3. Search and Storage: 用于存储和搜索事件。
  4. Web Interface: 网络接口。简单来说就是通过 Web 向用户展示数据并提供检索服务等。

logstash架构

Broker and Indexer 一般均由 Logstash 担当,除此之外,logstash 也可以同时作为 Shipper ,可以理解为一种自收自发的模式。不过 Logstash 同时作为 Shipper 的话,就表示每台应用服务器的机器都需要部署 Logstash 实例,比起 filebeat 这种专门用于收集发送的应用资源消耗更大(filebeat 也可以跳过 Logstash ,直接将事件传输到如 Elasticsearch 的存储服务,但是 filebeat 在数据处理方面过于薄弱)。
Search and Storeage 一般就是指 Elasticsearch ,而 Web Interface 通常就是 kibana 了。

Logstash 设置

通过 deb 或是 rpm 安装的 Logstash ,相关设置默认放在 /etc/Logstash 。/etc/Logstash 下有以下文件和文件夹。

  1. conf.d : 用于存储 Logstash 相关管道配置的文件夹。以服务方式启动的 Logstash 将会读取该文件夹下的所有 *.conf 文件。
  2. Logstash.yml : Logstash 的设置项文件。所有可以通过命令行启动指定的参数都可以在该文件中找到并设置,包括上述提到的读取 *.conf 文件的路径,可以改变 path.config 来改变要读取的 *.conf 文件的位置。
  3. jvm.options : Logstash 是依赖于 JVM 运行的,可以通过改设置文件改变 JVM 的参数。
  4. log4j2.properties : Logstash 应用本身用到的日志服务(log4j)的设置项。
  5. startup.options : 在 /usr/share/Logstash/bin 下有脚本 system-install ,用于安装 Logstash 。而 startup.options 就是安装时用到的参数。例如在安装时会用到 java ,可以通过 startup.options 改变 java 的路径,还有诸如应用的用户(通过服务启动的 Logstash 应用的用户为 logstash),服务名等信息。不过如果想要 startup.options 中的设置项生效,只能执行 system-install 脚本,重新安装 Logstash 。

Logstash 作为服务启动

在不同的平台上让 Logstash 作为启动是有所不同的,以下为常见平台的启动方式。

DistributionService System
Ubuntu 16.04 and newersystemd
Ubuntu 12.04 through 15.10upstart
Debian 8 "jessie" and newersystemd
Debian 7 "wheezy" and oldersysv
CentOS (and RHEL) 7 and newersystemd
CentOS (and RHEL) 6upstart

Logstash 如何工作

Logstash 的工作分为以下三个步骤。

  1. input
  2. filter (可选)
  3. output

Logstash 通过事件处理管道协调三者的执行,即 input、filter、output。
Logstash 管道的每个 input 阶段都有一个其自己的线程处理。input 将事件写入一个中心队列,这个队列可能存在于内存中(默认),也可能存在于硬盘中。然后管道的工作线程会将中心队列中的事件批量出队,然后通过 filter 进行事件的过滤、处理,最后再将经过处理的事件交给 output ,执行事件的输出。
logstash工作概念图

Logstash 的整个工作流程,input,filter,ouput 三者对外表现为线性地对数据进行收集、处理,即抽象为管道,但是实际上收集者与处理者是分离的,通过队列进行数据的传递。
对于用户来说,logstash 的工作流程是线性的,事件一个一个的进入管道,一个一个的被处理,方便用户理解,配置。而内部是利用队列将收集与处理的逻辑分离了开来,这样可以适当的提高代码的可维护性,并且可以提高整体的执行效率,因为收集到的事件会先存进队列中,如果队列是存在于内存中的,就相当于处理流程中添加了缓存,同时可以灵活地给分配线程去分别完成收集和处理。

Logstash 配置

上面由提到,以服务的方式启动的 Logstash 会读取 /etc/Logstash/conf.d 下的 *.conf 配置文件,这些配置文件就是上面提到的关于 input、filter、output 的相关配置,配置文件的格式如下。

# This is a comment. You should use comments to describe
# parts of your configuration.
input {
  ...
}

filter {
  ...
}

output {
  ...
}

Logstash 将各项功能都视为一个个插件,通过配置插件使用具体的功能。关于插件的详情参考: Input Plugins, Output Plugins, Filter Plugins, Codec Plugins

Input Plugins, Output plugins, Filter Plugins 的用处不用多说,而 Codec Plugins 主要是用于数据格式的处理(如json格式的数据,或是多行数据),作用于 input 或是 ouput 。下面为处理 json 输入数据的例子。

# This is a comment. You should use comments to describe
# parts of your configuration.
input {
  file {
    path => "/var/log/json_format_log"
    codec => "json"
  }
}

filter {
  ...
}

output {
  ...
}

多个管道

如果想在一个 Logstash 进程中使用多个管道,可以通过配置 pipelines.yml 文件实现,pipelines.yml 一般来说是不存在的,在需要时再创建,位于 Logstash 的设置文件路径,通常来说就是 /etc/Logstash 。配置文件的结构如下。

- pipeline.id: my-pipeline_1
  path.config: "/etc/path/to/p1.config"
  pipeline.workers: 3
- pipeline.id: my-other-pipeline
  path.config: "/etc/different/path/p2.cfg"
  queue.type: persisted

上述的配置例子,主要是定义了管道的 id ,指定了管道的配置文件所在路径,配置了工作者线程数量或是开启持久化队列(即将上述提到的中心队列实现持久化,可以说是在硬盘中实现队列,可以有效防止意外宕机导致 Logstash 数据丢失)。其他管道相关的配置项没有进行配置的话,将使用 Logstash.yml 中的定义的配置。

使用多管道,可以在一个 Logstash 实例中处理多个事件流而不共享 input, filter, output 配置。
而且对于不同的事件流,可以使用不同的管道配置,在有限的资源中总是会存在优先级,多管道下可以根据事件的优先级配置资源。
另外,每个管道的持久化队列以及 dead letter queues (死信队列) 是相互独立的,会以管道 id 作为命名。

Logstash 部署方案

Logstash 的使用一般都是用于搭建 ELK ,现在用搭建 ELK 为例子,讲述一下相关的 Logstash 部署方案。

Logstash 自收自发

这种方式就是上面提到的,logstash 实例同时作为 Shipper , Broker 和 Indexer 。 使用 file 插件收集日志,然后继续完成相应的事件处理以及事件发送。
logstash简易部署

大致的配置文件如下。

input {
    file {
        path => "/data/logs/web-service/web-service.log"
        start_position => "beginning"
        add_field => { "[@metadata][type]" => "web_service" }
    }
}

filter {
    # 需要进行的数据处理
}

output {
    elasticsearch {
        hosts => ["127.0.0.1:9200"]
        index => "%{[@metadata][type]}-%{+YYYY.MM.dd}"
        codec => "json"
    }
}

这种部署方式很简单,无需再额外安装部署其他任何服务,但是问题就是每台应用服务的机器都需要部署 Logstash 实例,而 Logstash 实例占用的资源还是不少的,在一定程度上可能会到影响应用服务。
当然为了解决上述提到的问题,可以将 logsatsh 单独部署到一台机器上,然后将应用服务的机器的日志目录通过网络共享挂载到 Logstash 的机器上,不过该方案我也没尝试过,所以也不清楚实际效果的好坏,但我个人并不看好。

使用轻量级 Shipper

对于上面提到的问题,可以在收集日志阶段使用轻量级的日志收集者,像 Filebeat 就是一个很好的选择,然后就可以将 Logstash 单独部署到另外的机器上,接收 Filebeat 收集并传输的事件。
使用轻量级 Shipper 的 Logstash 部署

Filebeat 是十分轻量级的,部署在应用服务的机器上不会像 Logstash 一样由于消耗过多资源而影响到应用。

Filebeat 的配置文件为 filebeat.yml ,以 rpm 或是 deb 的方式安装的话在目录 /etc/filebeat 下。我自己使用时,相关配置大致如下。

filebeat.yml 的配置。

filebeat.prospectors:
- type: log
  enabled: true
  paths:
  - /data/logs/web-service/web-service.log
  fields:
    type: web_service

output.Logstash:
  hosts: ["127.0.0.1:5044"]

而 Logstash 的相关配置如下。

input {
     # 监听 5044 端口,接收 filebeat 传输的事件
     beats {
         port => 5044
     }
 }

 filter {
     # 使用 filebeat 中定义的 fields.type 作为索引名称,可以有效处理不同的事件
     mutate {
         add_field => { "[@metadata][custom_index]" => "%{[fields][type]}" }
     }
     # 其他相关配置
     ...
 }

 output {
     elasticsearch {
         hosts => ["127.0.0:9200"]
         index => "%{[@metadata][custom_index]}-%{+YYYY.MM.dd}"
     }
 }

使用 Filebeat 其实可以直接跳过 Logstash ,即不需要将事件传输到 Logstash ,而是直接将数据传输到 elasicsearch ,不过由于 Filebeat 过于简单(相比 Logstash ),所以在处理事件的功能上有所欠缺,这种方法只适合于简单的日志收集。

使用其他 Broker

开头提到的,logstash 通常同时担当整个日志收集体系的 Broker 和 Indexer 。这种方式在通常情况下是可行的,但是如果需要收集大量服务的日志文件的话,如将线上所有服务的日志统一收集处理的话,可以预见会有大量的事件同时传输到 Logstash ,这样毫无疑问会引发事件的堆积,而且默认情况下,logstash 是先将接收到的事件放入在内存中实现的有界队列中,潜在的风险和问题不用多说。

对于上述提到的问题,可以在事件收集和事件处理之间,即 Filebeat 和 Logstash 之间,添加一层像 redis 或是 kafka 等具有消息队列特性的服务,即先将 Filebeat 收集的事件传输到 reids/kafka ,然后 Logstash 从 redis/kafka 中读取事件,进行后续的事件处理。这样的话,logstash 将只担任 Indexer ,专注于事件的处理,而 Broker 则是由 redis、kafka 等消息队列服务担任,进行事件的存储。

使用其他 Broker 的 logsatsh 部署

详细的配置细节,可以参考:Filebeat Configure the Redis outputFilebeat Configure the Kafka outputLogstash Redis input pluginLogstash Kafka input plugin

其实除了上述的方案外,还可以开启 Logstash 的持久化队列特性,根据官方的说明,可以在一定程度上取代 redis 或是 kafka 等服务,详情参考:Persistent Queues 。这样的话还是可以让 Logstash 继续同时担任 Broker 和 Indexer 。

至于选择哪一种方案,个人认为取决于整个日志收集体系的大小,logstash 的持久化队列在存储上当然还是比不过 redis 和 kafka 等服务,而且 Broker 和 Indexer 耦合在一起,也比较难以进行一些灵活的配置或是扩展,所以如果日志收集体系的规模较大可以选择更换 Broker ,但是如果规模一定程度,但是还没称得上体系庞大的话,可以选择使用持久化队列。毕竟组件越多,资源,部署,运维的成本也会相应提高,根据实际的场景,衡量好成本与收益,选择出最适合的方案才是最好的方案。

转载于:https://my.oschina.net/bingzhong/blog/1941119

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值