logstash-output-syslog 2.1.0 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/logstash/outputs/syslog.rb +113 -16
- data/logstash-output-syslog.gemspec +3 -2
- data/spec/outputs/syslog_spec.rb +77 -0
- metadata +22 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aee984517a11e5ef3e6940d6a34a4ee6cac6c9fc
|
4
|
+
data.tar.gz: 81de265a5c4f28c56273e9c837e5383a906d91d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eae8c4f8b72bd7ec9891d430fea8573f1b39f80052770cbd8679f8ade14cac266f3ad8ae4a5a7f73c2a8eded295873be893981408a1c270ec7a6a374c7a4208d
|
7
|
+
data.tar.gz: f9df3603f5f561a86f7078998dd4bf075116ff014ed92f1db3dcbe72d43c2ad760763279b08caef440185157fecafa65341c983057b8542b694a6eb1fc9bda4d
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
require "logstash/outputs/base"
|
3
3
|
require "logstash/namespace"
|
4
4
|
require "date"
|
5
|
+
require "logstash/codecs/plain"
|
5
6
|
|
6
7
|
|
7
8
|
# Send events to a syslog server.
|
@@ -28,12 +29,10 @@ class LogStash::Outputs::Syslog < LogStash::Outputs::Base
|
|
28
29
|
"network news",
|
29
30
|
"uucp",
|
30
31
|
"clock",
|
31
|
-
"security/authorization",
|
32
32
|
"ftp",
|
33
33
|
"ntp",
|
34
34
|
"log audit",
|
35
35
|
"log alert",
|
36
|
-
"clock",
|
37
36
|
"local0",
|
38
37
|
"local1",
|
39
38
|
"local2",
|
@@ -64,31 +63,66 @@ class LogStash::Outputs::Syslog < LogStash::Outputs::Base
|
|
64
63
|
# when connection fails, retry interval in sec.
|
65
64
|
config :reconnect_interval, :validate => :number, :default => 1
|
66
65
|
|
67
|
-
# syslog server protocol. you can choose between udp and tcp
|
68
|
-
config :protocol, :validate => ["tcp", "udp"], :default => "udp"
|
66
|
+
# syslog server protocol. you can choose between udp, tcp and ssl/tls over tcp
|
67
|
+
config :protocol, :validate => ["tcp", "udp", "ssl-tcp"], :default => "udp"
|
68
|
+
|
69
|
+
# Verify the identity of the other end of the SSL connection against the CA.
|
70
|
+
config :ssl_verify, :validate => :boolean, :default => false
|
71
|
+
|
72
|
+
# The SSL CA certificate, chainfile or CA path. The system CA path is automatically included.
|
73
|
+
config :ssl_cacert, :validate => :path
|
74
|
+
|
75
|
+
# SSL certificate path
|
76
|
+
config :ssl_cert, :validate => :path
|
77
|
+
|
78
|
+
# SSL key path
|
79
|
+
config :ssl_key, :validate => :path
|
80
|
+
|
81
|
+
# SSL key passphrase
|
82
|
+
config :ssl_key_passphrase, :validate => :password, :default => nil
|
83
|
+
|
84
|
+
# use label parsing for severity and facility levels
|
85
|
+
# use priority field if set to false
|
86
|
+
config :use_labels, :validate => :boolean, :default => true
|
87
|
+
|
88
|
+
# syslog priority
|
89
|
+
# The new value can include `%{foo}` strings
|
90
|
+
# to help you build a new value from other parts of the event.
|
91
|
+
config :priority, :validate => :string, :default => "%{syslog_pri}"
|
69
92
|
|
70
93
|
# facility label for syslog message
|
71
|
-
|
94
|
+
# default fallback to user-level as in rfc3164
|
95
|
+
# The new value can include `%{foo}` strings
|
96
|
+
# to help you build a new value from other parts of the event.
|
97
|
+
config :facility, :validate => :string, :default => "user-level"
|
72
98
|
|
73
99
|
# severity label for syslog message
|
74
|
-
|
100
|
+
# default fallback to notice as in rfc3164
|
101
|
+
# The new value can include `%{foo}` strings
|
102
|
+
# to help you build a new value from other parts of the event.
|
103
|
+
config :severity, :validate => :string, :default => "notice"
|
75
104
|
|
76
|
-
# source host for syslog message
|
105
|
+
# source host for syslog message. The new value can include `%{foo}` strings
|
106
|
+
# to help you build a new value from other parts of the event.
|
77
107
|
config :sourcehost, :validate => :string, :default => "%{host}"
|
78
108
|
|
79
109
|
# timestamp for syslog message
|
80
110
|
config :timestamp, :validate => :string, :default => "%{@timestamp}", :deprecated => "This setting is no longer necessary. The RFC setting will determine what time format is used."
|
81
111
|
|
82
|
-
# application name for syslog message
|
112
|
+
# application name for syslog message. The new value can include `%{foo}` strings
|
113
|
+
# to help you build a new value from other parts of the event.
|
83
114
|
config :appname, :validate => :string, :default => "LOGSTASH"
|
84
115
|
|
85
|
-
# process id for syslog message
|
116
|
+
# process id for syslog message. The new value can include `%{foo}` strings
|
117
|
+
# to help you build a new value from other parts of the event.
|
86
118
|
config :procid, :validate => :string, :default => "-"
|
87
119
|
|
88
|
-
# message text to log
|
120
|
+
# message text to log. The new value can include `%{foo}` strings
|
121
|
+
# to help you build a new value from other parts of the event.
|
89
122
|
config :message, :validate => :string, :default => "%{message}"
|
90
123
|
|
91
|
-
# message id for syslog message
|
124
|
+
# message id for syslog message. The new value can include `%{foo}` strings
|
125
|
+
# to help you build a new value from other parts of the event.
|
92
126
|
config :msgid, :validate => :string, :default => "-"
|
93
127
|
|
94
128
|
# syslog message format: you can choose between rfc3164 or rfc5424
|
@@ -97,32 +131,59 @@ class LogStash::Outputs::Syslog < LogStash::Outputs::Base
|
|
97
131
|
def register
|
98
132
|
@client_socket = nil
|
99
133
|
|
100
|
-
|
101
|
-
|
102
|
-
|
134
|
+
if ssl?
|
135
|
+
@ssl_context = setup_ssl
|
136
|
+
end
|
137
|
+
|
138
|
+
if @codec.instance_of? LogStash::Codecs::Plain
|
139
|
+
if @codec.config["format"].nil?
|
140
|
+
@codec = LogStash::Codecs::Plain.new({"format" => @message})
|
141
|
+
end
|
142
|
+
end
|
143
|
+
@codec.on_event(&method(:publish))
|
103
144
|
|
104
145
|
# use instance variable to avoid string comparison for each event
|
105
146
|
@is_rfc3164 = (@rfc == "rfc3164")
|
106
147
|
end
|
107
148
|
|
108
149
|
def receive(event)
|
150
|
+
@codec.encode(event)
|
151
|
+
end
|
152
|
+
|
153
|
+
def publish(event, payload)
|
109
154
|
appname = event.sprintf(@appname)
|
110
155
|
procid = event.sprintf(@procid)
|
111
156
|
sourcehost = event.sprintf(@sourcehost)
|
112
157
|
|
158
|
+
message = payload.to_s.rstrip.gsub(/[\r][\n]/, "\n").gsub(/[\n]/, '\n')
|
159
|
+
|
160
|
+
# fallback to pri 13 (facility 1, severity 5)
|
161
|
+
if @use_labels
|
162
|
+
facility_code = (FACILITY_LABELS.index(event.sprintf(@facility)) || 1)
|
163
|
+
severity_code = (SEVERITY_LABELS.index(event.sprintf(@severity)) || 5)
|
164
|
+
priority = (facility_code * 8) + severity_code
|
165
|
+
else
|
166
|
+
priority = Integer(event.sprintf(@priority)) rescue 13
|
167
|
+
priority = 13 if (priority < 0 || priority > 191)
|
168
|
+
end
|
169
|
+
|
113
170
|
if @is_rfc3164
|
114
171
|
timestamp = event.sprintf("%{+MMM dd HH:mm:ss}")
|
115
|
-
syslog_msg = "<#{
|
172
|
+
syslog_msg = "<#{priority.to_s}>#{timestamp} #{sourcehost} #{appname}[#{procid}]: #{message}"
|
116
173
|
else
|
117
174
|
msgid = event.sprintf(@msgid)
|
118
175
|
timestamp = event.sprintf("%{+YYYY-MM-dd'T'HH:mm:ss.SSSZZ}")
|
119
|
-
syslog_msg = "<#{
|
176
|
+
syslog_msg = "<#{priority.to_s}>1 #{timestamp} #{sourcehost} #{appname} #{procid} #{msgid} - #{message}"
|
120
177
|
end
|
121
178
|
|
122
179
|
begin
|
123
180
|
@client_socket ||= connect
|
124
181
|
@client_socket.write(syslog_msg + "\n")
|
125
182
|
rescue => e
|
183
|
+
# We don't expect udp connections to fail because they are stateless, but ...
|
184
|
+
# udp connections may fail/raise an exception if used with localhost/127.0.0.1
|
185
|
+
return if udp?
|
186
|
+
|
126
187
|
@logger.warn("syslog " + @protocol + " output exception: closing, reconnecting and resending event", :host => @host, :port => @port, :exception => e, :backtrace => e.backtrace, :event => event)
|
127
188
|
@client_socket.close rescue nil
|
128
189
|
@client_socket = nil
|
@@ -138,6 +199,10 @@ class LogStash::Outputs::Syslog < LogStash::Outputs::Base
|
|
138
199
|
@protocol == "udp"
|
139
200
|
end
|
140
201
|
|
202
|
+
def ssl?
|
203
|
+
@protocol == "ssl-tcp"
|
204
|
+
end
|
205
|
+
|
141
206
|
def connect
|
142
207
|
socket = nil
|
143
208
|
if udp?
|
@@ -145,7 +210,39 @@ class LogStash::Outputs::Syslog < LogStash::Outputs::Base
|
|
145
210
|
socket.connect(@host, @port)
|
146
211
|
else
|
147
212
|
socket = TCPSocket.new(@host, @port)
|
213
|
+
if ssl?
|
214
|
+
socket = OpenSSL::SSL::SSLSocket.new(socket, @ssl_context)
|
215
|
+
begin
|
216
|
+
socket.connect
|
217
|
+
rescue OpenSSL::SSL::SSLError => ssle
|
218
|
+
@logger.error("SSL Error", :exception => ssle,
|
219
|
+
:backtrace => ssle.backtrace)
|
220
|
+
# NOTE(mrichar1): Hack to prevent hammering peer
|
221
|
+
sleep(5)
|
222
|
+
raise
|
223
|
+
end
|
224
|
+
end
|
148
225
|
end
|
149
226
|
socket
|
150
227
|
end
|
228
|
+
|
229
|
+
def setup_ssl
|
230
|
+
require "openssl"
|
231
|
+
ssl_context = OpenSSL::SSL::SSLContext.new
|
232
|
+
ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(@ssl_cert))
|
233
|
+
ssl_context.key = OpenSSL::PKey::RSA.new(File.read(@ssl_key),@ssl_key_passphrase)
|
234
|
+
if @ssl_verify
|
235
|
+
cert_store = OpenSSL::X509::Store.new
|
236
|
+
# Load the system default certificate path to the store
|
237
|
+
cert_store.set_default_paths
|
238
|
+
if File.directory?(@ssl_cacert)
|
239
|
+
cert_store.add_path(@ssl_cacert)
|
240
|
+
else
|
241
|
+
cert_store.add_file(@ssl_cacert)
|
242
|
+
end
|
243
|
+
ssl_context.cert_store = cert_store
|
244
|
+
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
245
|
+
end
|
246
|
+
ssl_context
|
247
|
+
end
|
151
248
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-output-syslog'
|
4
|
-
s.version = '2.1.
|
4
|
+
s.version = '2.1.1'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Send events to a syslog server."
|
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/plugin install gemname. This gem is not a stand-alone program"
|
@@ -21,8 +21,9 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
# Gem dependencies
|
23
23
|
s.add_runtime_dependency "logstash-core", ">= 2.0.0.beta2", "< 3.0.0"
|
24
|
+
s.add_runtime_dependency 'logstash-codec-plain'
|
24
25
|
|
25
26
|
s.add_development_dependency 'logstash-devutils'
|
26
|
-
s.add_development_dependency 'logstash-codec-
|
27
|
+
s.add_development_dependency 'logstash-codec-json'
|
27
28
|
end
|
28
29
|
|
data/spec/outputs/syslog_spec.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "logstash/devutils/rspec/spec_helper"
|
4
4
|
require "logstash/outputs/syslog"
|
5
|
+
require "logstash/codecs/plain"
|
5
6
|
|
6
7
|
describe LogStash::Outputs::Syslog do
|
7
8
|
|
@@ -47,4 +48,80 @@ describe LogStash::Outputs::Syslog do
|
|
47
48
|
|
48
49
|
it_behaves_like "syslog output"
|
49
50
|
end
|
51
|
+
|
52
|
+
context "sprintf rfc 3164" do
|
53
|
+
let(:event) { LogStash::Event.new({"message" => "bar", "host" => "baz", "facility" => "mail", "severity" => "critical", "appname" => "appname", "procid" => "1000" }) }
|
54
|
+
let(:options) { {"host" => "foo", "port" => "123", "facility" => "%{facility}", "severity" => "%{severity}", "appname" => "%{appname}", "procid" => "%{procid}"} }
|
55
|
+
let(:output) { /^<18>.+baz appname\[1000\]: bar\n/m }
|
56
|
+
|
57
|
+
it_behaves_like "syslog output"
|
58
|
+
end
|
59
|
+
|
60
|
+
context "sprintf rfc 5424" do
|
61
|
+
let(:event) { LogStash::Event.new({"message" => "bar", "host" => "baz", "facility" => "mail", "severity" => "critical", "appname" => "appname", "procid" => "1000", "msgid" => "2000" }) }
|
62
|
+
let(:options) { {"rfc" => "rfc5424", "host" => "foo", "port" => "123", "facility" => "%{facility}", "severity" => "%{severity}", "appname" => "%{appname}", "procid" => "%{procid}", "msgid" => "%{msgid}"} }
|
63
|
+
let(:output) { /^<18>1 .+baz appname 1000 2000 - bar\n/m }
|
64
|
+
|
65
|
+
it_behaves_like "syslog output"
|
66
|
+
end
|
67
|
+
|
68
|
+
context "use_labels == false, default" do
|
69
|
+
let(:event) { LogStash::Event.new({"message" => "bar", "host" => "baz" }) }
|
70
|
+
let(:options) { {"use_labels" => false, "host" => "foo", "port" => "123" } }
|
71
|
+
let(:output) { /^<13>.+baz LOGSTASH\[-\]: bar\n/m }
|
72
|
+
|
73
|
+
it_behaves_like "syslog output"
|
74
|
+
end
|
75
|
+
|
76
|
+
context "use_labels == false, syslog_pri" do
|
77
|
+
let(:event) { LogStash::Event.new({"message" => "bar", "host" => "baz", "syslog_pri" => "18" }) }
|
78
|
+
let(:options) { {"use_labels" => false, "host" => "foo", "port" => "123" } }
|
79
|
+
let(:output) { /^<18>.+baz LOGSTASH\[-\]: bar\n/m }
|
80
|
+
|
81
|
+
it_behaves_like "syslog output"
|
82
|
+
end
|
83
|
+
|
84
|
+
context "use_labels == false, sprintf" do
|
85
|
+
let(:event) { LogStash::Event.new({"message" => "bar", "host" => "baz", "priority" => "18" }) }
|
86
|
+
let(:options) { {"use_labels" => false, "host" => "foo", "port" => "123", "priority" => "%{priority}" } }
|
87
|
+
let(:output) { /^<18>.+baz LOGSTASH\[-\]: bar\n/m }
|
88
|
+
|
89
|
+
it_behaves_like "syslog output"
|
90
|
+
end
|
91
|
+
|
92
|
+
context "use plain codec with format set" do
|
93
|
+
let(:plain) { LogStash::Codecs::Plain.new({"format" => "%{host} %{message}"}) }
|
94
|
+
let(:options) { {"host" => "foo", "port" => "123", "facility" => "kernel", "severity" => "emergency", "codec" => plain} }
|
95
|
+
let(:output) { /^<0>.+baz LOGSTASH\[-\]: baz bar\n/m }
|
96
|
+
|
97
|
+
it_behaves_like "syslog output"
|
98
|
+
end
|
99
|
+
|
100
|
+
context "use codec json" do
|
101
|
+
let(:options) { {"host" => "foo", "port" => "123", "facility" => "kernel", "severity" => "emergency", "codec" => "json" } }
|
102
|
+
let(:output) { /^<0>.+baz LOGSTASH\[-\]: {\"message\":\"bar\",\"host\":\"baz\",\"@version\":\"1\",\"@timestamp\":\"[0-9TZ:.+-]+\"}\n/m }
|
103
|
+
|
104
|
+
it_behaves_like "syslog output"
|
105
|
+
end
|
106
|
+
|
107
|
+
context "escape carriage return, newline and newline to \\n" do
|
108
|
+
let(:options) { {"host" => "foo", "port" => "123", "facility" => "kernel", "severity" => "emergency", "message" => "foo\r\nbar\nbaz" } }
|
109
|
+
let(:output) { /^<0>.+baz LOGSTASH\[-\]: foo\\nbar\\nbaz\n/m }
|
110
|
+
|
111
|
+
it_behaves_like "syslog output"
|
112
|
+
end
|
113
|
+
|
114
|
+
context "tailing newline" do
|
115
|
+
let(:options) { {"host" => "foo", "port" => "123", "facility" => "kernel", "severity" => "emergency", "message" => "%{message}\n" } }
|
116
|
+
let(:output) { /^<0>.+baz LOGSTASH\[-\]: bar\n/m }
|
117
|
+
|
118
|
+
it_behaves_like "syslog output"
|
119
|
+
end
|
120
|
+
|
121
|
+
context "tailing carriage return and newline (windows)" do
|
122
|
+
let(:options) { {"host" => "foo", "port" => "123", "facility" => "kernel", "severity" => "emergency", "message" => "%{message}\n" } }
|
123
|
+
let(:output) { /^<0>.+baz LOGSTASH\[-\]: bar\n/m }
|
124
|
+
|
125
|
+
it_behaves_like "syslog output"
|
126
|
+
end
|
50
127
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-output-syslog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.1
|
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: 2016-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logstash-core
|
@@ -30,6 +30,20 @@ dependencies:
|
|
30
30
|
version: 3.0.0
|
31
31
|
prerelease: false
|
32
32
|
type: :runtime
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: logstash-codec-plain
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
prerelease: false
|
46
|
+
type: :runtime
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
48
|
name: logstash-devutils
|
35
49
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -45,7 +59,7 @@ dependencies:
|
|
45
59
|
prerelease: false
|
46
60
|
type: :development
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
|
-
name: logstash-codec-
|
62
|
+
name: logstash-codec-json
|
49
63
|
version_requirements: !ruby/object:Gem::Requirement
|
50
64
|
requirements:
|
51
65
|
- - '>='
|
@@ -64,15 +78,15 @@ executables: []
|
|
64
78
|
extensions: []
|
65
79
|
extra_rdoc_files: []
|
66
80
|
files:
|
67
|
-
- lib/logstash/outputs/syslog.rb
|
68
|
-
- spec/outputs/syslog_spec.rb
|
69
|
-
- logstash-output-syslog.gemspec
|
70
81
|
- CHANGELOG.md
|
71
|
-
- README.md
|
72
82
|
- CONTRIBUTORS
|
73
83
|
- Gemfile
|
74
84
|
- LICENSE
|
75
85
|
- NOTICE.TXT
|
86
|
+
- README.md
|
87
|
+
- lib/logstash/outputs/syslog.rb
|
88
|
+
- logstash-output-syslog.gemspec
|
89
|
+
- spec/outputs/syslog_spec.rb
|
76
90
|
homepage: http://www.elastic.co/guide/en/logstash/current/index.html
|
77
91
|
licenses:
|
78
92
|
- Apache License (2.0)
|
@@ -95,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
109
|
version: '0'
|
96
110
|
requirements: []
|
97
111
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.
|
112
|
+
rubygems_version: 2.4.8
|
99
113
|
signing_key:
|
100
114
|
specification_version: 4
|
101
115
|
summary: Send events to a syslog server.
|