logstash-input-syslog 3.5.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/docs/index.asciidoc +1 -1
- data/lib/logstash/inputs/syslog.rb +18 -3
- data/logstash-input-syslog.gemspec +4 -4
- data/spec/inputs/syslog_spec.rb +243 -199
- metadata +11 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c25de14662bbd82e873e09199f770ae115e73ab837d78300ad23d2f1a5f8617
|
4
|
+
data.tar.gz: ce332bc77901424f297d992d43c08999fbc30cc69547af624ead0d3aef2486f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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.
|
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.
|
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.
|
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
|
|
data/spec/inputs/syslog_spec.rb
CHANGED
@@ -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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
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(
|
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
|
-
|
134
|
-
expect(
|
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
|
-
|
139
|
-
|
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
|
-
|
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(
|
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
|
-
|
180
|
-
|
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
|
-
|
183
|
-
input {
|
184
|
-
|
185
|
-
|
186
|
-
|
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
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
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
|
-
|
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
|
-
|
200
|
-
|
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
|
-
|
204
|
-
|
205
|
-
|
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
|
-
|
265
|
+
event_count.times.collect { queue.pop }
|
266
|
+
end
|
208
267
|
|
209
|
-
|
210
|
-
|
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
|
-
|
274
|
+
it "should properly handle no locale and no timezone" do
|
275
|
+
port = 5511
|
213
276
|
|
214
|
-
|
215
|
-
|
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(
|
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
|
-
|
289
|
-
|
290
|
-
|
384
|
+
context 'tcp receiver' do
|
385
|
+
subject(:plugin) { LogStash::Inputs::Syslog.new }
|
386
|
+
before { plugin.register }
|
387
|
+
after { plugin.close }
|
291
388
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
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
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
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
|
-
|
304
|
-
end
|
401
|
+
plugin.send :tcp_receiver, queue, socket
|
305
402
|
|
306
|
-
|
307
|
-
|
308
|
-
|
403
|
+
expect( plugin.logger ).to have_received(:info).with(/connection closed/, anything)
|
404
|
+
expect( queue.size ).to eql 0
|
405
|
+
end
|
309
406
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
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
|
-
|
336
|
-
end
|
418
|
+
plugin.send :tcp_receiver, queue, socket
|
337
419
|
|
338
|
-
|
339
|
-
|
340
|
-
expect(
|
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
|
-
|
375
|
-
|
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.
|
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:
|
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.
|
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.
|
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.
|
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.
|
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: '
|
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: '
|
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
|
-
|
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
|