logstash-input-syslog 3.6.0 → 3.7.1

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: 630e8328b3161d33d8d34489893a654e8310aa871a827bceb3911454f149bd34
4
+ data.tar.gz: 8e7c5b275c4169a83a20cd0a2a41b4d3b746d9b4a7e5aedc6360f917cd9660cc
5
5
  SHA512:
6
- metadata.gz: ea924072e2e8904864649a6be3706523dca20a01c1c7aef441fea1c643f93e78dcb12d869ffb1f4d16ee2ebbdcdf4a396f45d6b3fc77909ad247941a849f9e6d
7
- data.tar.gz: d3d658703fa56537a9818f65b92ddba37e8f56e760beda02698b1782c5f89eb9dc6c279c18a0611ecf653f3c9b07894549edf5b750855fc0f42500862f7d6f4a
6
+ metadata.gz: 69270b0499c4768ec2bbacff35dd35aacdd8e24944ad24d873291c4e83ce780eecba5afeff97b10d360daaf14d0601c473f631b6af6f27a0b33d239c22ca93db
7
+ data.tar.gz: 361942102a239e8797c2364942659c31245ffcf5149203530d2e47834ff2d5b04c834bd2001aa07cfd363afe40918a5923b5da61b886d207aee251c70e0b57ff
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 3.7.1
2
+ - Fix issue where the priority field was not being set correctly when grok failed [#76](https://github.com/logstash-plugins/logstash-input-syslog/pull/78)
3
+
4
+ ## 3.7.0
5
+ - Changed the TCP reading mode to use the non-blocking method [#75](https://github.com/logstash-plugins/logstash-input-syslog/pull/75)
6
+ It fixes the high CPU usage when TCP clients do not properly disconnect/send EOF.
7
+ - Fixed broken tests
8
+
1
9
  ## 3.6.0
2
10
  - Add support for ECS v8 as alias to v1 implementation [#68](https://github.com/logstash-plugins/logstash-input-syslog/pull/68)
3
11
 
@@ -83,6 +83,8 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
83
83
  # assuming users would want that (they have specific use-case for LS as syslog server).
84
84
  config :service_type, :validate => :string, :default => 'system'
85
85
 
86
+ GROK_FAILURE_TAG = "_grokparsefailure_sysloginput"
87
+
86
88
  def initialize(*params)
87
89
  super
88
90
 
@@ -103,7 +105,7 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
103
105
  @grok_filter = LogStash::Filters::Grok.new(
104
106
  "overwrite" => @syslog_field,
105
107
  "match" => { @syslog_field => @grok_pattern },
106
- "tag_on_failure" => ["_grokparsefailure_sysloginput"],
108
+ "tag_on_failure" => [GROK_FAILURE_TAG],
107
109
  "ecs_compatibility" => ecs_compatibility # use ecs-compliant patterns
108
110
  )
109
111
 
@@ -221,6 +223,21 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
221
223
  close_tcp
222
224
  end # def tcp_listener
223
225
 
226
+ def tcp_read_lines(socket)
227
+ buffer = String.new
228
+ loop do
229
+ begin
230
+ buffer << socket.read_nonblock(1024)
231
+ while (newline = buffer.index("\n"))
232
+ yield buffer.slice!(0..newline)
233
+ end
234
+ rescue IO::WaitReadable
235
+ IO.select([socket], nil)
236
+ retry
237
+ end
238
+ end
239
+ end
240
+
224
241
  # tcp_receiver is executed in a thread, any uncatched exception will be bubbled up to the
225
242
  # tcp server thread and all tcp connections will be closed and the listener restarted.
226
243
  def tcp_receiver(output_queue, socket)
@@ -232,7 +249,7 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
232
249
 
233
250
  first_read = true
234
251
 
235
- socket.each do |line|
252
+ tcp_read_lines(socket) do |line|
236
253
  metric.increment(:messages_received)
237
254
  if @proxy_protocol && first_read
238
255
  first_read = false
@@ -253,7 +270,7 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
253
270
  rescue Errno::ECONNRESET
254
271
  # swallow connection reset exceptions to avoid bubling up the tcp_listener & server
255
272
  logger.info("connection reset", :client => "#{ip}:#{port}")
256
- rescue Errno::EBADF
273
+ rescue Errno::EBADF, EOFError
257
274
  # swallow connection closed exceptions to avoid bubling up the tcp_listener & server
258
275
  logger.info("connection closed", :client => "#{ip}:#{port}")
259
276
  rescue IOError => e
@@ -326,10 +343,14 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
326
343
  def syslog_relay(event)
327
344
  @grok_filter_exec.(event)
328
345
 
329
- if event.get("tags").nil? || !event.get("tags").include?(@grok_filter.tag_on_failure)
346
+ if event.get("tags").nil? || !event.get("tags").include?(GROK_FAILURE_TAG)
330
347
  # Per RFC3164, priority = (facility * 8) + severity
331
348
  # = (facility << 3) & (severity)
332
- priority = event.get(@priority_key).to_i rescue 13
349
+ priority = if event.include?(@priority_key)
350
+ event.get(@priority_key).to_i rescue 13
351
+ else
352
+ 13
353
+ end
333
354
  set_priority event, priority
334
355
 
335
356
  @date_filter_exec.(event)
@@ -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.1'
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,218 @@ 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
+ expect( event.get(priority_key) ).to eql 13
149
+
150
+ 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" })
151
+ input.syslog_relay(syslog_event)
152
+ expect( syslog_event.get(priority_key) ).to eql 164
153
+ expect( syslog_event.get(severity_key) ).to eql 4
154
+ expect( syslog_event.get("tags") ).to be nil
155
+
156
+ input.close
157
+ end
158
+
159
+ it "should properly handle a custom grok_pattern" do
160
+ port = 5511
161
+ event_count = 1
162
+ custom_grok = "<%{POSINT:#{priority_key}}>%{SYSLOGTIMESTAMP:timestamp} atypical %{GREEDYDATA:message}"
163
+ message_field = "This part constitutes the message field"
164
+ timestamp = "Oct 26 15:19:25"
165
+ custom_line = "<164>#{timestamp} atypical #{message_field}"
166
+
167
+ conf = <<-CONFIG
168
+ input {
169
+ syslog {
170
+ type => "blah"
171
+ port => #{port}
172
+ grok_pattern => "#{custom_grok}"
173
+ }
187
174
  }
188
- }
189
- CONFIG
175
+ CONFIG
190
176
 
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
177
+ events = input(conf) do |pipeline, queue|
178
+ socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
179
+ event_count.times do |i|
180
+ socket.puts(custom_line)
181
+ end
182
+ socket.close
183
+
184
+ event_count.times.collect { queue.pop }
185
+ end
195
186
 
196
- queue.pop
187
+ expect( events.length ).to eql event_count
188
+ events.each do |event|
189
+ expect( event.get(priority_key) ).to eql 164
190
+ expect( event.get(severity_key) ).to eql 4
191
+ expect( event.get(facility_key) ).to eql 20
192
+ expect( event.get("message") ).to eql "#{message_field}\n"
193
+ expect( event.get('timestamp') ).to eql timestamp if ecs_compatibility == :disabled
194
+ expect( event.include?('timestamp') ).to be false if ecs_compatibility != :disabled
195
+ end
197
196
  end
198
197
 
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)
198
+ it "should properly handle the cef codec with a custom grok_pattern" do
199
+ port = 5511
200
+ event_count = 1
201
+
202
+ custom_grok = "<%{POSINT:#{priority_key}}>%{TIMESTAMP_ISO8601:timestamp} atypical %{GREEDYDATA:syslog_message}"
203
+ timestamp = "2018-02-07T12:40:00.000Z"
204
+ cef_message = "Description Omitted"
205
+ syslog_message = "foo bar"
206
+ syslog_message_envelope = "<134>#{timestamp} atypical #{syslog_message}"
207
+ 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 "
208
+
209
+ conf = <<-CONFIG
210
+ input {
211
+ syslog {
212
+ port => #{port}
213
+ syslog_field => "syslog"
214
+ grok_pattern => "#{custom_grok}"
215
+ codec => cef { ecs_compatibility => #{ ecs_compatibility } }
216
+ }
217
+ }
218
+ CONFIG
219
+
220
+ events = input(conf) do |pipeline, queue|
221
+ socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
222
+ event_count.times do |i|
223
+ socket.puts(custom_line)
224
+ end
225
+ socket.close
226
+
227
+ event_count.times.collect { queue.pop }
228
+ end
229
+
230
+ expect( events.length ).to eql event_count
231
+ events.each do |event|
232
+ expect( event.get(priority_key) ).to eql 134
233
+ expect( event.get(severity_key) ).to eql 6
234
+ expect( event.get(facility_key) ).to eql 16
235
+ expect( event.get("message") ).to eql cef_message
236
+ expect( event.get("syslog_message") ).to eql syslog_message
237
+ expect( event.get('timestamp') ).to eql timestamp if ecs_compatibility == :disabled
238
+ expect( event.include?('timestamp') ).to be false if ecs_compatibility != :disabled
239
+ end
240
+ end
202
241
  end
203
242
 
204
- it "should support non UTC timezone" do
205
- input = LogStash::Inputs::Syslog.new({"timezone" => "-05:00"})
206
- input.register
243
+ context 'timestamp' do
244
+ it "should properly handle locale and timezone" do
245
+ port = 5511
246
+ event_count = 10
247
+
248
+ conf = <<-CONFIG
249
+ input {
250
+ syslog {
251
+ type => "blah"
252
+ port => #{port}
253
+ locale => "en"
254
+ timezone => "UTC"
255
+ }
256
+ }
257
+ CONFIG
258
+
259
+ events = input(conf) do |pipeline, queue|
260
+ socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
261
+ event_count.times do |i|
262
+ socket.puts(SYSLOG_LINE)
263
+ end
264
+ socket.close
207
265
 
208
- # event which is not syslog should have a new tag
266
+ event_count.times.collect { queue.pop }
267
+ end
209
268
 
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)
269
+ expect( events.length ).to eql event_count
270
+ events.each do |event|
271
+ expect( event.get("@timestamp") ).to be_a_logstash_timestamp_equivalent_to("#{Time.now.year}-10-26T15:19:25Z")
272
+ end
273
+ end
212
274
 
213
- expect( syslog_event.get("@timestamp") ).to be_a_logstash_timestamp_equivalent_to("#{Time.now.year}-10-26T20:19:25Z")
275
+ it "should properly handle no locale and no timezone" do
276
+ port = 5511
214
277
 
215
- input.close
216
- end
278
+ conf = <<-CONFIG
279
+ input {
280
+ syslog {
281
+ type => "blah"
282
+ port => #{port}
283
+ }
284
+ }
285
+ CONFIG
286
+
287
+ event = input(conf) do |pipeline, queue|
288
+ socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
289
+ socket.puts(SYSLOG_LINE)
290
+ socket.close
291
+
292
+ queue.pop
293
+ end
217
294
 
295
+ # chances platform timezone is not UTC, so parse without offset to create expectation
296
+ equivalent_time = Time.parse("#{Time.now.year}-10-26T15:19:25")
297
+ expect( event.get("@timestamp") ).to be_a_logstash_timestamp_equivalent_to(equivalent_time)
298
+ end
299
+
300
+ it "should support non UTC timezone" do
301
+ input = LogStash::Inputs::Syslog.new({"timezone" => "-05:00"})
302
+ input.register
303
+
304
+ # event which is not syslog should have a new tag
305
+
306
+ 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" })
307
+ input.syslog_relay(syslog_event)
308
+
309
+ expect( syslog_event.get("@timestamp") ).to be_a_logstash_timestamp_equivalent_to("#{Time.now.year}-10-26T20:19:25Z")
310
+
311
+ input.close
312
+ end
313
+ end
218
314
  end
219
315
  end
220
316
 
221
- context 'ECS behavior', :ecs_compatibility_support do
317
+ context 'ECS :v1 behavior', :ecs_compatibility_support do
222
318
 
223
319
  ecs_compatibility_matrix(:v1) do
224
320
 
@@ -270,7 +366,7 @@ describe LogStash::Inputs::Syslog do
270
366
 
271
367
  let(:socket) do
272
368
  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"
369
+ 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
370
  allow( server ).to receive(:close)
275
371
  server
276
372
  end
@@ -286,103 +382,51 @@ describe LogStash::Inputs::Syslog do
286
382
  end
287
383
  end
288
384
 
289
- it "should add unique tag when grok parsing fails" do
290
- input = LogStash::Inputs::Syslog.new({})
291
- input.register
385
+ context 'tcp receiver' do
386
+ subject(:plugin) { LogStash::Inputs::Syslog.new }
387
+ before { plugin.register }
388
+ after { plugin.close }
292
389
 
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"]
390
+ let(:queue) { Queue.new }
391
+ let(:socket) do
392
+ socket = double('tcp-socket')
393
+ expect( socket ).to receive(:peeraddr).and_return(["AF_INET", 514, "192.168.0.10", "192.168.0.10"])
394
+ socket
395
+ end
297
396
 
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
397
+ it 'should close connection when client sends EOF' do
398
+ expect( socket ).to receive(:read_nonblock).and_raise(EOFError)
399
+ expect( socket ).to receive(:close)
400
+ allow( plugin.logger ).to receive(:info)
303
401
 
304
- input.close
305
- end
402
+ plugin.send :tcp_receiver, queue, socket
306
403
 
307
- it_behaves_like 'an interruptible input plugin' do
308
- let(:config) { { "port" => 5511 } }
309
- end
404
+ expect( plugin.logger ).to have_received(:info).with(/connection closed/, anything)
405
+ expect( queue.size ).to eql 0
406
+ end
310
407
 
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)
408
+ it 'should properly read partially received messages' do
409
+ expect( socket ).to receive(:close)
410
+ allow( plugin.codec ).to receive(:decode).and_call_original
411
+
412
+ messages = ["<133>Mar 11 08:44:43 localhost message 2\n", "message 1\n", "<133>Mar 11 08:44:43 localhost ", ]
413
+ allow( socket ).to receive(:read_nonblock).at_least(messages.size).times do
414
+ msg = messages.pop
415
+ raise EOFError unless msg
416
+ msg
333
417
  end
334
- socket.close
335
418
 
336
- event_count.times.collect { queue.pop }
337
- end
419
+ plugin.send :tcp_receiver, queue, socket
338
420
 
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
421
+ expect( queue.size ).to eql 2
422
+ expect( plugin.codec ).to have_received(:decode).with("<133>Mar 11 08:44:43 localhost message 1\n")
423
+ expect( plugin.codec ).to have_received(:decode).with("<133>Mar 11 08:44:43 localhost message 2\n")
346
424
  end
347
425
  end
348
426
 
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
427
 
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
428
+ it_behaves_like 'an interruptible input plugin' do
429
+ let(:config) { { "port" => 5511 } }
386
430
  end
387
431
 
388
432
  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.1
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: 2025-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -20,8 +20,8 @@ dependencies:
20
20
  - !ruby/object:Gem::Version
21
21
  version: '2.99'
22
22
  name: logstash-core-plugin-api
23
- prerelease: false
24
23
  type: :runtime
24
+ prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
@@ -37,8 +37,8 @@ dependencies:
37
37
  - !ruby/object:Gem::Version
38
38
  version: '1.2'
39
39
  name: logstash-mixin-ecs_compatibility_support
40
- prerelease: false
41
40
  type: :runtime
41
+ prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
@@ -51,8 +51,8 @@ dependencies:
51
51
  - !ruby/object:Gem::Version
52
52
  version: '0'
53
53
  name: concurrent-ruby
54
- prerelease: false
55
54
  type: :runtime
55
+ prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - ">="
@@ -68,8 +68,8 @@ dependencies:
68
68
  - !ruby/object:Gem::Version
69
69
  version: 0.1.0
70
70
  name: stud
71
- prerelease: false
72
71
  type: :runtime
72
+ prerelease: false
73
73
  version_requirements: !ruby/object:Gem::Requirement
74
74
  requirements:
75
75
  - - ">="
@@ -85,8 +85,8 @@ dependencies:
85
85
  - !ruby/object:Gem::Version
86
86
  version: '0'
87
87
  name: logstash-codec-plain
88
- prerelease: false
89
88
  type: :runtime
89
+ prerelease: false
90
90
  version_requirements: !ruby/object:Gem::Requirement
91
91
  requirements:
92
92
  - - ">="
@@ -99,8 +99,8 @@ dependencies:
99
99
  - !ruby/object:Gem::Version
100
100
  version: 4.4.1
101
101
  name: logstash-filter-grok
102
- prerelease: false
103
102
  type: :runtime
103
+ prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - ">="
@@ -113,8 +113,8 @@ dependencies:
113
113
  - !ruby/object:Gem::Version
114
114
  version: '0'
115
115
  name: logstash-filter-date
116
- prerelease: false
117
116
  type: :runtime
117
+ prerelease: false
118
118
  version_requirements: !ruby/object:Gem::Requirement
119
119
  requirements:
120
120
  - - ">="
@@ -127,8 +127,8 @@ dependencies:
127
127
  - !ruby/object:Gem::Version
128
128
  version: '2.3'
129
129
  name: logstash-devutils
130
- prerelease: false
131
130
  type: :development
131
+ prerelease: false
132
132
  version_requirements: !ruby/object:Gem::Requirement
133
133
  requirements:
134
134
  - - "~>"
@@ -141,8 +141,8 @@ dependencies:
141
141
  - !ruby/object:Gem::Version
142
142
  version: '0'
143
143
  name: logstash-codec-cef
144
- prerelease: false
145
144
  type: :development
145
+ prerelease: false
146
146
  version_requirements: !ruby/object:Gem::Requirement
147
147
  requirements:
148
148
  - - ">="
@@ -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.3.26
191
191
  signing_key:
192
192
  specification_version: 4
193
193
  summary: Reads syslog messages as events