logstash-input-syslog 3.5.0 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f54c37d7c50508f001a49df641a45df74cf61cf4c4a4fcebafef442e380df68
4
- data.tar.gz: 8c269bbad63b3ee0b022e7e206fc0884ed213b38380b15bdda9ee421e7f8ebeb
3
+ metadata.gz: 0c25de14662bbd82e873e09199f770ae115e73ab837d78300ad23d2f1a5f8617
4
+ data.tar.gz: ce332bc77901424f297d992d43c08999fbc30cc69547af624ead0d3aef2486f7
5
5
  SHA512:
6
- metadata.gz: 8c886952d2095e9cefddeaaebbefa8495b78732b74350a6579849dd22da8f85f3065a35b411ce8952cd2cb12a80d49468cb44eeabfac4d93d8610663f7536366
7
- data.tar.gz: a254785ecca431fc409bd2ebd031a14b2901295f2293913c6d7f92629327e8694e1ee2e13e7e04898cdc7c1939f29b1a6bb674e5dbc183b7c5c1487146d47284
6
+ metadata.gz: 5a1cf93965af7f77e9f543d339567c0cba16e481d325c345fea9fcd945a85f032ab87ff4f135c4ebff82c44f14365e650e9e6fe08ef546efab42c8ba56cd273e
7
+ data.tar.gz: b6c4d596cac63c5432717086040ba6fb03cb2f7ae17b813f7414facef60c33cd3f3ea3239e5933768e2ca03721e596744d3301126087bc224db1c8abb09e4d72
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
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
+
6
+ ## 3.6.0
7
+ - Add support for ECS v8 as alias to v1 implementation [#68](https://github.com/logstash-plugins/logstash-input-syslog/pull/68)
8
+
1
9
  ## 3.5.0
2
10
  - Feat: ECS compatibility support [#63](https://github.com/logstash-plugins/logstash-input-syslog/pull/63)
3
11
 
data/docs/index.asciidoc CHANGED
@@ -71,7 +71,7 @@ input plugins.
71
71
  * Value type is <<string,string>>
72
72
  * Supported values are:
73
73
  ** `disabled`: does not use ECS-compatible field names (for example, `priority` for syslog priority)
74
- ** `v1`: uses fields that are compatible with Elastic Common Schema (for example, `[log][syslog][priority]`)
74
+ ** `v1`,`v8`: uses fields that are compatible with Elastic Common Schema (for example, `[log][syslog][priority]`)
75
75
  * Default value depends on which version of Logstash is running:
76
76
  ** When Logstash provides a `pipeline.ecs_compatibility` setting, its value is used as the default
77
77
  ** Otherwise, the default value is `disabled`.
@@ -26,7 +26,7 @@ require "stud/interval"
26
26
  # Note: This input will start listeners on both TCP and UDP.
27
27
  #
28
28
  class LogStash::Inputs::Syslog < LogStash::Inputs::Base
29
- include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled, :v1)
29
+ include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled, :v1, :v8 => :v1)
30
30
 
31
31
  config_name "syslog"
32
32
 
@@ -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.5.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"
@@ -21,16 +21,16 @@ Gem::Specification.new do |s|
21
21
 
22
22
  # Gem dependencies
23
23
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
- s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~> 1.1'
24
+ s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~> 1.2'
25
25
 
26
26
  s.add_runtime_dependency 'concurrent-ruby'
27
27
  s.add_runtime_dependency 'stud', '>= 0.0.22', '< 0.1.0'
28
28
 
29
29
  s.add_runtime_dependency 'logstash-codec-plain'
30
- s.add_runtime_dependency 'logstash-filter-grok', '>= 4.4.0'
30
+ s.add_runtime_dependency 'logstash-filter-grok', '>= 4.4.1'
31
31
  s.add_runtime_dependency 'logstash-filter-date'
32
32
 
33
- s.add_development_dependency 'logstash-devutils'
33
+ s.add_development_dependency 'logstash-devutils', '~> 2.3'
34
34
  s.add_development_dependency 'logstash-codec-cef'
35
35
  end
36
36
 
@@ -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) 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,52 +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_iso8601 ).to eql "#{Time.now.year}-10-26T15:19:25.000Z"
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 ignore the hours
200
- expect( event.get("@timestamp").to_iso8601 ).to match /#{Time.now.year}-10-26T\d\d:19:25.000Z/
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
201
240
  end
202
241
 
203
- it "should support non UTC timezone" do
204
- input = LogStash::Inputs::Syslog.new({"timezone" => "-05:00"})
205
- 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
206
264
 
207
- # event which is not syslog should have a new tag
265
+ event_count.times.collect { queue.pop }
266
+ end
208
267
 
209
- 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" })
210
- 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
211
273
 
212
- expect( syslog_event.get("@timestamp").to_iso8601 ).to eql "#{Time.now.year}-10-26T20:19:25.000Z"
274
+ it "should properly handle no locale and no timezone" do
275
+ port = 5511
213
276
 
214
- input.close
215
- 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
216
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
217
313
  end
218
314
  end
219
315
 
220
- context 'ECS behavior', :ecs_compatibility_support do
316
+ context 'ECS :v1 behavior', :ecs_compatibility_support do
221
317
 
222
318
  ecs_compatibility_matrix(:v1) do
223
319
 
@@ -269,7 +365,7 @@ describe LogStash::Inputs::Syslog do
269
365
 
270
366
  let(:socket) do
271
367
  server = double('tcp-server')
272
- 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")
273
369
  allow( server ).to receive(:close)
274
370
  server
275
371
  end
@@ -285,103 +381,51 @@ describe LogStash::Inputs::Syslog do
285
381
  end
286
382
  end
287
383
 
288
- it "should add unique tag when grok parsing fails" do
289
- input = LogStash::Inputs::Syslog.new({})
290
- input.register
384
+ context 'tcp receiver' do
385
+ subject(:plugin) { LogStash::Inputs::Syslog.new }
386
+ before { plugin.register }
387
+ after { plugin.close }
291
388
 
292
- # event which is not syslog should have a new tag
293
- event = LogStash::Event.new({ "message" => "hello world, this is not syslog RFC3164" })
294
- input.syslog_relay(event)
295
- 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
296
395
 
297
- 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" })
298
- input.syslog_relay(syslog_event)
299
- expect( syslog_event.get("priority") ).to eql 164
300
- expect( syslog_event.get("severity") ).to eql 4
301
- 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)
302
400
 
303
- input.close
304
- end
401
+ plugin.send :tcp_receiver, queue, socket
305
402
 
306
- it_behaves_like 'an interruptible input plugin' do
307
- let(:config) { { "port" => 5511 } }
308
- end
403
+ expect( plugin.logger ).to have_received(:info).with(/connection closed/, anything)
404
+ expect( queue.size ).to eql 0
405
+ end
309
406
 
310
- it "should properly handle a custom grok_pattern" do
311
- port = 5511
312
- event_count = 1
313
- custom_grok = "<%{POSINT:priority}>%{SYSLOGTIMESTAMP:timestamp} atypical %{GREEDYDATA:message}"
314
- message_field = "This part constitutes the message field"
315
- timestamp = "Oct 26 15:19:25"
316
- custom_line = "<164>#{timestamp} atypical #{message_field}"
317
-
318
- conf = <<-CONFIG
319
- input {
320
- syslog {
321
- type => "blah"
322
- port => #{port}
323
- grok_pattern => "#{custom_grok}"
324
- }
325
- }
326
- CONFIG
327
-
328
- events = input(conf) do |pipeline, queue|
329
- socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
330
- event_count.times do |i|
331
- 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
332
416
  end
333
- socket.close
334
417
 
335
- event_count.times.collect { queue.pop }
336
- end
418
+ plugin.send :tcp_receiver, queue, socket
337
419
 
338
- expect( events.length ).to eql event_count
339
- events.each do |event|
340
- expect( event.get("priority") ).to eql 164
341
- expect( event.get("severity") ).to eql 4
342
- expect( event.get("facility") ).to eql 20
343
- expect( event.get("message") ).to eql "#{message_field}\n"
344
- 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")
345
423
  end
346
424
  end
347
425
 
348
- it "should properly handle the cef codec with a custom grok_pattern" do
349
- port = 5511
350
- event_count = 1
351
- custom_grok = "<%{POSINT:priority}>%{TIMESTAMP_ISO8601:timestamp} atypical"
352
- message_field = "Description Omitted"
353
- timestamp = "2018-02-07T12:40:00.000Z"
354
- 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 "
355
-
356
- conf = <<-CONFIG
357
- input {
358
- syslog {
359
- port => #{port}
360
- syslog_field => "syslog"
361
- grok_pattern => "#{custom_grok}"
362
- codec => cef
363
- }
364
- }
365
- CONFIG
366
-
367
- events = input(conf) do |pipeline, queue|
368
- socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
369
- event_count.times do |i|
370
- socket.puts(custom_line)
371
- end
372
- socket.close
373
426
 
374
- event_count.times.collect { queue.pop }
375
- end
376
-
377
- expect( events.length ).to eql event_count
378
- events.each do |event|
379
- expect( event.get("priority") ).to eql 134
380
- expect( event.get("severity") ).to eql 6
381
- expect( event.get("facility") ).to eql 16
382
- expect( event.get("message") ).to eql message_field
383
- expect( event.get("timestamp") ).to eql timestamp
384
- end
427
+ it_behaves_like 'an interruptible input plugin' do
428
+ let(:config) { { "port" => 5511 } }
385
429
  end
386
430
 
387
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.5.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-03-22 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
@@ -35,7 +35,7 @@ dependencies:
35
35
  requirements:
36
36
  - - "~>"
37
37
  - !ruby/object:Gem::Version
38
- version: '1.1'
38
+ version: '1.2'
39
39
  name: logstash-mixin-ecs_compatibility_support
40
40
  prerelease: false
41
41
  type: :runtime
@@ -43,7 +43,7 @@ dependencies:
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '1.1'
46
+ version: '1.2'
47
47
  - !ruby/object:Gem::Dependency
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  requirements:
@@ -97,7 +97,7 @@ dependencies:
97
97
  requirements:
98
98
  - - ">="
99
99
  - !ruby/object:Gem::Version
100
- version: 4.4.0
100
+ version: 4.4.1
101
101
  name: logstash-filter-grok
102
102
  prerelease: false
103
103
  type: :runtime
@@ -105,7 +105,7 @@ dependencies:
105
105
  requirements:
106
106
  - - ">="
107
107
  - !ruby/object:Gem::Version
108
- version: 4.4.0
108
+ version: 4.4.1
109
109
  - !ruby/object:Gem::Dependency
110
110
  requirement: !ruby/object:Gem::Requirement
111
111
  requirements:
@@ -123,17 +123,17 @@ dependencies:
123
123
  - !ruby/object:Gem::Dependency
124
124
  requirement: !ruby/object:Gem::Requirement
125
125
  requirements:
126
- - - ">="
126
+ - - "~>"
127
127
  - !ruby/object:Gem::Version
128
- version: '0'
128
+ version: '2.3'
129
129
  name: logstash-devutils
130
130
  prerelease: false
131
131
  type: :development
132
132
  version_requirements: !ruby/object:Gem::Requirement
133
133
  requirements:
134
- - - ">="
134
+ - - "~>"
135
135
  - !ruby/object:Gem::Version
136
- version: '0'
136
+ version: '2.3'
137
137
  - !ruby/object:Gem::Dependency
138
138
  requirement: !ruby/object:Gem::Requirement
139
139
  requirements:
@@ -187,8 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
187
  - !ruby/object:Gem::Version
188
188
  version: '0'
189
189
  requirements: []
190
- rubyforge_project:
191
- rubygems_version: 2.6.13
190
+ rubygems_version: 3.2.33
192
191
  signing_key:
193
192
  specification_version: 4
194
193
  summary: Reads syslog messages as events