logstash-output-newrelic 0.9.1 → 1.0.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 +5 -5
- data/CHANGELOG.md +2 -5
- data/CONTRIBUTORS +10 -0
- data/DEVELOPER.md +37 -0
- data/Gemfile +1 -0
- data/LICENSE +196 -17
- data/README.md +60 -74
- data/lib/logstash/outputs/newrelic_internal.rb +126 -0
- data/lib/logstash/outputs/newrelic_internal_version/version.rb +7 -0
- data/logstash-output-newrelic.gemspec +22 -17
- data/spec/outputs/newrelic_internal_spec.rb +284 -0
- metadata +54 -38
- data/.github/CONTRIBUTING.md +0 -65
- data/.github/ISSUE_TEMPLATE.md +0 -9
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -1
- data/.gitignore +0 -2
- data/.travis.yml +0 -11
- data/NOTICE.TXT +0 -5
- data/Rakefile +0 -7
- data/bin/logstash-newrelic +0 -2
- data/bin/logstash-newrelic-debug +0 -2
- data/bin/logstash-newrelic.conf.template +0 -10
- data/lib/logstash/outputs/newrelic.rb +0 -220
- data/spec/outputs/newrelic_spec.rb +0 -66
@@ -0,0 +1,284 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/devutils/rspec/spec_helper"
|
3
|
+
require "logstash/outputs/newrelic_internal"
|
4
|
+
require "logstash/outputs/newrelic_internal_version/version"
|
5
|
+
require "logstash/codecs/plain"
|
6
|
+
require "logstash/event"
|
7
|
+
require "webmock/rspec"
|
8
|
+
require "zlib"
|
9
|
+
|
10
|
+
describe LogStash::Outputs::NewRelicInternal do
|
11
|
+
let (:api_key) { "someAccountKey" }
|
12
|
+
let (:base_uri) { "https://testing-example-collector.com" }
|
13
|
+
let (:retry_seconds) { 0 }
|
14
|
+
# Don't sleep in tests, to keep tests fast. We have a test for the method that produces the sleep duration between retries.
|
15
|
+
let (:max_delay) { 0 }
|
16
|
+
let (:retries) { 3 }
|
17
|
+
let (:simple_config) {
|
18
|
+
{
|
19
|
+
"api_key" => api_key,
|
20
|
+
"base_uri" => base_uri,
|
21
|
+
"retries" => retries,
|
22
|
+
"retry_seconds" => retry_seconds,
|
23
|
+
"max_delay" => max_delay,
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
def gunzip(bytes)
|
28
|
+
gz = Zlib::GzipReader.new(StringIO.new(bytes))
|
29
|
+
gz.read
|
30
|
+
end
|
31
|
+
|
32
|
+
def single_gzipped_message(body)
|
33
|
+
message = JSON.parse(gunzip(body))[0]['logs']
|
34
|
+
expect(message.length).to equal(1)
|
35
|
+
message[0]
|
36
|
+
end
|
37
|
+
|
38
|
+
def multiple_gzipped_messages(body)
|
39
|
+
JSON.parse(gunzip(body))
|
40
|
+
end
|
41
|
+
|
42
|
+
before(:each) do
|
43
|
+
@newrelic_output = LogStash::Plugin.lookup("output", "newrelic_internal").new(simple_config)
|
44
|
+
@newrelic_output.register
|
45
|
+
end
|
46
|
+
|
47
|
+
after(:each) do
|
48
|
+
@newrelic_output&.shutdown
|
49
|
+
end
|
50
|
+
|
51
|
+
context "validation of config" do
|
52
|
+
it "requires api_key" do
|
53
|
+
no_api_key_config = {
|
54
|
+
}
|
55
|
+
|
56
|
+
expect { LogStash::Plugin.lookup("output", "newrelic_internal").new(no_api_key_config) }.to raise_error LogStash::ConfigurationError
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "request headers" do
|
61
|
+
it "all present" do
|
62
|
+
stub_request(:any, base_uri).to_return(status: 200)
|
63
|
+
|
64
|
+
event = LogStash::Event.new({ "message" => "Test message" })
|
65
|
+
@newrelic_output.multi_receive([event])
|
66
|
+
|
67
|
+
wait_for(a_request(:post, base_uri)
|
68
|
+
.with(headers: {
|
69
|
+
"X-Insert-Key" => api_key,
|
70
|
+
"X-Event-Source" => "logs",
|
71
|
+
"Content-Encoding" => "gzip",
|
72
|
+
})).to have_been_made
|
73
|
+
end
|
74
|
+
end
|
75
|
+
context "request body" do
|
76
|
+
|
77
|
+
it "message contains plugin information" do
|
78
|
+
stub_request(:any, base_uri).to_return(status: 200)
|
79
|
+
|
80
|
+
event = LogStash::Event.new({ :message => "Test message", :@timestamp => '123' })
|
81
|
+
@newrelic_output.multi_receive([event])
|
82
|
+
|
83
|
+
wait_for(a_request(:post, base_uri)
|
84
|
+
.with { |request|
|
85
|
+
data = multiple_gzipped_messages(request.body)[0]
|
86
|
+
data['common']['attributes']['plugin']['type'] == 'logstash' &&
|
87
|
+
data['common']['attributes']['plugin']['version'] == LogStash::Outputs::NewRelicInternalVersion::VERSION })
|
88
|
+
.to have_been_made
|
89
|
+
end
|
90
|
+
|
91
|
+
# TODO: why is this field always removed?
|
92
|
+
it "'@timestamp' field is removed" do
|
93
|
+
stub_request(:any, base_uri).to_return(status: 200)
|
94
|
+
|
95
|
+
event = LogStash::Event.new({ :message => "Test message", :@timestamp => '123' })
|
96
|
+
@newrelic_output.multi_receive([event])
|
97
|
+
|
98
|
+
wait_for(a_request(:post, base_uri)
|
99
|
+
.with { |request| single_gzipped_message(request.body)['@timestamp'] == nil })
|
100
|
+
.to have_been_made
|
101
|
+
end
|
102
|
+
|
103
|
+
it "all other fields passed through as is" do
|
104
|
+
stub_request(:any, base_uri).to_return(status: 200)
|
105
|
+
|
106
|
+
event = LogStash::Event.new({ :message => "Test message", :other => "Other value" })
|
107
|
+
@newrelic_output.multi_receive([event])
|
108
|
+
|
109
|
+
wait_for(a_request(:post, base_uri)
|
110
|
+
.with { |request|
|
111
|
+
message = single_gzipped_message(request.body)
|
112
|
+
message['message'] == 'Test message' &&
|
113
|
+
message['other'] == 'Other value' })
|
114
|
+
.to have_been_made
|
115
|
+
end
|
116
|
+
|
117
|
+
it "JSON object 'message' field is parsed, removed, and its data merged as attributes" do
|
118
|
+
stub_request(:any, base_uri).to_return(status: 200)
|
119
|
+
|
120
|
+
message_json = '{ "in-json-1": "1", "in-json-2": "2", "sub-object": {"in-json-3": "3"} }'
|
121
|
+
event = LogStash::Event.new({ :message => message_json, :other => "Other value" })
|
122
|
+
@newrelic_output.multi_receive([event])
|
123
|
+
|
124
|
+
wait_for(a_request(:post, base_uri)
|
125
|
+
.with { |request|
|
126
|
+
message = single_gzipped_message(request.body)
|
127
|
+
message['in-json-1'] == '1' &&
|
128
|
+
message['in-json-2'] == '2' &&
|
129
|
+
message['sub-object'] == {"in-json-3" => "3"} &&
|
130
|
+
message['other'] == 'Other value' })
|
131
|
+
.to have_been_made
|
132
|
+
end
|
133
|
+
|
134
|
+
it "JSON array 'message' field is not parsed, left as is" do
|
135
|
+
stub_request(:any, base_uri).to_return(status: 200)
|
136
|
+
|
137
|
+
message_json_array = '[{ "in-json-1": "1", "in-json-2": "2", "sub-object": {"in-json-3": "3"} }]'
|
138
|
+
event = LogStash::Event.new({ :message => message_json_array, :other => "Other value" })
|
139
|
+
@newrelic_output.multi_receive([event])
|
140
|
+
|
141
|
+
wait_for(a_request(:post, base_uri)
|
142
|
+
.with { |request|
|
143
|
+
message = single_gzipped_message(request.body)
|
144
|
+
message['message'] == message_json_array &&
|
145
|
+
message['other'] == 'Other value' })
|
146
|
+
.to have_been_made
|
147
|
+
end
|
148
|
+
|
149
|
+
it "JSON string 'message' field is not parsed, left as is" do
|
150
|
+
stub_request(:any, base_uri).to_return(status: 200)
|
151
|
+
|
152
|
+
message_json_string = '"I can be parsed as JSON"'
|
153
|
+
event = LogStash::Event.new({ :message => message_json_string, :other => "Other value" })
|
154
|
+
@newrelic_output.multi_receive([event])
|
155
|
+
|
156
|
+
wait_for(a_request(:post, base_uri)
|
157
|
+
.with { |request|
|
158
|
+
message = single_gzipped_message(request.body)
|
159
|
+
message['message'] == message_json_string &&
|
160
|
+
message['other'] == 'Other value' })
|
161
|
+
.to have_been_made
|
162
|
+
end
|
163
|
+
|
164
|
+
it "other JSON fields are not parsed" do
|
165
|
+
stub_request(:any, base_uri).to_return(status: 200)
|
166
|
+
|
167
|
+
other_json = '{ "key": "value" }'
|
168
|
+
event = LogStash::Event.new({ :message => "Test message", :other => other_json })
|
169
|
+
@newrelic_output.multi_receive([event])
|
170
|
+
|
171
|
+
wait_for(a_request(:post, base_uri)
|
172
|
+
.with { |request|
|
173
|
+
message = single_gzipped_message(request.body)
|
174
|
+
message['message'] == 'Test message' &&
|
175
|
+
message['other'] == other_json })
|
176
|
+
.to have_been_made
|
177
|
+
end
|
178
|
+
|
179
|
+
it "handles messages without a 'message' field" do
|
180
|
+
stub_request(:any, base_uri).to_return(status: 200)
|
181
|
+
|
182
|
+
event = LogStash::Event.new({ :other => 'Other value' })
|
183
|
+
@newrelic_output.multi_receive([event])
|
184
|
+
|
185
|
+
wait_for(a_request(:post, base_uri)
|
186
|
+
.with { |request|
|
187
|
+
message = single_gzipped_message(request.body)
|
188
|
+
message['other'] == 'Other value' })
|
189
|
+
.to have_been_made
|
190
|
+
end
|
191
|
+
|
192
|
+
it "multiple events" do
|
193
|
+
stub_request(:any, base_uri).to_return(status: 200)
|
194
|
+
|
195
|
+
event1 = LogStash::Event.new({ "message" => "Test message 1" })
|
196
|
+
event2 = LogStash::Event.new({ "message" => "Test message 2" })
|
197
|
+
@newrelic_output.multi_receive([event1, event2])
|
198
|
+
|
199
|
+
wait_for(a_request(:post, base_uri)
|
200
|
+
.with { |request|
|
201
|
+
messages = multiple_gzipped_messages(request.body)[0]['logs']
|
202
|
+
messages.length == 2 &&
|
203
|
+
messages[0]['message'] == 'Test message 1' &&
|
204
|
+
messages[1]['message'] == 'Test message 2' })
|
205
|
+
.to have_been_made
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context "retry" do
|
210
|
+
it "sleep periods double each time up to max time" do
|
211
|
+
specific_config = simple_config.clone
|
212
|
+
# Use non-trivial times -- they can be big, since this test doesn't do any sleeping, just
|
213
|
+
# tests the sleep duration
|
214
|
+
specific_config["max_delay"] = 60
|
215
|
+
specific_config["retry_seconds"] = 5
|
216
|
+
|
217
|
+
# Create a new plugin with this specific config that has longer retry sleep
|
218
|
+
# configuration than we normally want
|
219
|
+
@newrelic_output&.shutdown
|
220
|
+
@newrelic_output = LogStash::Plugin.lookup("output", "newrelic_internal").new(specific_config)
|
221
|
+
@newrelic_output.register
|
222
|
+
|
223
|
+
expect(@newrelic_output.sleep_duration(0)).to equal(5)
|
224
|
+
expect(@newrelic_output.sleep_duration(1)).to equal(10)
|
225
|
+
expect(@newrelic_output.sleep_duration(2)).to equal(20)
|
226
|
+
expect(@newrelic_output.sleep_duration(3)).to equal(40)
|
227
|
+
expect(@newrelic_output.sleep_duration(4)).to equal(60)
|
228
|
+
expect(@newrelic_output.sleep_duration(5)).to equal(60) # Never gets bigger than this
|
229
|
+
end
|
230
|
+
|
231
|
+
it "first call fails, should retry" do
|
232
|
+
stub_request(:any, base_uri)
|
233
|
+
.to_return(status: 500)
|
234
|
+
.to_return(status: 200)
|
235
|
+
|
236
|
+
event = LogStash::Event.new({ "message" => "Test message" })
|
237
|
+
@newrelic_output.multi_receive([event])
|
238
|
+
|
239
|
+
wait_for(a_request(:post, base_uri)).to have_been_made.times(2)
|
240
|
+
end
|
241
|
+
|
242
|
+
it "first two calls fail, should retry" do
|
243
|
+
stub_request(:any, base_uri)
|
244
|
+
.to_return(status: 500)
|
245
|
+
.to_return(status: 500)
|
246
|
+
.to_return(status: 200)
|
247
|
+
|
248
|
+
event = LogStash::Event.new({ "message" => "Test message" })
|
249
|
+
@newrelic_output.multi_receive([event])
|
250
|
+
|
251
|
+
wait_for(a_request(:post, base_uri)).to have_been_made.times(3)
|
252
|
+
end
|
253
|
+
|
254
|
+
it "all calls fails, should stop retrying at some point" do
|
255
|
+
stub_request(:any, base_uri)
|
256
|
+
.to_return(status: 500)
|
257
|
+
|
258
|
+
event = LogStash::Event.new({ "message" => "Test message" })
|
259
|
+
@newrelic_output.multi_receive([event])
|
260
|
+
|
261
|
+
# This may not fail if the wait_for is called exactly when there have been 'retries' calls.
|
262
|
+
# However, with zero sleep time (max_delay=0), on a laptop the POST was done 2000+ times by the
|
263
|
+
# time this was executed
|
264
|
+
wait_for(a_request(:post, base_uri)).to have_been_made.times(retries)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context "error handling" do
|
269
|
+
it "continues through errors, future calls should still succeed" do
|
270
|
+
stub_request(:any, base_uri)
|
271
|
+
.to_raise(StandardError.new("from test"))
|
272
|
+
.to_return(status: 200)
|
273
|
+
|
274
|
+
event1 = LogStash::Event.new({ "message" => "Test message 1" })
|
275
|
+
event2 = LogStash::Event.new({ "message" => "Test message 2" })
|
276
|
+
@newrelic_output.multi_receive([event1])
|
277
|
+
@newrelic_output.multi_receive([event2])
|
278
|
+
|
279
|
+
wait_for(a_request(:post, base_uri)
|
280
|
+
.with { |request| single_gzipped_message(request.body)['message'] == 'Test message 2' })
|
281
|
+
.to have_been_made
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
metadata
CHANGED
@@ -1,39 +1,33 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-output-newrelic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- New Relic Logging Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-06-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
|
-
- -
|
16
|
+
- - "~>"
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: '
|
19
|
-
- - <=
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '2.99'
|
18
|
+
version: '2.0'
|
22
19
|
name: logstash-core-plugin-api
|
23
20
|
prerelease: false
|
24
21
|
type: :runtime
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '1.60'
|
30
|
-
- - <=
|
24
|
+
- - "~>"
|
31
25
|
- !ruby/object:Gem::Version
|
32
|
-
version: '2.
|
26
|
+
version: '2.0'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
requirement: !ruby/object:Gem::Requirement
|
35
29
|
requirements:
|
36
|
-
- -
|
30
|
+
- - ">="
|
37
31
|
- !ruby/object:Gem::Version
|
38
32
|
version: '0'
|
39
33
|
name: logstash-codec-plain
|
@@ -41,13 +35,13 @@ dependencies:
|
|
41
35
|
type: :runtime
|
42
36
|
version_requirements: !ruby/object:Gem::Requirement
|
43
37
|
requirements:
|
44
|
-
- -
|
38
|
+
- - ">="
|
45
39
|
- !ruby/object:Gem::Version
|
46
40
|
version: '0'
|
47
41
|
- !ruby/object:Gem::Dependency
|
48
42
|
requirement: !ruby/object:Gem::Requirement
|
49
43
|
requirements:
|
50
|
-
- -
|
44
|
+
- - ">="
|
51
45
|
- !ruby/object:Gem::Version
|
52
46
|
version: '0'
|
53
47
|
name: logstash-devutils
|
@@ -55,35 +49,57 @@ dependencies:
|
|
55
49
|
type: :development
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
51
|
requirements:
|
58
|
-
- -
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
name: webmock
|
62
|
+
prerelease: false
|
63
|
+
type: :development
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
name: rspec-wait
|
76
|
+
prerelease: false
|
77
|
+
type: :development
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
59
81
|
- !ruby/object:Gem::Version
|
60
82
|
version: '0'
|
61
|
-
description:
|
62
|
-
|
83
|
+
description: Gzips and decorates logstash events to be properly formatted as custom
|
84
|
+
events
|
85
|
+
email: logging-team@newrelic.com
|
63
86
|
executables: []
|
64
87
|
extensions: []
|
65
88
|
extra_rdoc_files: []
|
66
89
|
files:
|
67
|
-
- .github/CONTRIBUTING.md
|
68
|
-
- .github/ISSUE_TEMPLATE.md
|
69
|
-
- .github/PULL_REQUEST_TEMPLATE.md
|
70
|
-
- .gitignore
|
71
|
-
- .travis.yml
|
72
90
|
- CHANGELOG.md
|
91
|
+
- CONTRIBUTORS
|
92
|
+
- DEVELOPER.md
|
73
93
|
- Gemfile
|
74
94
|
- LICENSE
|
75
|
-
- NOTICE.TXT
|
76
95
|
- README.md
|
77
|
-
-
|
78
|
-
-
|
79
|
-
- bin/logstash-newrelic-debug
|
80
|
-
- bin/logstash-newrelic.conf.template
|
81
|
-
- lib/logstash/outputs/newrelic.rb
|
96
|
+
- lib/logstash/outputs/newrelic_internal.rb
|
97
|
+
- lib/logstash/outputs/newrelic_internal_version/version.rb
|
82
98
|
- logstash-output-newrelic.gemspec
|
83
|
-
- spec/outputs/
|
84
|
-
homepage:
|
99
|
+
- spec/outputs/newrelic_internal_spec.rb
|
100
|
+
homepage: https://source.datanerd.us/logging/logstash-output-newrelic
|
85
101
|
licenses:
|
86
|
-
-
|
102
|
+
- Apache-2.0
|
87
103
|
metadata:
|
88
104
|
logstash_plugin: 'true'
|
89
105
|
logstash_group: output
|
@@ -93,19 +109,19 @@ require_paths:
|
|
93
109
|
- lib
|
94
110
|
required_ruby_version: !ruby/object:Gem::Requirement
|
95
111
|
requirements:
|
96
|
-
- -
|
112
|
+
- - ">="
|
97
113
|
- !ruby/object:Gem::Version
|
98
114
|
version: '0'
|
99
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
116
|
requirements:
|
101
|
-
- -
|
117
|
+
- - ">="
|
102
118
|
- !ruby/object:Gem::Version
|
103
119
|
version: '0'
|
104
120
|
requirements: []
|
105
121
|
rubyforge_project:
|
106
|
-
rubygems_version: 2.
|
122
|
+
rubygems_version: 2.7.6
|
107
123
|
signing_key:
|
108
124
|
specification_version: 4
|
109
|
-
summary:
|
125
|
+
summary: Forwards logs as custom events to insights
|
110
126
|
test_files:
|
111
|
-
- spec/outputs/
|
127
|
+
- spec/outputs/newrelic_internal_spec.rb
|
data/.github/CONTRIBUTING.md
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
# Contributing to Logstash
|
2
|
-
|
3
|
-
All contributions are welcome: ideas, patches, documentation, bug reports,
|
4
|
-
complaints, etc!
|
5
|
-
|
6
|
-
Programming is not a required skill, and there are many ways to help out!
|
7
|
-
It is more important to us that you are able to contribute.
|
8
|
-
|
9
|
-
That said, some basic guidelines, which you are free to ignore :)
|
10
|
-
|
11
|
-
## Want to learn?
|
12
|
-
|
13
|
-
Want to lurk about and see what others are doing with Logstash?
|
14
|
-
|
15
|
-
* The irc channel (#logstash on irc.freenode.org) is a good place for this
|
16
|
-
* The [forum](https://discuss.elastic.co/c/logstash) is also
|
17
|
-
great for learning from others.
|
18
|
-
|
19
|
-
## Got Questions?
|
20
|
-
|
21
|
-
Have a problem you want Logstash to solve for you?
|
22
|
-
|
23
|
-
* You can ask a question in the [forum](https://discuss.elastic.co/c/logstash)
|
24
|
-
* Alternately, you are welcome to join the IRC channel #logstash on
|
25
|
-
irc.freenode.org and ask for help there!
|
26
|
-
|
27
|
-
## Have an Idea or Feature Request?
|
28
|
-
|
29
|
-
* File a ticket on [GitHub](https://github.com/elastic/logstash/issues). Please remember that GitHub is used only for issues and feature requests. If you have a general question, the [forum](https://discuss.elastic.co/c/logstash) or IRC would be the best place to ask.
|
30
|
-
|
31
|
-
## Something Not Working? Found a Bug?
|
32
|
-
|
33
|
-
If you think you found a bug, it probably is a bug.
|
34
|
-
|
35
|
-
* If it is a general Logstash or a pipeline issue, file it in [Logstash GitHub](https://github.com/elasticsearch/logstash/issues)
|
36
|
-
* If it is specific to a plugin, please file it in the respective repository under [logstash-plugins](https://github.com/logstash-plugins)
|
37
|
-
* or ask the [forum](https://discuss.elastic.co/c/logstash).
|
38
|
-
|
39
|
-
# Contributing Documentation and Code Changes
|
40
|
-
|
41
|
-
If you have a bugfix or new feature that you would like to contribute to
|
42
|
-
logstash, and you think it will take more than a few minutes to produce the fix
|
43
|
-
(ie; write code), it is worth discussing the change with the Logstash users and developers first! You can reach us via [GitHub](https://github.com/elastic/logstash/issues), the [forum](https://discuss.elastic.co/c/logstash), or via IRC (#logstash on freenode irc)
|
44
|
-
Please note that Pull Requests without tests will not be merged. If you would like to contribute but do not have experience with writing tests, please ping us on IRC/forum or create a PR and ask our help.
|
45
|
-
|
46
|
-
## Contributing to plugins
|
47
|
-
|
48
|
-
Check our [documentation](https://www.elastic.co/guide/en/logstash/current/contributing-to-logstash.html) on how to contribute to plugins or write your own! It is super easy!
|
49
|
-
|
50
|
-
## Contribution Steps
|
51
|
-
|
52
|
-
1. Test your changes! [Run](https://github.com/elastic/logstash#testing) the test suite
|
53
|
-
2. Please make sure you have signed our [Contributor License
|
54
|
-
Agreement](https://www.elastic.co/contributor-agreement/). We are not
|
55
|
-
asking you to assign copyright to us, but to give us the right to distribute
|
56
|
-
your code without restriction. We ask this of all contributors in order to
|
57
|
-
assure our users of the origin and continuing existence of the code. You
|
58
|
-
only need to sign the CLA once.
|
59
|
-
3. Send a pull request! Push your changes to your fork of the repository and
|
60
|
-
[submit a pull
|
61
|
-
request](https://help.github.com/articles/using-pull-requests). In the pull
|
62
|
-
request, describe what your changes do and mention any bugs/issues related
|
63
|
-
to the pull request.
|
64
|
-
|
65
|
-
|
data/.github/ISSUE_TEMPLATE.md
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
Please post all product and debugging questions on our [forum](https://discuss.elastic.co/c/logstash). Your questions will reach our wider community members there, and if we confirm that there is a bug, then we can open a new issue here.
|
2
|
-
|
3
|
-
For all general issues, please provide the following details for fast resolution:
|
4
|
-
|
5
|
-
- Version:
|
6
|
-
- Operating System:
|
7
|
-
- Config File (if you have sensitive info, please remove it):
|
8
|
-
- Sample Data:
|
9
|
-
- Steps to Reproduce:
|
@@ -1 +0,0 @@
|
|
1
|
-
Thanks for contributing to Logstash! If you haven't already signed our CLA, here's a handy link: https://www.elastic.co/contributor-agreement/
|
data/.gitignore
DELETED
data/.travis.yml
DELETED
data/NOTICE.TXT
DELETED
data/Rakefile
DELETED
data/bin/logstash-newrelic
DELETED
data/bin/logstash-newrelic-debug
DELETED