fluentd 0.14.18 → 0.14.19

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c1133959101a3b085e0bcc08fbf62a87d2768a3
4
- data.tar.gz: 4f8d96e61d587a5c89d2f3c73a6e1d0ba0e4fecc
3
+ metadata.gz: 0e8cde86e1ab8e515cd2573c413a821fd7fec5ac
4
+ data.tar.gz: f182030e17d2e1f72c63dffd08dd854e84544923
5
5
  SHA512:
6
- metadata.gz: 1985d37f5b9b9dffd4b40af81112768653a71afe1249be0d36c4a57f2ef768d1f9e3e5007ffe3df85246bc745bf6a8bf1e4ba2d161fa391c0fa87da8b24a46f7
7
- data.tar.gz: fe02e6749d04169de7b79eb2c5c6dadbe1f223acbc72d3b2415e1ad2a48b6a9b9d6bb0ea36b06d41b623c7486149fdc4e5df6f0a125f6b0cf936c53cd69439ef
6
+ metadata.gz: 490ef9c95652e18a65713eefdb0003876991c9a0d504b26edd73904cc24d7e9e7048205e056073d6637d10e75e2226ed5e1deb302596916a59dd4a82555f88e3
7
+ data.tar.gz: dfc41329fc70c653505d251fc9c66f51c4547693723c216c1d01dafa5c8ee38ecca561a3e4cf7aeb11b24879c0c35199265abcf02f659e366029cfcafdb7b96b
data/ChangeLog CHANGED
@@ -1,5 +1,23 @@
1
1
  # v0.14
2
2
 
3
+ ## Release v0.14.19 - 2017/07/12
4
+
5
+ ### New features / Enhancements
6
+
7
+ * in_syslog: More characters are available in tag part of syslog format
8
+ https://github.com/fluent/fluentd/pull/1610
9
+ * in_syslog: Add resolve_hostname parameter
10
+ https://github.com/fluent/fluentd/pull/1616
11
+ * filter_grep: Support new configuration format by config_section
12
+ https://github.com/fluent/fluentd/pull/1611
13
+
14
+ ### Bug fixes
15
+
16
+ * output: Fix race condition of retry state in flush thread
17
+ https://github.com/fluent/fluentd/pull/1623
18
+ * test: Fix typo in test_in_tail.rb
19
+ https://github.com/fluent/fluentd/pull/1622
20
+
3
21
  ## Release v0.14.18 - 2017/06/21
4
22
 
5
23
  ### New features / Enhancements
data/README.md CHANGED
@@ -64,15 +64,16 @@ Many enterprises run Fluentd in production to handle all of their logging needs.
64
64
 
65
65
  ## More Information
66
66
 
67
- - Website: http://fluentd.org/
67
+ - Website: https://www.fluentd.org/
68
68
  - Documentation: http://docs.fluentd.org/
69
- - Source repository: http://github.com/fluent
69
+ - Project repository: http://github.com/fluent
70
70
  - Discussion: http://groups.google.com/group/fluentd
71
71
  - Slack / Community: http://slack.fluentd.org
72
72
  - Newsletters: http://get.treasuredata.com/Fluentd_education
73
73
  - Author: Sadayuki Furuhashi
74
74
  - Copyright: (c) 2011 FURUHASHI Sadayuki
75
75
  - License: Apache License, Version 2.0
76
+
76
77
  ## Contributors:
77
78
 
78
79
  Patches contributed by [great developers](https://github.com/fluent/fluentd/contributors).
@@ -24,32 +24,59 @@ module Fluent::Plugin
24
24
 
25
25
  REGEXP_MAX_NUM = 20
26
26
 
27
- (1..REGEXP_MAX_NUM).each {|i| config_param :"regexp#{i}", :string, default: nil }
28
- (1..REGEXP_MAX_NUM).each {|i| config_param :"exclude#{i}", :string, default: nil }
27
+ (1..REGEXP_MAX_NUM).each {|i| config_param :"regexp#{i}", :string, default: nil, deprecated: "Use <regexp> section" }
28
+ (1..REGEXP_MAX_NUM).each {|i| config_param :"exclude#{i}", :string, default: nil, deprecated: "Use <exclude> section" }
29
+
30
+ config_section :regexp, param_name: :regexps, multi: true do
31
+ desc "The field name to which the regular expression is applied."
32
+ config_param :key, :string
33
+ desc "The regular expression."
34
+ config_param :pattern do |value|
35
+ Regexp.compile(value)
36
+ end
37
+ end
38
+
39
+ config_section :exclude, param_name: :excludes, multi: true do
40
+ desc "The field name to which the regular expression is applied."
41
+ config_param :key, :string
42
+ desc "The regular expression."
43
+ config_param :pattern do |value|
44
+ Regexp.compile(value)
45
+ end
46
+ end
29
47
 
30
48
  # for test
31
- attr_reader :regexps
32
- attr_reader :excludes
49
+ attr_reader :_regexps
50
+ attr_reader :_excludes
33
51
 
34
52
  def configure(conf)
35
53
  super
36
54
 
37
- @regexps = {}
55
+ @_regexps = {}
38
56
  (1..REGEXP_MAX_NUM).each do |i|
39
57
  next unless conf["regexp#{i}"]
40
58
  key, regexp = conf["regexp#{i}"].split(/ /, 2)
41
59
  raise Fluent::ConfigError, "regexp#{i} does not contain 2 parameters" unless regexp
42
- raise Fluent::ConfigError, "regexp#{i} contains a duplicated key, #{key}" if @regexps[key]
43
- @regexps[key] = Regexp.compile(regexp)
60
+ raise Fluent::ConfigError, "regexp#{i} contains a duplicated key, #{key}" if @_regexps[key]
61
+ @_regexps[key] = Regexp.compile(regexp)
44
62
  end
45
63
 
46
- @excludes = {}
64
+ @_excludes = {}
47
65
  (1..REGEXP_MAX_NUM).each do |i|
48
66
  next unless conf["exclude#{i}"]
49
67
  key, exclude = conf["exclude#{i}"].split(/ /, 2)
50
68
  raise Fluent::ConfigError, "exclude#{i} does not contain 2 parameters" unless exclude
51
- raise Fluent::ConfigError, "exclude#{i} contains a duplicated key, #{key}" if @excludes[key]
52
- @excludes[key] = Regexp.compile(exclude)
69
+ raise Fluent::ConfigError, "exclude#{i} contains a duplicated key, #{key}" if @_excludes[key]
70
+ @_excludes[key] = Regexp.compile(exclude)
71
+ end
72
+
73
+ @regexps.each do |e|
74
+ raise Fluent::ConfigError, "Duplicate key: #{e.key}" if @_regexps.key?(e.key)
75
+ @_regexps[e.key] = e.pattern
76
+ end
77
+ @excludes.each do |e|
78
+ raise Fluent::ConfigError, "Duplicate key: #{e.key}" if @_excludes.key?(e.key)
79
+ @_excludes[e.key] = e.pattern
53
80
  end
54
81
  end
55
82
 
@@ -57,10 +84,10 @@ module Fluent::Plugin
57
84
  result = nil
58
85
  begin
59
86
  catch(:break_loop) do
60
- @regexps.each do |key, regexp|
87
+ @_regexps.each do |key, regexp|
61
88
  throw :break_loop unless ::Fluent::StringUtil.match_regexp(regexp, record[key].to_s)
62
89
  end
63
- @excludes.each do |key, exclude|
90
+ @_excludes.each do |key, exclude|
64
91
  throw :break_loop if ::Fluent::StringUtil.match_regexp(exclude, record[key].to_s)
65
92
  end
66
93
  result = record
@@ -83,6 +83,8 @@ module Fluent::Plugin
83
83
 
84
84
  desc 'The field name of hostname of sender.'
85
85
  config_param :source_hostname_key, :string, default: nil
86
+ config_param :resolve_hostname, :bool, default: nil
87
+ desc 'Connections will be disconnected right after receiving first message if this value is true.'
86
88
  desc 'The field name of source address of sender.'
87
89
  config_param :source_address_key, :string, default: nil
88
90
  desc 'The field name of the priority.'
@@ -116,7 +118,13 @@ module Fluent::Plugin
116
118
  end
117
119
  @source_address_key = @source_host_key
118
120
  end
119
- @resolve_name = !!@source_hostname_key
121
+ if @source_hostname_key
122
+ if @resolve_hostname.nil?
123
+ @resolve_hostname = true
124
+ elsif !@resolve_hostname # user specifies "false" in config
125
+ raise Fluent::ConfigError, "resolve_hostname must be true with source_hostname_key"
126
+ end
127
+ end
120
128
 
121
129
  @_event_loop_run_timeout = @blocking_timeout
122
130
  end
@@ -138,7 +146,7 @@ module Fluent::Plugin
138
146
  end
139
147
 
140
148
  def start_udp_server
141
- server_create_udp(:in_syslog_udp_server, @port, bind: @bind, max_bytes: @message_length_limit, resolve_name: @resolve_name) do |data, sock|
149
+ server_create_udp(:in_syslog_udp_server, @port, bind: @bind, max_bytes: @message_length_limit, resolve_name: @resolve_hostname) do |data, sock|
142
150
  message_handler(data.chomp, sock)
143
151
  end
144
152
  end
@@ -147,7 +155,7 @@ module Fluent::Plugin
147
155
  # syslog family add "\n" to each message and this seems only way to split messages in tcp stream
148
156
  delimiter = "\n"
149
157
  delimiter_size = delimiter.size
150
- server_create_connection(:in_syslog_tcp_server, @port, bind: @bind, resolve_name: @resolve_name) do |conn|
158
+ server_create_connection(:in_syslog_tcp_server, @port, bind: @bind, resolve_name: @resolve_hostname) do |conn|
151
159
  buffer = ""
152
160
  conn.data do |data|
153
161
  buffer << data
@@ -1264,7 +1264,7 @@ module Fluent
1264
1264
  current_clock = Fluent::Clock.now
1265
1265
  interval = state.next_clock - current_clock
1266
1266
 
1267
- if state.next_clock <= current_clock && (!@retry || @retry_mutex.synchronize{ @retry.next_time } <= Time.now)
1267
+ if state.next_clock <= current_clock && @retry_mutex.synchronize { @retry ? @retry.next_time <= Time.now : true }
1268
1268
  try_flush
1269
1269
 
1270
1270
  # next_flush_time uses flush_thread_interval or flush_thread_burst_interval (or retrying)
@@ -24,9 +24,9 @@ module Fluent
24
24
  Plugin.register_parser('syslog', self)
25
25
 
26
26
  # From existence TextParser pattern
27
- REGEXP = /^(?<time>[^ ]*\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
27
+ REGEXP = /^(?<time>[^ ]*\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[^ :\[]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
28
28
  # From in_syslog default pattern
29
- REGEXP_WITH_PRI = /^\<(?<pri>[0-9]+)\>(?<time>[^ ]* {1,2}[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
29
+ REGEXP_WITH_PRI = /^\<(?<pri>[0-9]+)\>(?<time>[^ ]* {1,2}[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[^ :\[]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
30
30
  REGEXP_RFC5424 = /\A^(?<time>[^ ]+) (?<host>[^ ]+) (?<ident>[^ ]+) (?<pid>[-0-9]+) (?<msgid>[^ ]+) (?<extradata>(\[(.*)\]|[^ ])) (?<message>.+)$\z/
31
31
  REGEXP_RFC5424_WITH_PRI = /\A^\<(?<pri>[0-9]{1,3})\>[1-9]\d{0,2} (?<time>[^ ]+) (?<host>[^ ]+) (?<ident>[^ ]+) (?<pid>[-0-9]+) (?<msgid>[^ ]+) (?<extradata>(\[(.*)\]|[^ ])) (?<message>.+)$\z/
32
32
  REGEXP_DETECT_RFC5424 = /^\<.*\>[1-9]\d{0,2}/
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '0.14.18'
19
+ VERSION = '0.14.19'
20
20
 
21
21
  end
@@ -23,12 +23,51 @@ class GrepFilterTest < Test::Unit::TestCase
23
23
 
24
24
  test "regexpN can contain a space" do
25
25
  d = create_driver(%[regexp1 message foo])
26
- assert_equal(Regexp.compile(/ foo/), d.instance.regexps['message'])
26
+ assert_equal(Regexp.compile(/ foo/), d.instance._regexps['message'])
27
27
  end
28
28
 
29
29
  test "excludeN can contain a space" do
30
30
  d = create_driver(%[exclude1 message foo])
31
- assert_equal(Regexp.compile(/ foo/), d.instance.excludes['message'])
31
+ assert_equal(Regexp.compile(/ foo/), d.instance._excludes['message'])
32
+ end
33
+
34
+ sub_test_case "duplicate key" do
35
+ test "flat" do
36
+ conf = %[
37
+ regexp1 message test
38
+ regexp2 message test2
39
+ ]
40
+ assert_raise(Fluent::ConfigError) do
41
+ create_driver(conf)
42
+ end
43
+ end
44
+ test "section" do
45
+ conf = %[
46
+ <regexp>
47
+ key message
48
+ pattern test
49
+ </regexp>
50
+ <regexp>
51
+ key message
52
+ pattern test2
53
+ </regexp>
54
+ ]
55
+ assert_raise(Fluent::ConfigError) do
56
+ create_driver(conf)
57
+ end
58
+ end
59
+ test "mix" do
60
+ conf = %[
61
+ regexp1 message test
62
+ <regexp>
63
+ key message
64
+ pattern test
65
+ </regexp>
66
+ ]
67
+ assert_raise(Fluent::ConfigError) do
68
+ create_driver(conf)
69
+ end
70
+ end
32
71
  end
33
72
  end
34
73
 
@@ -77,6 +116,38 @@ class GrepFilterTest < Test::Unit::TestCase
77
116
  end
78
117
  end
79
118
 
119
+ test 'regexps' do
120
+ conf = %[
121
+ <regexp>
122
+ key message
123
+ pattern WARN
124
+ </regexp>
125
+ ]
126
+ filtered_records = filter(conf, messages)
127
+ assert_equal(3, filtered_records.size)
128
+ assert_block('only WARN logs') do
129
+ filtered_records.all? { |r|
130
+ !r['message'].include?('INFO')
131
+ }
132
+ end
133
+ end
134
+
135
+ test 'excludes' do
136
+ conf = %[
137
+ <exclude>
138
+ key message
139
+ pattern favicon
140
+ </exclude>
141
+ ]
142
+ filtered_records = filter(conf, messages)
143
+ assert_equal(3, filtered_records.size)
144
+ assert_block('remove favicon logs') do
145
+ filtered_records.all? { |r|
146
+ !r['message'].include?('favicon')
147
+ }
148
+ end
149
+ end
150
+
80
151
  sub_test_case 'with invalid sequence' do
81
152
  def messages
82
153
  [
@@ -37,6 +37,24 @@ class SyslogInputTest < Test::Unit::TestCase
37
37
  assert_equal bind_addr, d.instance.bind
38
38
  end
39
39
 
40
+ sub_test_case 'source_hostname_key and source_address_key features' do
41
+ test 'resolve_hostname must be true with source_hostname_key' do
42
+ assert_raise(Fluent::ConfigError) {
43
+ create_driver(CONFIG + <<EOS)
44
+ resolve_hostname false
45
+ source_hostname_key hostname
46
+ EOS
47
+ }
48
+ end
49
+
50
+ data('resolve_hostname' => 'resolve_hostname true',
51
+ 'source_hostname_key' => 'source_hostname_key source_host')
52
+ def test_configure_reslove_hostname(param)
53
+ d = create_driver([CONFIG, param].join("\n"))
54
+ assert_true d.instance.resolve_hostname
55
+ end
56
+ end
57
+
40
58
  data(
41
59
  ipv4: ['127.0.0.1', CONFIG, ::Socket::AF_INET],
42
60
  ipv6: ['::1', IPv6_CONFIG, ::Socket::AF_INET6],
@@ -823,7 +823,7 @@ class TailInputTest < Test::Unit::TestCase
823
823
  sub_test_case "path" do
824
824
  # * path test
825
825
  # TODO: Clean up tests
826
- EX_RORATE_WAIT = 0
826
+ EX_ROTATE_WAIT = 0
827
827
 
828
828
  EX_CONFIG = config_element("", "", {
829
829
  "tag" => "tail",
@@ -832,7 +832,7 @@ class TailInputTest < Test::Unit::TestCase
832
832
  "pos_file" => "#{TMP_DIR}/tail.pos",
833
833
  "read_from_head" => true,
834
834
  "refresh_interval" => 30,
835
- "rotate_wait" => "#{EX_RORATE_WAIT}s",
835
+ "rotate_wait" => "#{EX_ROTATE_WAIT}s",
836
836
  })
837
837
  EX_PATHS = [
838
838
  'test/plugin/data/2010/01/20100102-030405.log',
@@ -926,7 +926,7 @@ class TailInputTest < Test::Unit::TestCase
926
926
  Timecop.freeze(2010, 1, 2, 3, 4, 5) do
927
927
  flexstub(Fluent::Plugin::TailInput::TailWatcher) do |watcherclass|
928
928
  EX_PATHS.each do |path|
929
- watcherclass.should_receive(:new).with(path, EX_RORATE_WAIT, Fluent::Plugin::TailInput::FilePositionEntry, any, true, true, 1000, any, any, any, any, any, any).once.and_return do
929
+ watcherclass.should_receive(:new).with(path, EX_ROTATE_WAIT, Fluent::Plugin::TailInput::FilePositionEntry, any, true, true, 1000, any, any, any, any, any, any).once.and_return do
930
930
  flexmock('TailWatcher') { |watcher|
931
931
  watcher.should_receive(:attach).once
932
932
  watcher.should_receive(:unwatched=).zero_or_more_times
@@ -944,7 +944,7 @@ class TailInputTest < Test::Unit::TestCase
944
944
 
945
945
  Timecop.freeze(2010, 1, 2, 3, 4, 6) do
946
946
  flexstub(Fluent::Plugin::TailInput::TailWatcher) do |watcherclass|
947
- watcherclass.should_receive(:new).with('test/plugin/data/2010/01/20100102-030406.log', EX_RORATE_WAIT, Fluent::Plugin::TailInput::FilePositionEntry, any, true, true, 1000, any, any, any, any, any, any).once.and_return do
947
+ watcherclass.should_receive(:new).with('test/plugin/data/2010/01/20100102-030406.log', EX_ROTATE_WAIT, Fluent::Plugin::TailInput::FilePositionEntry, any, true, true, 1000, any, any, any, any, any, any).once.and_return do
948
948
  flexmock('TailWatcher') do |watcher|
949
949
  watcher.should_receive(:attach).once
950
950
  watcher.should_receive(:unwatched=).zero_or_more_times
@@ -64,6 +64,24 @@ class SyslogParserTest < ::Test::Unit::TestCase
64
64
  end
65
65
  end
66
66
 
67
+ def test_parse_various_characters_for_tag
68
+ ident = '~!@#$%^&*()_+=-`]{};"\'/?\\,.<>'
69
+ @parser.configure({})
70
+ @parser.instance.parse("Feb 28 12:00:00 192.168.0.1 #{ident}[11111]: [error] Syslog test") { |time, record|
71
+ assert_equal(event_time('Feb 28 12:00:00', format: '%b %d %H:%M:%S'), time)
72
+ assert_equal(@expected.merge('ident' => ident), record)
73
+ }
74
+ end
75
+
76
+ def test_parse_various_characters_for_tag_with_priority
77
+ ident = '~!@#$%^&*()_+=-`]{};"\'/?\\,.<>'
78
+ @parser.configure('with_priority' => true)
79
+ @parser.instance.parse("<6>Feb 28 12:00:00 192.168.0.1 #{ident}[11111]: [error] Syslog test") { |time, record|
80
+ assert_equal(event_time('Feb 28 12:00:00', format: '%b %d %H:%M:%S'), time)
81
+ assert_equal(@expected.merge('pri' => 6, 'ident' => ident), record)
82
+ }
83
+ end
84
+
67
85
  class TestRFC5424Regexp < self
68
86
  def test_parse_with_rfc5424_message
69
87
  @parser.configure(
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluentd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.18
4
+ version: 0.14.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-22 00:00:00.000000000 Z
11
+ date: 2017-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack