现在所用的 Logstash 配置文件越来越复杂,每次做一点点小改动,都需要提心吊胆,仔细测试才敢部署到生产环境。其实这里面主要存在两个问题:

  • 我们现在的做法就是一个环境只有一个配置文件,这样导致配置文件非常大,很难写单元测试
  • 没有写任何测试,每次改动都需要手动测试

配置文件的管理

-f, --config CONFIG_PATH      Load the logstash config from a specific file
                              or directory.  If a directory is given, all
                              files in that directory will be concatenated
                              in lexicographical order and then parsed as a
                              single config file. You can also specify
                              wildcards (globs) and any matched files will
                              be loaded in the order described above.

从 Logstash 帮助文档可知:如果启动时候指定的是一个目录,Logstash 会按照字母顺序合并这个目录下的所有文件,最终得到一个配置文件。那么我们就可以把配置文件按照功能分成几个配置文件,然后再为每个配置文件写单元测试。其目录结构如下:

1
2
3
4
5
6
configs
└── apache
├── 1-input-01.conf
├── 2-filter-01.conf
├── 2-filter-02.conf
└── 3-output-01.conf

启动 Logstash agent 时用 -f 指定对应的目录:./bin/logstash agent -f configs/apache

如何为 Logstash 配置文件写单元测试

理论上,下面所说的方法适用于 1.5 以后的版本,但是我只测试过 2.3.3。

由于 Logstash 在 1.5 以后,不能直接运行 rspec,所以先下载开发相关的插件。

1
bin/logstash-plugin install --development

写单元测试的时候,也没有办法使用 LogStash::RSpec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# encoding: utf-8
require 'logstash/devutils/rspec/spec_helper'
require 'logstash/filters/grok'
require 'logstash/filters/mutate'

files = Dir['configs/apache/2-filter*.conf']
@@configuration = String.new
files.sort.each do |file|
@@configuration << File.read(file)
end

describe 'my first logstash rspec test' do

config(@@configuration)

message = %(127.0.0.1 - - [11/Dec/2013:00:01:45 -0800] "GET /xampp/status.php HTTP/1.1" 200 3891 "http://cadenza/xampp/navi.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0")

sample('message' => message) do
puts subject.to_json
insist { subject['new_field'] } == '3891'
end
end

运行测试:./bin/rspec spec/test.rb