logstash-output-udp 3.0.6 → 3.1.0
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/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
|