logstash-input-syslog 3.4.5 → 3.5.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 +3 -0
- data/docs/index.asciidoc +18 -0
- data/lib/logstash/inputs/syslog.rb +111 -56
- data/logstash-input-syslog.gemspec +3 -2
- data/spec/inputs/syslog_spec.rb +171 -74
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f54c37d7c50508f001a49df641a45df74cf61cf4c4a4fcebafef442e380df68
|
4
|
+
data.tar.gz: 8c269bbad63b3ee0b022e7e206fc0884ed213b38380b15bdda9ee421e7f8ebeb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c886952d2095e9cefddeaaebbefa8495b78732b74350a6579849dd22da8f85f3065a35b411ce8952cd2cb12a80d49468cb44eeabfac4d93d8610663f7536366
|
7
|
+
data.tar.gz: a254785ecca431fc409bd2ebd031a14b2901295f2293913c6d7f92629327e8694e1ee2e13e7e04898cdc7c1939f29b1a6bb674e5dbc183b7c5c1487146d47284
|
data/CHANGELOG.md
CHANGED
data/docs/index.asciidoc
CHANGED
@@ -47,6 +47,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
47
47
|
[cols="<,<,<",options="header",]
|
48
48
|
|=======================================================================
|
49
49
|
|Setting |Input type|Required
|
50
|
+
| <<plugins-{type}s-{plugin}-ecs_compatibility>> | <<string,string>>|No
|
50
51
|
| <<plugins-{type}s-{plugin}-facility_labels>> |<<array,array>>|No
|
51
52
|
| <<plugins-{type}s-{plugin}-grok_pattern>> |<<string,string>>|No
|
52
53
|
| <<plugins-{type}s-{plugin}-host>> |<<string,string>>|No
|
@@ -64,6 +65,20 @@ input plugins.
|
|
64
65
|
|
65
66
|
|
66
67
|
|
68
|
+
[id="plugins-{type}s-{plugin}-ecs_compatibility"]
|
69
|
+
===== `ecs_compatibility`
|
70
|
+
|
71
|
+
* Value type is <<string,string>>
|
72
|
+
* Supported values are:
|
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]`)
|
75
|
+
* Default value depends on which version of Logstash is running:
|
76
|
+
** When Logstash provides a `pipeline.ecs_compatibility` setting, its value is used as the default
|
77
|
+
** Otherwise, the default value is `disabled`.
|
78
|
+
|
79
|
+
Controls this plugin's compatibility with the
|
80
|
+
{ecs-ref}[Elastic Common Schema (ECS)].
|
81
|
+
|
67
82
|
[id="plugins-{type}s-{plugin}-facility_labels"]
|
68
83
|
===== `facility_labels`
|
69
84
|
|
@@ -84,6 +99,9 @@ the facility_label is not added to the event.
|
|
84
99
|
|
85
100
|
* Value type is <<string,string>>
|
86
101
|
* Default value is `"<%{POSINT:priority}>%{SYSLOGLINE}"`
|
102
|
+
* Default value depends on whether <<plugins-{type}s-{plugin}-ecs_compatibility>> is enabled:
|
103
|
+
** ECS Compatibility disabled: `"<%{POSINT:priority}>%{SYSLOGLINE}"`
|
104
|
+
** ECS Compatibility enabled: `"<%{POSINT:[log][syslog][priority]:int}>%{SYSLOGLINE}"`
|
87
105
|
|
88
106
|
The default value should read and properly parse syslog lines which are
|
89
107
|
fully compliant with http://www.ietf.org/rfc/rfc3164.txt[RFC3164].
|
@@ -6,6 +6,7 @@ require "logstash/filters/grok"
|
|
6
6
|
require "logstash/filters/date"
|
7
7
|
require "logstash/inputs/base"
|
8
8
|
require "logstash/namespace"
|
9
|
+
require 'logstash/plugin_mixins/ecs_compatibility_support'
|
9
10
|
require "stud/interval"
|
10
11
|
|
11
12
|
# Read syslog messages as events over the network.
|
@@ -25,6 +26,8 @@ require "stud/interval"
|
|
25
26
|
# Note: This input will start listeners on both TCP and UDP.
|
26
27
|
#
|
27
28
|
class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
29
|
+
include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled, :v1)
|
30
|
+
|
28
31
|
config_name "syslog"
|
29
32
|
|
30
33
|
default :codec, "plain"
|
@@ -42,7 +45,7 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
42
45
|
|
43
46
|
# Set custom grok pattern to parse the syslog, in case the format differs
|
44
47
|
# from the defined standard. This is common in security and other appliances
|
45
|
-
config :grok_pattern, :validate => :string
|
48
|
+
config :grok_pattern, :validate => :string
|
46
49
|
|
47
50
|
# Proxy protocol support, only v1 is supported at this time
|
48
51
|
# http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
|
@@ -74,22 +77,67 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
74
77
|
#
|
75
78
|
config :locale, :validate => :string
|
76
79
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
+
# ECS only option to configure [service][type] value in produced events.
|
81
|
+
#
|
82
|
+
# NOTE: for now, purposefully un-documented as there are other [service] fields we could support,
|
83
|
+
# assuming users would want that (they have specific use-case for LS as syslog server).
|
84
|
+
config :service_type, :validate => :string, :default => 'system'
|
85
|
+
|
86
|
+
def initialize(*params)
|
87
|
+
super
|
88
|
+
|
89
|
+
@priority_key = ecs_select[disabled:'priority', v1:'[log][syslog][priority]']
|
90
|
+
@facility_key = ecs_select[disabled:'facility', v1:'[log][syslog][facility][code]']
|
91
|
+
@severity_key = ecs_select[disabled:'severity', v1:'[log][syslog][severity][code]']
|
92
|
+
|
93
|
+
@facility_label_key = ecs_select[disabled:'facility_label', v1:'[log][syslog][facility][name]']
|
94
|
+
@severity_label_key = ecs_select[disabled:'severity_label', v1:'[log][syslog][severity][name]']
|
95
|
+
|
96
|
+
@host_key = ecs_select[disabled:'host', v1:'[host][ip]']
|
97
|
+
|
98
|
+
@grok_pattern ||= ecs_select[
|
99
|
+
disabled:"<%{POSINT:#{@priority_key}}>%{SYSLOGLINE}",
|
100
|
+
v1:"<%{POSINT:#{@priority_key}:int}>%{SYSLOGLINE}"
|
101
|
+
]
|
80
102
|
|
81
103
|
@grok_filter = LogStash::Filters::Grok.new(
|
82
|
-
|
83
|
-
|
84
|
-
|
104
|
+
"overwrite" => @syslog_field,
|
105
|
+
"match" => { @syslog_field => @grok_pattern },
|
106
|
+
"tag_on_failure" => ["_grokparsefailure_sysloginput"],
|
107
|
+
"ecs_compatibility" => ecs_compatibility # use ecs-compliant patterns
|
85
108
|
)
|
86
109
|
|
110
|
+
@grok_filter_exec = ecs_select[
|
111
|
+
disabled: -> (event) { @grok_filter.filter(event) },
|
112
|
+
v1: -> (event) {
|
113
|
+
event.set('[event][original]', event.get(@syslog_field))
|
114
|
+
@grok_filter.filter(event)
|
115
|
+
set_service_fields(event)
|
116
|
+
}
|
117
|
+
]
|
118
|
+
|
87
119
|
@date_filter = LogStash::Filters::Date.new(
|
88
|
-
|
89
|
-
|
90
|
-
|
120
|
+
"match" => [ "timestamp", "MMM dd HH:mm:ss", "MMM d HH:mm:ss", "MMM d HH:mm:ss", "ISO8601"],
|
121
|
+
"locale" => @locale,
|
122
|
+
"timezone" => @timezone,
|
91
123
|
)
|
92
124
|
|
125
|
+
@date_filter_exec = ecs_select[
|
126
|
+
disabled: -> (event) {
|
127
|
+
# in legacy (non-ecs) mode we used to match (SYSLOGBASE2) timestamp into two fields
|
128
|
+
event.set("timestamp", event.get("timestamp8601")) if event.include?("timestamp8601")
|
129
|
+
@date_filter.filter(event)
|
130
|
+
},
|
131
|
+
v1: -> (event) {
|
132
|
+
@date_filter.filter(event)
|
133
|
+
event.remove('timestamp')
|
134
|
+
}
|
135
|
+
]
|
136
|
+
end
|
137
|
+
|
138
|
+
def register
|
139
|
+
@metric_errors = metric.namespace(:errors)
|
140
|
+
|
93
141
|
@grok_filter.register
|
94
142
|
@date_filter.register
|
95
143
|
|
@@ -97,7 +145,8 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
97
145
|
@tcp = @udp = nil
|
98
146
|
end # def register
|
99
147
|
|
100
|
-
|
148
|
+
private
|
149
|
+
|
101
150
|
def run(output_queue)
|
102
151
|
udp_thr = Thread.new(output_queue) do |output_queue|
|
103
152
|
server(:udp, output_queue)
|
@@ -112,8 +161,8 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
112
161
|
udp_thr.join
|
113
162
|
tcp_thr.join
|
114
163
|
end # def run
|
164
|
+
public :run
|
115
165
|
|
116
|
-
private
|
117
166
|
# server call the specified protocol listener and basically restarts on
|
118
167
|
# any listener uncatched exception
|
119
168
|
#
|
@@ -130,7 +179,6 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
130
179
|
end
|
131
180
|
end
|
132
181
|
|
133
|
-
private
|
134
182
|
# udp_listener creates the udp socket and continously read from it.
|
135
183
|
# upon exception the socket will be closed and the exception bubbled
|
136
184
|
# in the server which will restart the listener
|
@@ -151,7 +199,6 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
151
199
|
close_udp
|
152
200
|
end # def udp_listener
|
153
201
|
|
154
|
-
private
|
155
202
|
# tcp_listener accepts tcp connections and creates a new tcp_receiver thread
|
156
203
|
# for each accepted socket.
|
157
204
|
# upon exception all tcp sockets will be closed and the exception bubbled
|
@@ -177,11 +224,14 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
177
224
|
# tcp_receiver is executed in a thread, any uncatched exception will be bubbled up to the
|
178
225
|
# tcp server thread and all tcp connections will be closed and the listener restarted.
|
179
226
|
def tcp_receiver(output_queue, socket)
|
180
|
-
|
181
|
-
|
227
|
+
peer_addr = socket.peeraddr
|
228
|
+
ip, port = peer_addr[3], peer_addr[1]
|
229
|
+
|
182
230
|
@logger.info("new connection", :client => "#{ip}:#{port}")
|
183
231
|
LogStash::Util::set_thread_name("input|syslog|tcp|#{ip}:#{port}}")
|
184
232
|
|
233
|
+
first_read = true
|
234
|
+
|
185
235
|
socket.each do |line|
|
186
236
|
metric.increment(:messages_received)
|
187
237
|
if @proxy_protocol && first_read
|
@@ -189,10 +239,10 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
189
239
|
pp_info = line.split(/\s/)
|
190
240
|
# PROXY proto clientip proxyip clientport proxyport
|
191
241
|
if pp_info[0] != "PROXY"
|
192
|
-
@logger.error("invalid proxy protocol header label", :
|
242
|
+
@logger.error("invalid proxy protocol header label", header: line)
|
193
243
|
raise IOError
|
194
244
|
else
|
195
|
-
|
245
|
+
@logger.debug("proxy protocol detected", header: line)
|
196
246
|
ip = pp_info[2]
|
197
247
|
port = pp_info[3]
|
198
248
|
next
|
@@ -206,20 +256,19 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
206
256
|
rescue Errno::EBADF
|
207
257
|
# swallow connection closed exceptions to avoid bubling up the tcp_listener & server
|
208
258
|
logger.info("connection closed", :client => "#{ip}:#{port}")
|
209
|
-
rescue IOError =>
|
259
|
+
rescue IOError => e
|
210
260
|
# swallow connection closed exceptions to avoid bubling up the tcp_listener & server
|
211
|
-
raise unless socket.closed? &&
|
212
|
-
logger.info("connection error:
|
261
|
+
raise(e) unless socket.closed? && e.message.to_s.include?("closed")
|
262
|
+
logger.info("connection error:", :exception => e.class, :message => e.message)
|
213
263
|
ensure
|
214
264
|
@tcp_sockets.delete(socket)
|
215
265
|
socket.close rescue log_and_squash(:close_tcp_receiver_socket)
|
216
266
|
end
|
217
267
|
|
218
|
-
|
219
|
-
def decode(host, output_queue, data)
|
268
|
+
def decode(ip, output_queue, data)
|
220
269
|
@codec.decode(data) do |event|
|
221
270
|
decorate(event)
|
222
|
-
event.set(
|
271
|
+
event.set(@host_key, ip)
|
223
272
|
syslog_relay(event)
|
224
273
|
output_queue << event
|
225
274
|
metric.increment(:events)
|
@@ -230,13 +279,13 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
230
279
|
@metric_errors.increment(:decoding)
|
231
280
|
end
|
232
281
|
|
233
|
-
|
282
|
+
# @see LogStash::Plugin#close
|
234
283
|
def stop
|
235
284
|
close_udp
|
236
285
|
close_tcp
|
237
286
|
end
|
287
|
+
public :stop
|
238
288
|
|
239
|
-
private
|
240
289
|
def close_udp
|
241
290
|
if @udp
|
242
291
|
@udp.close_read rescue log_and_squash(:close_udp_read)
|
@@ -245,8 +294,6 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
245
294
|
@udp = nil
|
246
295
|
end
|
247
296
|
|
248
|
-
private
|
249
|
-
|
250
297
|
# Helper for inline rescues, which logs the exception at "DEBUG" level and returns nil.
|
251
298
|
#
|
252
299
|
# Instead of:
|
@@ -276,46 +323,54 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
276
323
|
# If the message cannot be recognized (see @grok_filter), we'll
|
277
324
|
# treat it like the whole event["message"] is correct and try to fill
|
278
325
|
# the missing pieces (host, priority, etc)
|
279
|
-
public
|
280
326
|
def syslog_relay(event)
|
281
|
-
@
|
327
|
+
@grok_filter_exec.(event)
|
282
328
|
|
283
329
|
if event.get("tags").nil? || !event.get("tags").include?(@grok_filter.tag_on_failure)
|
284
330
|
# Per RFC3164, priority = (facility * 8) + severity
|
285
331
|
# = (facility << 3) & (severity)
|
286
|
-
priority = event.get(
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
event.set("facility", facility)
|
292
|
-
|
293
|
-
event.set("timestamp", event.get("timestamp8601")) if event.include?("timestamp8601")
|
294
|
-
@date_filter.filter(event)
|
332
|
+
priority = event.get(@priority_key).to_i rescue 13
|
333
|
+
set_priority event, priority
|
334
|
+
|
335
|
+
@date_filter_exec.(event)
|
336
|
+
|
295
337
|
else
|
296
|
-
@logger.debug? && @logger.debug("
|
338
|
+
@logger.debug? && @logger.debug("un-matched syslog message", :message => event.get("message"))
|
297
339
|
|
298
340
|
# RFC3164 says unknown messages get pri=13
|
299
|
-
|
300
|
-
event.set("priority", 13)
|
301
|
-
event.set("severity", 5) # 13 & 7 == 5
|
302
|
-
event.set("facility", 1) # 13 >> 3 == 1
|
341
|
+
set_priority event, 13
|
303
342
|
metric.increment(:unknown_messages)
|
304
343
|
end
|
305
344
|
|
306
|
-
# Apply severity and facility metadata if
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
345
|
+
# Apply severity and facility metadata if use_labels => true
|
346
|
+
set_labels(event) if @use_labels
|
347
|
+
end # def syslog_relay
|
348
|
+
public :syslog_relay
|
349
|
+
|
350
|
+
def set_priority(event, priority)
|
351
|
+
severity = priority & 7 # 7 is 111 (3 bits)
|
352
|
+
facility = priority >> 3
|
353
|
+
event.set(@priority_key, priority)
|
354
|
+
event.set(@severity_key, severity)
|
355
|
+
event.set(@facility_key, facility)
|
356
|
+
end
|
311
357
|
|
312
|
-
|
313
|
-
|
314
|
-
|
358
|
+
def set_labels(event)
|
359
|
+
facility_number = event.get(@facility_key)
|
360
|
+
severity_number = event.get(@severity_key)
|
315
361
|
|
316
|
-
|
317
|
-
|
318
|
-
|
362
|
+
facility_label = @facility_labels[facility_number]
|
363
|
+
event.set(@facility_label_key, facility_label) if facility_label
|
364
|
+
|
365
|
+
severity_label = @severity_labels[severity_number]
|
366
|
+
event.set(@severity_label_key, severity_label) if severity_label
|
367
|
+
end
|
368
|
+
|
369
|
+
def set_service_fields(event)
|
370
|
+
service_type = @service_type
|
371
|
+
if service_type && !service_type.empty?
|
372
|
+
event.set('[service][type]', service_type) unless event.include?('[service][type]')
|
319
373
|
end
|
320
|
-
end
|
374
|
+
end
|
375
|
+
|
321
376
|
end # class LogStash::Inputs::Syslog
|
@@ -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.5.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,12 +21,13 @@ 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
25
|
|
25
26
|
s.add_runtime_dependency 'concurrent-ruby'
|
26
27
|
s.add_runtime_dependency 'stud', '>= 0.0.22', '< 0.1.0'
|
27
28
|
|
28
29
|
s.add_runtime_dependency 'logstash-codec-plain'
|
29
|
-
s.add_runtime_dependency 'logstash-filter-grok'
|
30
|
+
s.add_runtime_dependency 'logstash-filter-grok', '>= 4.4.0'
|
30
31
|
s.add_runtime_dependency 'logstash-filter-date'
|
31
32
|
|
32
33
|
s.add_development_dependency 'logstash-devutils'
|
data/spec/inputs/syslog_spec.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
require "logstash/devutils/rspec/spec_helper"
|
3
3
|
require "logstash/devutils/rspec/shared_examples"
|
4
4
|
|
5
|
+
require 'logstash/plugin_mixins/ecs_compatibility_support/spec_helper'
|
6
|
+
|
5
7
|
# running the grok code outside a logstash package means
|
6
8
|
# LOGSTASH_HOME will not be defined, so let's set it here
|
7
9
|
# before requiring the grok filter
|
@@ -32,7 +34,7 @@ describe LogStash::Inputs::Syslog do
|
|
32
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]"
|
33
35
|
|
34
36
|
it "should properly handle priority, severity and facilities" do
|
35
|
-
|
37
|
+
skip_if_stack_known_issue
|
36
38
|
port = 5511
|
37
39
|
event_count = 10
|
38
40
|
conf = <<-CONFIG
|
@@ -63,7 +65,7 @@ describe LogStash::Inputs::Syslog do
|
|
63
65
|
end
|
64
66
|
|
65
67
|
it "should properly PROXY protocol v1" do
|
66
|
-
|
68
|
+
skip_if_stack_known_issue
|
67
69
|
port = 5511
|
68
70
|
event_count = 10
|
69
71
|
conf = <<-CONFIG
|
@@ -97,101 +99,190 @@ describe LogStash::Inputs::Syslog do
|
|
97
99
|
end
|
98
100
|
end
|
99
101
|
|
100
|
-
|
101
|
-
|
102
|
-
port = 5511
|
103
|
-
event_count = 10
|
104
|
-
conf = <<-CONFIG
|
105
|
-
input {
|
106
|
-
syslog {
|
107
|
-
type => "blah"
|
108
|
-
port => #{port}
|
109
|
-
}
|
110
|
-
}
|
111
|
-
CONFIG
|
102
|
+
context 'tag', :ecs_compatibility_support do
|
103
|
+
ecs_compatibility_matrix(:disabled, :v1) do
|
112
104
|
|
113
|
-
|
114
|
-
|
115
|
-
event_count.times do |i|
|
116
|
-
socket.puts("message which causes the a grok parse failure")
|
105
|
+
before(:each) do
|
106
|
+
allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
|
117
107
|
end
|
118
|
-
socket.close
|
119
108
|
|
120
|
-
|
121
|
-
|
109
|
+
it "should add unique tag when grok parsing fails with live syslog input" do
|
110
|
+
skip_if_stack_known_issue
|
111
|
+
port = 5511
|
112
|
+
event_count = 10
|
113
|
+
conf = <<-CONFIG
|
114
|
+
input {
|
115
|
+
syslog {
|
116
|
+
type => "blah"
|
117
|
+
port => #{port}
|
118
|
+
}
|
119
|
+
}
|
120
|
+
CONFIG
|
121
|
+
|
122
|
+
events = input(conf) do |pipeline, queue|
|
123
|
+
socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
|
124
|
+
event_count.times do |i|
|
125
|
+
socket.puts("message which causes the a grok parse failure")
|
126
|
+
end
|
127
|
+
socket.close
|
128
|
+
|
129
|
+
event_count.times.collect { queue.pop }
|
130
|
+
end
|
131
|
+
|
132
|
+
expect( events.length ).to eql event_count
|
133
|
+
event_count.times do |i|
|
134
|
+
expect( events[i].get("tags") ).to eql ["_grokparsefailure_sysloginput"]
|
135
|
+
end
|
136
|
+
end
|
122
137
|
|
123
|
-
expect( events.length ).to eql event_count
|
124
|
-
event_count.times do |i|
|
125
|
-
expect( events[i].get("tags") ).to eql ["_grokparsefailure_sysloginput"]
|
126
138
|
end
|
127
139
|
end
|
128
140
|
|
129
|
-
|
130
|
-
|
131
|
-
event_count = 10
|
141
|
+
context 'timestamp', :ecs_compatibility_support do
|
142
|
+
ecs_compatibility_matrix(:disabled, :v1) do
|
132
143
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
type => "blah"
|
137
|
-
port => #{port}
|
138
|
-
locale => "en"
|
139
|
-
timezone => "UTC"
|
140
|
-
}
|
141
|
-
}
|
142
|
-
CONFIG
|
144
|
+
before(:each) do
|
145
|
+
allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
|
146
|
+
end
|
143
147
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
+
it "should properly handle locale and timezone" do
|
149
|
+
port = 5511
|
150
|
+
event_count = 10
|
151
|
+
|
152
|
+
conf = <<-CONFIG
|
153
|
+
input {
|
154
|
+
syslog {
|
155
|
+
type => "blah"
|
156
|
+
port => #{port}
|
157
|
+
locale => "en"
|
158
|
+
timezone => "UTC"
|
159
|
+
}
|
160
|
+
}
|
161
|
+
CONFIG
|
162
|
+
|
163
|
+
events = input(conf) do |pipeline, queue|
|
164
|
+
socket = Stud.try(5.times) { TCPSocket.new("127.0.0.1", port) }
|
165
|
+
event_count.times do |i|
|
166
|
+
socket.puts(SYSLOG_LINE)
|
167
|
+
end
|
168
|
+
socket.close
|
169
|
+
|
170
|
+
event_count.times.collect { queue.pop }
|
171
|
+
end
|
172
|
+
|
173
|
+
expect( events.length ).to eql event_count
|
174
|
+
events.each do |event|
|
175
|
+
expect( event.get("@timestamp").to_iso8601 ).to eql "#{Time.now.year}-10-26T15:19:25.000Z"
|
176
|
+
end
|
148
177
|
end
|
149
|
-
socket.close
|
150
178
|
|
151
|
-
|
152
|
-
|
179
|
+
it "should properly handle no locale and no timezone" do
|
180
|
+
port = 5511
|
181
|
+
|
182
|
+
conf = <<-CONFIG
|
183
|
+
input {
|
184
|
+
syslog {
|
185
|
+
type => "blah"
|
186
|
+
port => #{port}
|
187
|
+
}
|
188
|
+
}
|
189
|
+
CONFIG
|
190
|
+
|
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
|
195
|
+
|
196
|
+
queue.pop
|
197
|
+
end
|
198
|
+
|
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/
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should support non UTC timezone" do
|
204
|
+
input = LogStash::Inputs::Syslog.new({"timezone" => "-05:00"})
|
205
|
+
input.register
|
206
|
+
|
207
|
+
# event which is not syslog should have a new tag
|
208
|
+
|
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)
|
211
|
+
|
212
|
+
expect( syslog_event.get("@timestamp").to_iso8601 ).to eql "#{Time.now.year}-10-26T20:19:25.000Z"
|
213
|
+
|
214
|
+
input.close
|
215
|
+
end
|
153
216
|
|
154
|
-
expect( events.length ).to eql event_count
|
155
|
-
events.each do |event|
|
156
|
-
expect( event.get("@timestamp").to_iso8601 ).to eql "#{Time.now.year}-10-26T15:19:25.000Z"
|
157
217
|
end
|
158
218
|
end
|
159
219
|
|
160
|
-
|
161
|
-
port = 5511
|
220
|
+
context 'ECS behavior', :ecs_compatibility_support do
|
162
221
|
|
163
|
-
|
164
|
-
input {
|
165
|
-
syslog {
|
166
|
-
type => "blah"
|
167
|
-
port => #{port}
|
168
|
-
}
|
169
|
-
}
|
170
|
-
CONFIG
|
222
|
+
ecs_compatibility_matrix(:v1) do
|
171
223
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
socket.close
|
224
|
+
before(:each) do
|
225
|
+
allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
|
226
|
+
end
|
176
227
|
|
177
|
-
|
178
|
-
|
228
|
+
let(:event) do
|
229
|
+
LogStash::Event.new("message" => "<164>Oct 26 15:19:25 1.2.3.4 a sample message")
|
230
|
+
end
|
179
231
|
|
180
|
-
|
181
|
-
expect( event.get("@timestamp").to_iso8601 ).to match /#{Time.now.year}-10-26T\d\d:19:25.000Z/
|
182
|
-
end
|
232
|
+
subject { LogStash::Inputs::Syslog.new }
|
183
233
|
|
184
|
-
|
185
|
-
|
186
|
-
input.register
|
234
|
+
before { subject.register }
|
235
|
+
after { subject.close }
|
187
236
|
|
188
|
-
|
237
|
+
it "should not have a timestamp field" do
|
238
|
+
subject.syslog_relay(event)
|
189
239
|
|
190
|
-
|
191
|
-
|
192
|
-
expect( syslog_event.get("@timestamp").to_iso8601 ).to eql "#{Time.now.year}-10-26T20:19:25.000Z"
|
240
|
+
expect( event.to_hash.keys ).to_not include 'timestamp'
|
241
|
+
end
|
193
242
|
|
194
|
-
|
243
|
+
it "overwrites message" do
|
244
|
+
subject.syslog_relay(event)
|
245
|
+
|
246
|
+
expect( event.get('message') ).to eql 'a sample message'
|
247
|
+
end
|
248
|
+
|
249
|
+
it "keep original log message" do
|
250
|
+
subject.syslog_relay(event)
|
251
|
+
|
252
|
+
expect( event.get('[event][original]') ).to eql '<164>Oct 26 15:19:25 1.2.3.4 a sample message'
|
253
|
+
end
|
254
|
+
|
255
|
+
it "sets syslog priority and severity" do
|
256
|
+
subject.syslog_relay(event)
|
257
|
+
|
258
|
+
expect( event.get('log') ).to include 'syslog' => hash_including('priority' => 164)
|
259
|
+
expect( event.get('log') ).to include 'syslog' => hash_including('severity' => { 'code' => 4, 'name' => 'Warning' })
|
260
|
+
end
|
261
|
+
|
262
|
+
it "sets service type" do
|
263
|
+
subject.syslog_relay(event)
|
264
|
+
|
265
|
+
expect( event.get('service') ).to include 'type' => 'system'
|
266
|
+
end
|
267
|
+
|
268
|
+
let(:queue) { Queue.new }
|
269
|
+
|
270
|
+
let(:socket) do
|
271
|
+
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"
|
273
|
+
allow( server ).to receive(:close)
|
274
|
+
server
|
275
|
+
end
|
276
|
+
|
277
|
+
it "sets host IP" do
|
278
|
+
expect( socket ).to receive(:peeraddr).and_return(["AF_INET", 514, "192.168.0.10", "192.168.0.10"])
|
279
|
+
subject.send :tcp_receiver, queue, socket
|
280
|
+
|
281
|
+
expect( queue.size ).to eql 1
|
282
|
+
event = queue.pop
|
283
|
+
expect( event.get('host') ).to eql 'hostname' => 'precision', 'ip' => '192.168.0.10'
|
284
|
+
end
|
285
|
+
end
|
195
286
|
end
|
196
287
|
|
197
288
|
it "should add unique tag when grok parsing fails" do
|
@@ -292,4 +383,10 @@ describe LogStash::Inputs::Syslog do
|
|
292
383
|
expect( event.get("timestamp") ).to eql timestamp
|
293
384
|
end
|
294
385
|
end
|
386
|
+
|
387
|
+
private
|
388
|
+
|
389
|
+
def skip_if_stack_known_issue
|
390
|
+
skip 'elastic/logstash#11196 known LS 7.5 issue' if ENV['ELASTIC_STACK_VERSION'] && JRUBY_VERSION.eql?('9.2.8.0')
|
391
|
+
end
|
295
392
|
end
|
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.5.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
|
+
date: 2021-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -30,6 +30,20 @@ dependencies:
|
|
30
30
|
- - "<="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2.99'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - "~>"
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '1.1'
|
39
|
+
name: logstash-mixin-ecs_compatibility_support
|
40
|
+
prerelease: false
|
41
|
+
type: :runtime
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.1'
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
48
|
requirement: !ruby/object:Gem::Requirement
|
35
49
|
requirements:
|
@@ -83,7 +97,7 @@ dependencies:
|
|
83
97
|
requirements:
|
84
98
|
- - ">="
|
85
99
|
- !ruby/object:Gem::Version
|
86
|
-
version:
|
100
|
+
version: 4.4.0
|
87
101
|
name: logstash-filter-grok
|
88
102
|
prerelease: false
|
89
103
|
type: :runtime
|
@@ -91,7 +105,7 @@ dependencies:
|
|
91
105
|
requirements:
|
92
106
|
- - ">="
|
93
107
|
- !ruby/object:Gem::Version
|
94
|
-
version:
|
108
|
+
version: 4.4.0
|
95
109
|
- !ruby/object:Gem::Dependency
|
96
110
|
requirement: !ruby/object:Gem::Requirement
|
97
111
|
requirements:
|