logstash-input-syslog 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef06714d6d1b2383646d6ec53550171592e1dbcd97e3e7b1e847edcceba41d4a
4
- data.tar.gz: acd1005f0b2db5ad66ff95c7d74027ead6841d97b4805c05ed19225fa5af3cf5
3
+ metadata.gz: 0c25de14662bbd82e873e09199f770ae115e73ab837d78300ad23d2f1a5f8617
4
+ data.tar.gz: ce332bc77901424f297d992d43c08999fbc30cc69547af624ead0d3aef2486f7
5
5
  SHA512:
6
- metadata.gz: ea924072e2e8904864649a6be3706523dca20a01c1c7aef441fea1c643f93e78dcb12d869ffb1f4d16ee2ebbdcdf4a396f45d6b3fc77909ad247941a849f9e6d
7
- data.tar.gz: d3d658703fa56537a9818f65b92ddba37e8f56e760beda02698b1782c5f89eb9dc6c279c18a0611ecf653f3c9b07894549edf5b750855fc0f42500862f7d6f4a
6
+ metadata.gz: 5a1cf93965af7f77e9f543d339567c0cba16e481d325c345fea9fcd945a85f032ab87ff4f135c4ebff82c44f14365e650e9e6fe08ef546efab42c8ba56cd273e
7
+ data.tar.gz: b6c4d596cac63c5432717086040ba6fb03cb2f7ae17b813f7414facef60c33cd3f3ea3239e5933768e2ca03721e596744d3301126087bc224db1c8abb09e4d72
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 3.7.0
2
+ - Changed the TCP reading mode to use the non-blocking method [#75](https://github.com/logstash-plugins/logstash-input-syslog/pull/75)
3
+ It fixes the high CPU usage when TCP clients do not properly disconnect/send EOF.
4
+ - Fixed broken tests
5
+
1
6
  ## 3.6.0
2
7
  - Add support for ECS v8 as alias to v1 implementation [#68](https://github.com/logstash-plugins/logstash-input-syslog/pull/68)
3
8
 
@@ -221,6 +221,21 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
221
221
  close_tcp
222
222
  end # def tcp_listener
223
223
 
224
+ def tcp_read_lines(socket)
225
+ buffer = String.new
226
+ loop do
227
+ begin
228
+ buffer << socket.read_nonblock(1024)
229
+ while (newline = buffer.index("\n"))
230
+ yield buffer.slice!(0..newline)
231
+ end
232
+ rescue IO::WaitReadable
233
+ IO.select([socket], nil)
234
+ retry
235
+ end
236
+ end
237
+ end
238
+
224
239
  # tcp_receiver is executed in a thread, any uncatched exception will be bubbled up to the
225
240
  # tcp server thread and all tcp connections will be closed and the listener restarted.
226
241
  def tcp_receiver(output_queue, socket)
@@ -232,7 +247,7 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
232
247
 
233
248
  first_read = true
234
249
 
235
- socket.each do |line|
250
+ tcp_read_lines(socket) do |line|
236
251
  metric.increment(:messages_received)
237
252
  if @proxy_protocol && first_read
238
253
  first_read = false
@@ -253,7 +268,7 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
253
268
  rescue Errno::ECONNRESET
254
269
  # swallow connection reset exceptions to avoid bubling up the tcp_listener & server
255
270
  logger.info("connection reset", :client => "#{ip}:#{port}")
256
- rescue Errno::EBADF
271
+ rescue Errno::EBADF, EOFError
257
272
  # swallow connection closed exceptions to avoid bubling up the tcp_listener & server
258
273
  logger.info("connection closed", :client => "#{ip}:#{port}")
259
274
  rescue IOError => e
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-input-syslog'
4
- s.version = '3.6.0'
4
+ s.version = '3.7.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Reads syslog messages as events"
7
7
  s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
@@ -33,80 +33,18 @@ require "socket"
33
33
  describe LogStash::Inputs::Syslog do
34
34
  SYSLOG_LINE = "<164>Oct 26 15:19:25 1.2.3.4 %ASA-4-106023: Deny udp src DRAC:10.1.2.3/43434 dst outside:192.168.0.1/53 by access-group \"acl_drac\" [0x0, 0x0]"
35
35
 
36
- it "should properly handle priority, severity and facilities" do
37
- skip_if_stack_known_issue
38
- port = 5511
39
- event_count = 10
40
- conf = <<-CONFIG
41
- input {
42
- syslog {
43
- type => "blah"
44
- port => #{port}
45
- }
46
- }
47
- CONFIG
48
-
49
- events = input(conf) do |pipeline, queue|
50
- socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
51
- event_count.times do |i|
52
- socket.puts(SYSLOG_LINE)
53
- end
54
- socket.close
55
-
56
- event_count.times.collect { queue.pop }
57
- end
58
-
59
- expect( events.length ).to eql event_count
60
- events.each do |event|
61
- expect( event.get("priority") ).to eql 164
62
- expect( event.get("severity") ).to eql 4
63
- expect( event.get("facility") ).to eql 20
64
- end
65
- end
66
-
67
- it "should properly PROXY protocol v1" do
68
- skip_if_stack_known_issue
69
- port = 5511
70
- event_count = 10
71
- conf = <<-CONFIG
72
- input {
73
- syslog {
74
- type => "blah"
75
- port => #{port}
76
- proxy_protocol => true
77
- }
78
- }
79
- CONFIG
80
-
81
- events = input(conf) do |pipeline, queue|
82
- socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
83
- socket.puts("PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678\r");
84
- socket.flush
85
- event_count.times do |i|
86
- socket.puts(SYSLOG_LINE)
87
- end
88
- socket.close
89
-
90
- event_count.times.collect { queue.pop }
91
- end
92
-
93
- expect( events.length ).to eql event_count
94
- events.each do |event|
95
- expect( event.get("priority") ).to eql 164
96
- expect( event.get("severity") ).to eql 4
97
- expect( event.get("facility") ).to eql 20
98
- expect( event.get("host") ).to eql "1.2.3.4"
99
- end
100
- end
101
-
102
- context 'tag', :ecs_compatibility_support do
103
- ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do
36
+ context 'ECS common behavior', :ecs_compatibility_support do
37
+ ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do |ecs_select|
38
+ let(:priority_key) { ecs_select[disabled:'priority', v1:'[log][syslog][priority]'] }
39
+ let(:facility_key) { ecs_select[disabled:'facility', v1:'[log][syslog][facility][code]'] }
40
+ let(:severity_key) { ecs_select[disabled:'severity', v1:'[log][syslog][severity][code]'] }
41
+ let(:host_key) { ecs_select[disabled:'host', v1:'[host][ip]'] }
104
42
 
105
43
  before(:each) do
106
44
  allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
107
45
  end
108
46
 
109
- it "should add unique tag when grok parsing fails with live syslog input" do
47
+ it "should properly handle priority, severity and facilities" do
110
48
  skip_if_stack_known_issue
111
49
  port = 5511
112
50
  event_count = 10
@@ -122,7 +60,7 @@ describe LogStash::Inputs::Syslog do
122
60
  events = input(conf) do |pipeline, queue|
123
61
  socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
124
62
  event_count.times do |i|
125
- socket.puts("message which causes the a grok parse failure")
63
+ socket.puts(SYSLOG_LINE)
126
64
  end
127
65
  socket.close
128
66
 
@@ -130,38 +68,31 @@ describe LogStash::Inputs::Syslog do
130
68
  end
131
69
 
132
70
  expect( events.length ).to eql event_count
133
- event_count.times do |i|
134
- expect( events[i].get("tags") ).to eql ["_grokparsefailure_sysloginput"]
71
+ events.each do |event|
72
+ expect( event.get(priority_key) ).to eql 164
73
+ expect( event.get(severity_key) ).to eql 4
74
+ expect( event.get(facility_key) ).to eql 20
135
75
  end
136
76
  end
137
77
 
138
- end
139
- end
140
-
141
- context 'timestamp', :ecs_compatibility_support do
142
- ecs_compatibility_matrix(:disabled, :v1) do
143
-
144
- before(:each) do
145
- allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
146
- end
147
-
148
- it "should properly handle locale and timezone" do
78
+ it "should properly PROXY protocol v1" do
79
+ skip_if_stack_known_issue
149
80
  port = 5511
150
81
  event_count = 10
151
-
152
82
  conf = <<-CONFIG
153
83
  input {
154
84
  syslog {
155
85
  type => "blah"
156
86
  port => #{port}
157
- locale => "en"
158
- timezone => "UTC"
87
+ proxy_protocol => true
159
88
  }
160
89
  }
161
90
  CONFIG
162
91
 
163
92
  events = input(conf) do |pipeline, queue|
164
93
  socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
94
+ socket.puts("PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678\r\n")
95
+ socket.flush
165
96
  event_count.times do |i|
166
97
  socket.puts(SYSLOG_LINE)
167
98
  end
@@ -172,53 +103,217 @@ describe LogStash::Inputs::Syslog do
172
103
 
173
104
  expect( events.length ).to eql event_count
174
105
  events.each do |event|
175
- expect( event.get("@timestamp") ).to be_a_logstash_timestamp_equivalent_to("#{Time.now.year}-10-26T15:19:25Z")
106
+ expect( event.get(priority_key) ).to eql 164
107
+ expect( event.get(severity_key) ).to eql 4
108
+ expect( event.get(facility_key) ).to eql 20
109
+ expect( event.get(host_key) ).to eql "1.2.3.4"
176
110
  end
177
111
  end
178
112
 
179
- it "should properly handle no locale and no timezone" do
180
- port = 5511
113
+ context 'grok' do
114
+ it "should add unique tag when grok parsing fails with live syslog input" do
115
+ skip_if_stack_known_issue
116
+ port = 5511
117
+ event_count = 10
118
+ conf = <<-CONFIG
119
+ input {
120
+ syslog {
121
+ type => "blah"
122
+ port => #{port}
123
+ }
124
+ }
125
+ CONFIG
126
+ events = input(conf) do |pipeline, queue|
127
+ socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
128
+ event_count.times do |i|
129
+ socket.puts("message which causes the a grok parse failure")
130
+ end
131
+ socket.close
132
+ event_count.times.collect { queue.pop }
133
+ end
134
+ expect( events.length ).to eql event_count
135
+ event_count.times do |i|
136
+ expect( events[i].get("tags") ).to eql ["_grokparsefailure_sysloginput"]
137
+ end
138
+ end
181
139
 
182
- conf = <<-CONFIG
183
- input {
184
- syslog {
185
- type => "blah"
186
- port => #{port}
140
+ it "should add unique tag when grok parsing fails" do
141
+ input = LogStash::Inputs::Syslog.new({})
142
+ input.register
143
+
144
+ # event which is not syslog should have a new tag
145
+ event = LogStash::Event.new({ "message" => "hello world, this is not syslog RFC3164" })
146
+ input.syslog_relay(event)
147
+ expect( event.get("tags") ).to eql ["_grokparsefailure_sysloginput"]
148
+
149
+ syslog_event = LogStash::Event.new({ "message" => "<164>Oct 26 15:19:25 1.2.3.4 %ASA-4-106023: Deny udp src DRAC:10.1.2.3/43434" })
150
+ input.syslog_relay(syslog_event)
151
+ expect( syslog_event.get(priority_key) ).to eql 164
152
+ expect( syslog_event.get(severity_key) ).to eql 4
153
+ expect( syslog_event.get("tags") ).to be nil
154
+
155
+ input.close
156
+ end
157
+
158
+ it "should properly handle a custom grok_pattern" do
159
+ port = 5511
160
+ event_count = 1
161
+ custom_grok = "<%{POSINT:#{priority_key}}>%{SYSLOGTIMESTAMP:timestamp} atypical %{GREEDYDATA:message}"
162
+ message_field = "This part constitutes the message field"
163
+ timestamp = "Oct 26 15:19:25"
164
+ custom_line = "<164>#{timestamp} atypical #{message_field}"
165
+
166
+ conf = <<-CONFIG
167
+ input {
168
+ syslog {
169
+ type => "blah"
170
+ port => #{port}
171
+ grok_pattern => "#{custom_grok}"
172
+ }
187
173
  }
188
- }
189
- CONFIG
174
+ CONFIG
190
175
 
191
- event = input(conf) do |pipeline, queue|
192
- socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
193
- socket.puts(SYSLOG_LINE)
194
- socket.close
176
+ events = input(conf) do |pipeline, queue|
177
+ socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
178
+ event_count.times do |i|
179
+ socket.puts(custom_line)
180
+ end
181
+ socket.close
182
+
183
+ event_count.times.collect { queue.pop }
184
+ end
195
185
 
196
- queue.pop
186
+ expect( events.length ).to eql event_count
187
+ events.each do |event|
188
+ expect( event.get(priority_key) ).to eql 164
189
+ expect( event.get(severity_key) ).to eql 4
190
+ expect( event.get(facility_key) ).to eql 20
191
+ expect( event.get("message") ).to eql "#{message_field}\n"
192
+ expect( event.get('timestamp') ).to eql timestamp if ecs_compatibility == :disabled
193
+ expect( event.include?('timestamp') ).to be false if ecs_compatibility != :disabled
194
+ end
197
195
  end
198
196
 
199
- # chances platform timezone is not UTC, so parse without offset to create expectation
200
- equivalent_time = Time.parse("#{Time.now.year}-10-26T15:19:25")
201
- expect( event.get("@timestamp") ).to be_a_logstash_timestamp_equivalent_to(equivalent_time)
197
+ it "should properly handle the cef codec with a custom grok_pattern" do
198
+ port = 5511
199
+ event_count = 1
200
+
201
+ custom_grok = "<%{POSINT:#{priority_key}}>%{TIMESTAMP_ISO8601:timestamp} atypical %{GREEDYDATA:syslog_message}"
202
+ timestamp = "2018-02-07T12:40:00.000Z"
203
+ cef_message = "Description Omitted"
204
+ syslog_message = "foo bar"
205
+ syslog_message_envelope = "<134>#{timestamp} atypical #{syslog_message}"
206
+ custom_line = "CEF:0|Company Name|Application Name|Application Version Number|632|Syslog Configuration Updated|3|src=192.168.0.1 suser=user@example.com target=TARGET msg=#{cef_message} syslog=#{syslog_message_envelope} KeyValueOne=kv1 KeyValueTwo=12345 "
207
+
208
+ conf = <<-CONFIG
209
+ input {
210
+ syslog {
211
+ port => #{port}
212
+ syslog_field => "syslog"
213
+ grok_pattern => "#{custom_grok}"
214
+ codec => cef { ecs_compatibility => #{ ecs_compatibility } }
215
+ }
216
+ }
217
+ CONFIG
218
+
219
+ events = input(conf) do |pipeline, queue|
220
+ socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
221
+ event_count.times do |i|
222
+ socket.puts(custom_line)
223
+ end
224
+ socket.close
225
+
226
+ event_count.times.collect { queue.pop }
227
+ end
228
+
229
+ expect( events.length ).to eql event_count
230
+ events.each do |event|
231
+ expect( event.get(priority_key) ).to eql 134
232
+ expect( event.get(severity_key) ).to eql 6
233
+ expect( event.get(facility_key) ).to eql 16
234
+ expect( event.get("message") ).to eql cef_message
235
+ expect( event.get("syslog_message") ).to eql syslog_message
236
+ expect( event.get('timestamp') ).to eql timestamp if ecs_compatibility == :disabled
237
+ expect( event.include?('timestamp') ).to be false if ecs_compatibility != :disabled
238
+ end
239
+ end
202
240
  end
203
241
 
204
- it "should support non UTC timezone" do
205
- input = LogStash::Inputs::Syslog.new({"timezone" => "-05:00"})
206
- input.register
242
+ context 'timestamp' do
243
+ it "should properly handle locale and timezone" do
244
+ port = 5511
245
+ event_count = 10
246
+
247
+ conf = <<-CONFIG
248
+ input {
249
+ syslog {
250
+ type => "blah"
251
+ port => #{port}
252
+ locale => "en"
253
+ timezone => "UTC"
254
+ }
255
+ }
256
+ CONFIG
257
+
258
+ events = input(conf) do |pipeline, queue|
259
+ socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
260
+ event_count.times do |i|
261
+ socket.puts(SYSLOG_LINE)
262
+ end
263
+ socket.close
207
264
 
208
- # event which is not syslog should have a new tag
265
+ event_count.times.collect { queue.pop }
266
+ end
209
267
 
210
- syslog_event = LogStash::Event.new({ "message" => "<164>Oct 26 15:19:25 1.2.3.4 %ASA-4-106023: Deny udp src DRAC:10.1.2.3/43434" })
211
- input.syslog_relay(syslog_event)
268
+ expect( events.length ).to eql event_count
269
+ events.each do |event|
270
+ expect( event.get("@timestamp") ).to be_a_logstash_timestamp_equivalent_to("#{Time.now.year}-10-26T15:19:25Z")
271
+ end
272
+ end
212
273
 
213
- expect( syslog_event.get("@timestamp") ).to be_a_logstash_timestamp_equivalent_to("#{Time.now.year}-10-26T20:19:25Z")
274
+ it "should properly handle no locale and no timezone" do
275
+ port = 5511
214
276
 
215
- input.close
216
- end
277
+ conf = <<-CONFIG
278
+ input {
279
+ syslog {
280
+ type => "blah"
281
+ port => #{port}
282
+ }
283
+ }
284
+ CONFIG
285
+
286
+ event = input(conf) do |pipeline, queue|
287
+ socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
288
+ socket.puts(SYSLOG_LINE)
289
+ socket.close
290
+
291
+ queue.pop
292
+ end
217
293
 
294
+ # chances platform timezone is not UTC, so parse without offset to create expectation
295
+ equivalent_time = Time.parse("#{Time.now.year}-10-26T15:19:25")
296
+ expect( event.get("@timestamp") ).to be_a_logstash_timestamp_equivalent_to(equivalent_time)
297
+ end
298
+
299
+ it "should support non UTC timezone" do
300
+ input = LogStash::Inputs::Syslog.new({"timezone" => "-05:00"})
301
+ input.register
302
+
303
+ # event which is not syslog should have a new tag
304
+
305
+ syslog_event = LogStash::Event.new({ "message" => "<164>Oct 26 15:19:25 1.2.3.4 %ASA-4-106023: Deny udp src DRAC:10.1.2.3/43434" })
306
+ input.syslog_relay(syslog_event)
307
+
308
+ expect( syslog_event.get("@timestamp") ).to be_a_logstash_timestamp_equivalent_to("#{Time.now.year}-10-26T20:19:25Z")
309
+
310
+ input.close
311
+ end
312
+ end
218
313
  end
219
314
  end
220
315
 
221
- context 'ECS behavior', :ecs_compatibility_support do
316
+ context 'ECS :v1 behavior', :ecs_compatibility_support do
222
317
 
223
318
  ecs_compatibility_matrix(:v1) do
224
319
 
@@ -270,7 +365,7 @@ describe LogStash::Inputs::Syslog do
270
365
 
271
366
  let(:socket) do
272
367
  server = double('tcp-server')
273
- allow( server ).to receive(:each).and_yield "<133>Mar 11 08:44:43 precision kernel: [765135.424096] mce: CPU6: Package temperature/speed normal\n"
368
+ allow( subject ).to receive(:tcp_read_lines).and_yield("<133>Mar 11 08:44:43 precision kernel: [765135.424096] mce: CPU6: Package temperature/speed normal\n")
274
369
  allow( server ).to receive(:close)
275
370
  server
276
371
  end
@@ -286,103 +381,51 @@ describe LogStash::Inputs::Syslog do
286
381
  end
287
382
  end
288
383
 
289
- it "should add unique tag when grok parsing fails" do
290
- input = LogStash::Inputs::Syslog.new({})
291
- input.register
384
+ context 'tcp receiver' do
385
+ subject(:plugin) { LogStash::Inputs::Syslog.new }
386
+ before { plugin.register }
387
+ after { plugin.close }
292
388
 
293
- # event which is not syslog should have a new tag
294
- event = LogStash::Event.new({ "message" => "hello world, this is not syslog RFC3164" })
295
- input.syslog_relay(event)
296
- expect( event.get("tags") ).to eql ["_grokparsefailure_sysloginput"]
389
+ let(:queue) { Queue.new }
390
+ let(:socket) do
391
+ socket = double('tcp-socket')
392
+ expect( socket ).to receive(:peeraddr).and_return(["AF_INET", 514, "192.168.0.10", "192.168.0.10"])
393
+ socket
394
+ end
297
395
 
298
- syslog_event = LogStash::Event.new({ "message" => "<164>Oct 26 15:19:25 1.2.3.4 %ASA-4-106023: Deny udp src DRAC:10.1.2.3/43434" })
299
- input.syslog_relay(syslog_event)
300
- expect( syslog_event.get("priority") ).to eql 164
301
- expect( syslog_event.get("severity") ).to eql 4
302
- expect( syslog_event.get("tags") ).to be nil
396
+ it 'should close connection when client sends EOF' do
397
+ expect( socket ).to receive(:read_nonblock).and_raise(EOFError)
398
+ expect( socket ).to receive(:close)
399
+ allow( plugin.logger ).to receive(:info)
303
400
 
304
- input.close
305
- end
401
+ plugin.send :tcp_receiver, queue, socket
306
402
 
307
- it_behaves_like 'an interruptible input plugin' do
308
- let(:config) { { "port" => 5511 } }
309
- end
403
+ expect( plugin.logger ).to have_received(:info).with(/connection closed/, anything)
404
+ expect( queue.size ).to eql 0
405
+ end
310
406
 
311
- it "should properly handle a custom grok_pattern" do
312
- port = 5511
313
- event_count = 1
314
- custom_grok = "<%{POSINT:priority}>%{SYSLOGTIMESTAMP:timestamp} atypical %{GREEDYDATA:message}"
315
- message_field = "This part constitutes the message field"
316
- timestamp = "Oct 26 15:19:25"
317
- custom_line = "<164>#{timestamp} atypical #{message_field}"
318
-
319
- conf = <<-CONFIG
320
- input {
321
- syslog {
322
- type => "blah"
323
- port => #{port}
324
- grok_pattern => "#{custom_grok}"
325
- }
326
- }
327
- CONFIG
328
-
329
- events = input(conf) do |pipeline, queue|
330
- socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
331
- event_count.times do |i|
332
- socket.puts(custom_line)
407
+ it 'should properly read partially received messages' do
408
+ expect( socket ).to receive(:close)
409
+ allow( plugin.codec ).to receive(:decode).and_call_original
410
+
411
+ messages = ["<133>Mar 11 08:44:43 localhost message 2\n", "message 1\n", "<133>Mar 11 08:44:43 localhost ", ]
412
+ allow( socket ).to receive(:read_nonblock).at_least(messages.size).times do
413
+ msg = messages.pop
414
+ raise EOFError unless msg
415
+ msg
333
416
  end
334
- socket.close
335
417
 
336
- event_count.times.collect { queue.pop }
337
- end
418
+ plugin.send :tcp_receiver, queue, socket
338
419
 
339
- expect( events.length ).to eql event_count
340
- events.each do |event|
341
- expect( event.get("priority") ).to eql 164
342
- expect( event.get("severity") ).to eql 4
343
- expect( event.get("facility") ).to eql 20
344
- expect( event.get("message") ).to eql "#{message_field}\n"
345
- expect( event.get("timestamp") ).to eql timestamp
420
+ expect( queue.size ).to eql 2
421
+ expect( plugin.codec ).to have_received(:decode).with("<133>Mar 11 08:44:43 localhost message 1\n")
422
+ expect( plugin.codec ).to have_received(:decode).with("<133>Mar 11 08:44:43 localhost message 2\n")
346
423
  end
347
424
  end
348
425
 
349
- it "should properly handle the cef codec with a custom grok_pattern" do
350
- port = 5511
351
- event_count = 1
352
- custom_grok = "<%{POSINT:priority}>%{TIMESTAMP_ISO8601:timestamp} atypical"
353
- message_field = "Description Omitted"
354
- timestamp = "2018-02-07T12:40:00.000Z"
355
- custom_line = "<134>#{timestamp} atypical CEF:0|Company Name|Application Name|Application Version Number|632|Syslog Configuration Updated|3|src=192.168.0.1 suser=user@example.com target=TARGET msg=#{message_field} KeyValueOne=kv1 KeyValueTwo=12345 "
356
-
357
- conf = <<-CONFIG
358
- input {
359
- syslog {
360
- port => #{port}
361
- syslog_field => "syslog"
362
- grok_pattern => "#{custom_grok}"
363
- codec => cef
364
- }
365
- }
366
- CONFIG
367
-
368
- events = input(conf) do |pipeline, queue|
369
- socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
370
- event_count.times do |i|
371
- socket.puts(custom_line)
372
- end
373
- socket.close
374
426
 
375
- event_count.times.collect { queue.pop }
376
- end
377
-
378
- expect( events.length ).to eql event_count
379
- events.each do |event|
380
- expect( event.get("priority") ).to eql 134
381
- expect( event.get("severity") ).to eql 6
382
- expect( event.get("facility") ).to eql 16
383
- expect( event.get("message") ).to eql message_field
384
- expect( event.get("timestamp") ).to eql timestamp
385
- end
427
+ it_behaves_like 'an interruptible input plugin' do
428
+ let(:config) { { "port" => 5511 } }
386
429
  end
387
430
 
388
431
  private
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-syslog
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.0
4
+ version: 3.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-11 00:00:00.000000000 Z
11
+ date: 2023-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -187,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
187
  - !ruby/object:Gem::Version
188
188
  version: '0'
189
189
  requirements: []
190
- rubygems_version: 3.1.6
190
+ rubygems_version: 3.2.33
191
191
  signing_key:
192
192
  specification_version: 4
193
193
  summary: Reads syslog messages as events