logstash-output-udp 3.0.6 → 3.1.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 +4 -0
- data/docs/index.asciidoc +24 -1
- data/lib/logstash/outputs/udp.rb +46 -6
- data/logstash-output-udp.gemspec +1 -1
- data/spec/outputs/udp_spec.rb +67 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6d89de043149e0924a181b904dfd2d56766fd52c77ffb7ad623c27c3ee18df4
|
4
|
+
data.tar.gz: 94ad42d0d5b5d9c2bda8714318b3ca79899b8889e1db69e1e2a4c71358059f2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ead3de8b14b596c8cac1330ca63737232fb8d8ce5e2564f5aed6cedb54e811662dae7ba2a2a36680ba6aba9d11aa1ce6f14e1e35888076d01907de6976fb5e2d
|
7
|
+
data.tar.gz: 71d2903845ceed02477768fe9eea5ca8c27a0875ba064b96a2d396331c726d1bbaa0aca88d64ed9df77b70a7ab30b0523ceaf67a648436f87449a33ba4b9cf26
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 3.1.0
|
2
|
+
- Fixed plugin crash upon socket write exception [#10](https://github.com/logstash-plugins/logstash-output-udp/pull/10)
|
3
|
+
- Added support for the 'retry_count' and 'retry_backoff_ms' options [#12](https://github.com/logstash-plugins/logstash-output-udp/pull/12)
|
4
|
+
|
1
5
|
## 3.0.6
|
2
6
|
- Docs: Set the default_codec doc attribute.
|
3
7
|
|
data/docs/index.asciidoc
CHANGED
@@ -23,7 +23,14 @@ include::{include_path}/plugin_header.asciidoc[]
|
|
23
23
|
|
24
24
|
Send events over UDP
|
25
25
|
|
26
|
-
Keep in mind that UDP
|
26
|
+
Keep in mind that UDP does not provide delivery or duplicate protection guarantees.
|
27
|
+
Even when this plugin succeeds at writing to the UDP socket, there is no guarantee that
|
28
|
+
the recipient will receive exactly one copy of the event.
|
29
|
+
|
30
|
+
When this plugin fails to write to the UDP socket, by default the event will be dropped
|
31
|
+
and the error message will be logged. The <<plugins-{type}s-{plugin}-retry_count>> option
|
32
|
+
in conjunction with the <<plugins-{type}s-{plugin}-retry_backoff_ms>> option can be used
|
33
|
+
to retry a failed write for a number of times before dropping the event.
|
27
34
|
|
28
35
|
[id="plugins-{type}s-{plugin}-options"]
|
29
36
|
==== Udp Output Configuration Options
|
@@ -35,6 +42,8 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
35
42
|
|Setting |Input type|Required
|
36
43
|
| <<plugins-{type}s-{plugin}-host>> |<<string,string>>|Yes
|
37
44
|
| <<plugins-{type}s-{plugin}-port>> |<<number,number>>|Yes
|
45
|
+
| <<plugins-{type}s-{plugin}-retry_count>> |<<number,number>>|No
|
46
|
+
| <<plugins-{type}s-{plugin}-retry_backoff_ms>> |<<number,number>>|No
|
38
47
|
|=======================================================================
|
39
48
|
|
40
49
|
Also see <<plugins-{type}s-{plugin}-common-options>> for a list of options supported by all
|
@@ -60,7 +69,21 @@ The address to send messages to
|
|
60
69
|
|
61
70
|
The port to send messages on
|
62
71
|
|
72
|
+
[id="plugins-{type}s-{plugin}-retry_count"]
|
73
|
+
===== `retry_count`
|
74
|
+
|
75
|
+
* Value type is <<number,number>>
|
76
|
+
* Default value is `0`
|
77
|
+
|
78
|
+
The number of times to retry a failed UPD socket write
|
79
|
+
|
80
|
+
[id="plugins-{type}s-{plugin}-retry_backoff_ms"]
|
81
|
+
===== `retry_backoff_ms`
|
82
|
+
|
83
|
+
* Value type is <<number,number>>
|
84
|
+
* Default value is `10`
|
63
85
|
|
86
|
+
The amount of time to wait in milliseconds before attempting to retry a failed UPD socket write
|
64
87
|
|
65
88
|
[id="plugins-{type}s-{plugin}-common-options"]
|
66
89
|
include::{include_path}/{type}.asciidoc[]
|
data/lib/logstash/outputs/udp.rb
CHANGED
@@ -5,7 +5,7 @@ require "socket"
|
|
5
5
|
|
6
6
|
# Send events over UDP
|
7
7
|
#
|
8
|
-
# Keep in mind that UDP
|
8
|
+
# Keep in mind that UDP is a lossy protocol
|
9
9
|
class LogStash::Outputs::UDP < LogStash::Outputs::Base
|
10
10
|
config_name "udp"
|
11
11
|
|
@@ -17,18 +17,58 @@ class LogStash::Outputs::UDP < LogStash::Outputs::Base
|
|
17
17
|
# The port to send messages on
|
18
18
|
config :port, :validate => :number, :required => true
|
19
19
|
|
20
|
-
|
20
|
+
# The number of times to retry a failed UPD socket write
|
21
|
+
config :retry_count, :validate => :number, :default => 0
|
22
|
+
|
23
|
+
# The amount of time to wait in milliseconds before attempting to retry a failed UPD socket write
|
24
|
+
config :retry_backoff_ms, :validate => :number, :default => 100
|
25
|
+
|
21
26
|
def register
|
22
27
|
@socket = UDPSocket.new
|
28
|
+
|
23
29
|
@codec.on_event do |event, payload|
|
24
|
-
|
30
|
+
socket_send(payload)
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
28
34
|
def receive(event)
|
29
|
-
|
30
|
-
return if event == LogStash::SHUTDOWN
|
31
35
|
@codec.encode(event)
|
32
36
|
end
|
33
37
|
|
34
|
-
|
38
|
+
private
|
39
|
+
|
40
|
+
def socket_send(payload)
|
41
|
+
send_count = 0
|
42
|
+
begin
|
43
|
+
send_count += 1
|
44
|
+
@socket.send(payload, 0, @host, @port)
|
45
|
+
rescue Errno::EMSGSIZE => e
|
46
|
+
logger.error("Failed to send event, message size of #{payload.size} too long", error_hash(e, payload))
|
47
|
+
rescue => e
|
48
|
+
if @retry_count > 0 && send_count <= @retry_count
|
49
|
+
logger.warn("Failed to send event, retrying:", error_hash(e, payload))
|
50
|
+
sleep(@retry_backoff_ms / 1000.0)
|
51
|
+
retry
|
52
|
+
else
|
53
|
+
logger.error("Failed to send event:", error_hash(e, payload))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
MAX_DEBUG_PAYLOAD = 1000
|
59
|
+
|
60
|
+
def error_hash(error, payload)
|
61
|
+
error_hash = {
|
62
|
+
:error => error.inspect,
|
63
|
+
:backtrace => error.backtrace.first(10)
|
64
|
+
}
|
65
|
+
if logger.debug?
|
66
|
+
error_hash.merge(
|
67
|
+
:event_payload =>
|
68
|
+
payload.length > MAX_DEBUG_PAYLOAD ? "#{payload[0...MAX_DEBUG_PAYLOAD]}...<TRUNCATED>" : payload
|
69
|
+
)
|
70
|
+
else
|
71
|
+
error_hash
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/logstash-output-udp.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-output-udp'
|
4
|
-
s.version = '3.0
|
4
|
+
s.version = '3.1.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Sends events over UDP"
|
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"
|
data/spec/outputs/udp_spec.rb
CHANGED
@@ -3,18 +3,17 @@ require_relative "../spec_helper"
|
|
3
3
|
|
4
4
|
describe LogStash::Outputs::UDP do
|
5
5
|
|
6
|
+
subject { described_class.new(config) }
|
6
7
|
let(:host) { "localhost" }
|
7
8
|
let(:port) { rand(1024..65535) }
|
9
|
+
let(:config) {{ "host" => host, "port" => port}}
|
8
10
|
|
9
11
|
it "should register without errors" do
|
10
|
-
plugin = LogStash::Plugin.lookup("output", "udp").new(
|
12
|
+
plugin = LogStash::Plugin.lookup("output", "udp").new(config)
|
11
13
|
expect { plugin.register }.to_not raise_error
|
12
14
|
end
|
13
15
|
|
14
16
|
describe "#send" do
|
15
|
-
|
16
|
-
subject { LogStash::Outputs::UDP.new({"host" => host, "port" => port}) }
|
17
|
-
|
18
17
|
let(:properties) { { "message" => "This is a message!"} }
|
19
18
|
let(:event) { LogStash::Event.new(properties) }
|
20
19
|
|
@@ -24,7 +23,71 @@ describe LogStash::Outputs::UDP do
|
|
24
23
|
|
25
24
|
it "should receive the generated event" do
|
26
25
|
expect(subject.instance_variable_get("@socket")).to receive(:send).with(kind_of(String), 0, host, port)
|
26
|
+
expect(subject.instance_variable_get("@logger")).not_to receive(:error)
|
27
|
+
subject.receive(event)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "retries" do
|
32
|
+
let(:event) { LogStash::Event.new("message" => "test") }
|
33
|
+
let(:config) {{ "host" => host, "port" => port}}
|
34
|
+
|
35
|
+
before(:each) do
|
36
|
+
subject.register
|
37
|
+
end
|
38
|
+
|
39
|
+
context "not using :retry_count" do
|
40
|
+
it "should not retry upon send exception by default" do
|
41
|
+
allow(subject.instance_variable_get("@socket")).to receive(:send).once.and_raise(IOError)
|
42
|
+
expect(subject.instance_variable_get("@logger")).to receive(:error).once
|
43
|
+
subject.receive(event)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "using :retry_count" do
|
48
|
+
let(:backoff) { 10 }
|
49
|
+
let(:retry_count) { 5 }
|
50
|
+
let(:config) {{ "host" => host, "port" => port, "retry_count" => retry_count, "retry_backoff_ms" => backoff}}
|
51
|
+
|
52
|
+
it "should retry upon send exception" do
|
53
|
+
allow(subject.instance_variable_get("@socket")).to receive(:send).exactly(retry_count + 1).times.and_raise(IOError)
|
54
|
+
expect(subject.instance_variable_get("@logger")).to receive(:warn).exactly(retry_count).times
|
55
|
+
expect(subject.instance_variable_get("@logger")).to receive(:error).once
|
56
|
+
expect(subject).to receive(:sleep).with(backoff / 1000.0).exactly(retry_count).times
|
57
|
+
subject.receive(event)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "large message" do
|
63
|
+
let(:properties) { { "message" => "0" * 65_536 } }
|
64
|
+
let(:event) { LogStash::Event.new(properties) }
|
65
|
+
|
66
|
+
before(:each) do
|
67
|
+
subject.register
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should handle the error and log when an error is received" do
|
71
|
+
expect(subject.instance_variable_get("@logger")).to receive(:error)
|
27
72
|
subject.receive(event)
|
28
73
|
end
|
74
|
+
|
75
|
+
it "should log a truncated payload with debug logging when an error is received and the message is too long" do
|
76
|
+
expect(subject.instance_variable_get("@logger")).to receive(:debug?).and_return(true)
|
77
|
+
expect(subject.instance_variable_get("@logger")).to receive(:error) do |_, hash|
|
78
|
+
expect(hash).to include(:event_payload)
|
79
|
+
expect(hash[:event_payload]).to include("TRUNCATED")
|
80
|
+
end
|
81
|
+
subject.receive(event)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should not log a payload with debug logging when an error is received" do
|
85
|
+
expect(subject.instance_variable_get("@logger")).to receive(:debug?).and_return(false)
|
86
|
+
expect(subject.instance_variable_get("@logger")).to receive(:error) do |_, hash|
|
87
|
+
expect(hash).not_to include(:event_payload)
|
88
|
+
end
|
89
|
+
subject.receive(event)
|
90
|
+
end
|
91
|
+
|
29
92
|
end
|
30
93
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-output-udp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.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: 2019-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
99
|
version: '0'
|
100
100
|
requirements: []
|
101
101
|
rubyforge_project:
|
102
|
-
rubygems_version: 2.6.
|
102
|
+
rubygems_version: 2.6.13
|
103
103
|
signing_key:
|
104
104
|
specification_version: 4
|
105
105
|
summary: Sends events over UDP
|