Skip to content

Commit 27bacbe

Browse files
authored
Added support for RFC5424 structured data (#67)
* Added support for RFC5424 structured data Signed-off-by: Tero Saarni <[email protected]>
1 parent 906c1a8 commit 27bacbe

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## 3.0.6
22
- Change codec instance comparison [#69](https://github.com/logstash-plugins/logstash-output-syslog/pull/69)
3+
- Added support for RFC5424 structured data [#67](https://github.com/logstash-plugins/logstash-output-syslog/pull/67)
34

45
## 3.0.5
56
- Docs: Set the default_codec doc attribute.
@@ -40,4 +41,3 @@
4041
- Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
4142
instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
4243
- Dependency on logstash-core update to 2.0
43-

docs/index.asciidoc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
5959
| <<plugins-{type}s-{plugin}-ssl_key_passphrase>> |<<password,password>>|No
6060
| <<plugins-{type}s-{plugin}-ssl_verify>> |<<boolean,boolean>>|No
6161
| <<plugins-{type}s-{plugin}-use_labels>> |<<boolean,boolean>>|No
62+
| <<plugins-{type}s-{plugin}-structured_data>> |<<string,string>>|No
6263
|=======================================================================
6364

6465
Also see <<plugins-{type}s-{plugin}-common-options>> for a list of options supported by all
@@ -234,9 +235,21 @@ Verify the identity of the other end of the SSL connection against the CA.
234235
use label parsing for severity and facility levels
235236
use priority field if set to false
236237

238+
[id="plugins-{type}s-{plugin}-structured_data"]
239+
===== `structured_data`
237240

241+
* Value type is <<string,string>>
242+
* There is no default value for this setting.
243+
244+
RFC5424 structured data is a string of one or more structured data elements, including brackets.
245+
The elements need to be formatted according to link:https://datatracker.ietf.org/doc/html/rfc5424#section-6.3[RFC5424 section 6.3], for example:
246+
247+
["source",subs="attributes"]
248+
`[exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"][examplePriority@32473 class="high"]`
249+
250+
The new value can include `%{foo}` strings to help you build a new value from other parts of the event.
238251

239252
[id="plugins-{type}s-{plugin}-common-options"]
240253
include::{include_path}/{type}.asciidoc[]
241254

242-
:default_codec!:
255+
:default_codec!:

lib/logstash/outputs/syslog.rb

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,16 @@ class LogStash::Outputs::Syslog < LogStash::Outputs::Base
125125
# syslog message format: you can choose between rfc3164 or rfc5424
126126
config :rfc, :validate => ["rfc3164", "rfc5424"], :default => "rfc3164"
127127

128+
# RFC5424 structured data.
129+
config :structured_data, :validate => :string, :default => ""
130+
128131
def register
129132
@client_socket = nil
130133

131134
if ssl?
132135
@ssl_context = setup_ssl
133136
end
134-
137+
135138
if @codec.class.name == "LogStash::Codecs::Plain"
136139
if @codec.config["format"].nil?
137140
@codec = LogStash::Codecs::Plain.new({"format" => @message})
@@ -141,6 +144,11 @@ def register
141144

142145
# use instance variable to avoid string comparison for each event
143146
@is_rfc3164 = (@rfc == "rfc3164")
147+
148+
if @is_rfc3164 && !@structured_data.empty?
149+
raise LogStash::ConfigurationError, "Structured data is not supported for RFC3164"
150+
end
151+
144152
end
145153

146154
def receive(event)
@@ -169,8 +177,9 @@ def publish(event, payload)
169177
syslog_msg = "<#{priority.to_s}>#{timestamp} #{sourcehost} #{appname}[#{procid}]: #{message}"
170178
else
171179
msgid = event.sprintf(@msgid)
180+
sd = @structured_data.empty? ? "-" : event.sprintf(@structured_data)
172181
timestamp = event.sprintf("%{+YYYY-MM-dd'T'HH:mm:ss.SSSZZ}")
173-
syslog_msg = "<#{priority.to_s}>1 #{timestamp} #{sourcehost} #{appname} #{procid} #{msgid} - #{message}"
182+
syslog_msg = "<#{priority.to_s}>1 #{timestamp} #{sourcehost} #{appname} #{procid} #{msgid} #{sd} #{message}"
174183
end
175184

176185
begin

spec/outputs/syslog_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,28 @@
139139

140140
it_behaves_like "syslog output"
141141
end
142+
143+
context "structured data is not supported for RFC3164" do
144+
let(:options) { {"host" => "foo", "port" => "123", "rfc" => "rfc3164", "structured_data" => "[foo@12345]" } }
145+
146+
it "should raise exception" do
147+
expect { subject.register }.to raise_error(LogStash::ConfigurationError)
148+
end
149+
end
150+
151+
context "send with both structured data and message" do
152+
let(:options) { {"host" => "foo", "port" => "123", "rfc" => "rfc5424", "structured_data" => '[exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"][examplePriority@32473 class="high"]' } }
153+
let(:output) { /^<13>1 #{RFC3339_DATE_TIME_REGEX} baz LOGSTASH - - \[exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"\]\[examplePriority@32473 class="high"\] bar\n/m }
154+
155+
it_behaves_like "syslog output"
156+
end
157+
158+
context "set structured data elements from event" do
159+
let(:event) { LogStash::Event.new({"message" => "bar", "host" => "baz", "pod" => "mypod" }) }
160+
let(:options) { {"host" => "foo", "port" => "123", "rfc" => "rfc5424", "structured_data" => '[exampleSDID@32473 pod="%{pod}"]' } }
161+
let(:output) { /^<13>1 #{RFC3339_DATE_TIME_REGEX} baz LOGSTASH - - \[exampleSDID@32473 pod="mypod"\] bar\n/m }
162+
163+
it_behaves_like "syslog output"
164+
end
165+
142166
end

0 commit comments

Comments
 (0)