logstash-output-loggly 5.0.0 → 6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5ef3911c30709e44be9b65e5be43f192b716bc00b40c9d373fcc78677f7b060
4
- data.tar.gz: 1be2aa1769cf66c2bf19d431738a6995217b8ee9007533a1848647c0b358b2dd
3
+ metadata.gz: bccd01fccea37ecf90a43b572b94db5e05dad7e415b8d2b8c97afb9c835eb8f6
4
+ data.tar.gz: fab97721a923024d364c1a36cdfad1be3d2b1b59c78b370867ebb744457c83f6
5
5
  SHA512:
6
- metadata.gz: 85b87a48f7c044a25fb8739c21761ced70f6d131614890fb39a7ae7edd03be025e0f0cc0bbc4b4ab16ca19d398ff389c95f9aea759d31e63cb294ded666e659f
7
- data.tar.gz: 6bfa8d3d9ef0dbbceb2332b30b13fc794dc75935ff31c45ba7494ad4de243db5f433642b78538dccbaf30593f476702307d01913788e5c684a6e56d0734b1c41
6
+ metadata.gz: c3da1ce06b6dbf4ba04e2baad8082e753cc7cd7759b1a8d17e164565e8c02fa685599899053641f91789f17dce231b8fb5e9669db02be6711cdf867066d55f6a
7
+ data.tar.gz: 6fb1b4d3ff313299f29863208a4882f0c554cf5541eba386135250510cd6bcfb7aab980715c4d43a695c23e22cc732b84a836f18cc973f9b9161777039cda62a
@@ -1,5 +1,13 @@
1
+ ## 6.0.0
2
+ - Fixed bug when interpolation fails in a list of tag. The list of tags no
3
+ longer gets completely replaced with a default value.
4
+ [#31](https://github.com/logstash-plugins/logstash-output-loggly/pull/31)
5
+ - [BREAKING] Changed tagging to no longer set a tag by default.
6
+ The tag is optional with Loggly.
7
+ [#31](https://github.com/logstash-plugins/logstash-output-loggly/pull/31)
8
+
1
9
  ## 5.0.0
2
- - This version introduces "breaking" changes for users who never copied/renamed
10
+ - [BREAKING] This version introduces "breaking" changes for users who never copied/renamed
3
11
  their `@timestamp` field to `timestamp`: their events will suddenly appear
4
12
  in Loggly with a `timestamp` based on Logstash's value of `@timestamp`.
5
13
  This would especially be noticed at times where processing is behind, and
@@ -20,9 +28,9 @@
20
28
  - New settings: `max_event_size` and `max_payload_size`.
21
29
  Both are currently set according to Loggly's [published API limits](https://www.loggly.com/docs/http-bulk-endpoint/).
22
30
  They only need to be changed if Loggly changes these limits.
23
- - The plugin now skips events bigger than the API limit for single event size.
31
+ - [BREAKING] The plugin now skips events bigger than the API limit for single event size.
24
32
  A proper warning is logged when this happens.
25
- - When interpolating `key` field, drop messages where interpolation doesn't
33
+ - [BREAKING] When interpolating `key` field, drop messages where interpolation doesn't
26
34
  resolve (meaning we don't have the API key for the event).
27
35
  - When interpolating `tag` field, revert to default of 'logstash' if interpolation doesn't resolve.
28
36
  - Beef up unit tests significantly.
@@ -189,16 +189,17 @@ It will try to submit request until retry_count and then halt
189
189
  ===== `tag`
190
190
 
191
191
  * Value type is <<string,string>>
192
- * Default value is `"logstash"`
193
192
 
194
193
  Loggly Tags help you to find your logs in the Loggly dashboard easily.
195
- You can search for a tag in Loggly using `"tag:logstash"`.
194
+ You can search for a tag in Loggly, using `"tag:your_tag"`.
196
195
 
197
196
  If you need to specify multiple tags here on your events,
198
197
  specify them as outlined in https://www.loggly.com/docs/tags/[the tag documentation].
199
198
  E.g. `"tag" => "foo,bar,myApp"`.
200
199
 
201
- You can also use `"tag" => "%{somefield}"` to take your tag value from `somefield` on your event.
200
+ You can also use `"tag" => "%{somefield},%{another_field}"` to take your tag values
201
+ from `somefield` and `another_field` on your event. If the field doesn't exist,
202
+ no tag will be created.
202
203
  Helpful for leveraging https://www.loggly.com/docs/source-groups/[Loggly source groups].
203
204
 
204
205
 
@@ -59,17 +59,18 @@ class LogStash::Outputs::Loggly < LogStash::Outputs::Base
59
59
  config :proto, :validate => :string, :default => "http"
60
60
 
61
61
  # Loggly Tags help you to find your logs in the Loggly dashboard easily.
62
- # You can search for a tag in Loggly using `"tag:logstash"`.
62
+ # You can search for a tag in Loggly using `"tag:your_tag"`.
63
63
  #
64
64
  # If you need to specify multiple tags here on your events,
65
65
  # specify them as outlined in the tag documentation (https://www.loggly.com/docs/tags/).
66
66
  # E.g. `"tag" => "foo,bar,myApp"`.
67
67
  #
68
- # You can also use `"tag" => "%{somefield}"` to take your tag value from `somefield` on your event.
68
+ # You can also use `"tag" => "%{somefield},%{another_field}"` to take your tag values
69
+ # from `somefield` and `another_field` on your event. If the field doesn't exist,
70
+ # no tag will be created.
69
71
  # Helpful for leveraging Loggly source groups (https://www.loggly.com/docs/source-groups/).
70
72
 
71
- DEFAULT_LOGGLY_TAG = 'logstash'
72
- config :tag, :validate => :string, :default => DEFAULT_LOGGLY_TAG
73
+ config :tag, :validate => :string, :default => ''
73
74
 
74
75
  # Retry count.
75
76
  # It may be possible that the request may timeout due to slow Internet connection
@@ -81,6 +82,8 @@ class LogStash::Outputs::Loggly < LogStash::Outputs::Base
81
82
  # Setting this value true helps user to send multiple retry attempts if the first request fails
82
83
  config :can_retry, :validate => :boolean, :default => true
83
84
 
85
+ config :mime_type, :validate => :string, :default => 'application/json'
86
+
84
87
  # Proxy Host
85
88
  config :proxy_host, :validate => :string
86
89
 
@@ -133,7 +136,16 @@ class LogStash::Outputs::Loggly < LogStash::Outputs::Base
133
136
  # or returns nil, if event's key doesn't resolve.
134
137
  def prepare_meta(event)
135
138
  key = event.sprintf(@key)
136
- tag = event.sprintf(@tag)
139
+ tags = @tag.split(",")
140
+ tag_array = []
141
+
142
+ tags.each do |t|
143
+ t = event.sprintf(t)
144
+ # For those cases where %{somefield} doesn't exist we don't include it
145
+ unless /%{\w+}/.match(t) || t.blank?
146
+ tag_array.push(t)
147
+ end
148
+ end
137
149
 
138
150
  if expected_field = key[/%{(.*)}/, 1]
139
151
  @logger.warn "Skipping sending message to Loggly. No key provided (key='#{key}'). Make sure to set field '#{expected_field}'."
@@ -141,9 +153,9 @@ class LogStash::Outputs::Loggly < LogStash::Outputs::Base
141
153
  return nil
142
154
  end
143
155
 
144
- # For those cases where %{somefield} doesn't exist
145
- # we should ship logs with the default tag value.
146
- tag = DEFAULT_LOGGLY_TAG if /%{\w+}/.match(tag)
156
+ unless tag_array.empty?
157
+ tag = tag_array.uniq.join(",")
158
+ end
147
159
 
148
160
  event_hash = event.to_hash # Don't want to modify the event in an output
149
161
  if @convert_timestamp && event_hash['@timestamp'] && !event_hash['timestamp']
@@ -163,7 +175,12 @@ class LogStash::Outputs::Loggly < LogStash::Outputs::Base
163
175
  def send_batch(meta_events)
164
176
  split_batches(meta_events.compact).each_pair do |k, batch|
165
177
  key, tag = *k
166
- url = "#{@proto}://#{@host}/bulk/#{key}/tag/#{tag}"
178
+ if tag.nil?
179
+ url = "#{@proto}://#{@host}/bulk/#{key}"
180
+ else
181
+ url = "#{@proto}://#{@host}/bulk/#{key}/tag/#{tag}"
182
+ end
183
+
167
184
 
168
185
  build_message_bodies(batch) do |body|
169
186
  perform_api_call url, body
@@ -241,7 +258,7 @@ class LogStash::Outputs::Loggly < LogStash::Outputs::Base
241
258
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
242
259
  end
243
260
 
244
- request = Net::HTTP::Post.new(url.path, {'Content-Type' =>'application/json'})
261
+ request = Net::HTTP::Post.new(url.path, {'Content-Type' => @mime_type})
245
262
  request.body = message
246
263
 
247
264
  # Variable for count total retries
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-loggly'
3
- s.version = '5.0.0'
4
- s.licenses = ['Apache License (2.0)']
3
+ s.version = '6.0.0'
4
+ s.licenses = ['Apache-2.0']
5
5
  s.summary = "Ships logs to Loggly"
6
6
  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"
7
7
  s.authors = ["Elastic"]
@@ -33,15 +33,15 @@ describe 'outputs/loggly' do
33
33
  it 'should have default config values' do
34
34
  expect(subject.proto).to eq('http')
35
35
  expect(subject.host).to eq('logs-01.loggly.com')
36
- expect(subject.tag).to eq('logstash')
36
+ expect(subject.tag).to eq('')
37
37
  expect(subject.max_event_size).to eq(1_048_576)
38
38
  expect(subject.max_payload_size).to eq(5_242_880)
39
39
  end
40
40
  end
41
41
 
42
42
  context 'when sending events' do
43
- it 'should set the default tag to logstash' do
44
- expect(output).to receive(:send_batch).with([{event: event.to_hash, key: 'abcdef123456', tag: 'logstash'}])
43
+ it 'should set the default tag to nil' do
44
+ expect(output).to receive(:send_batch).with([{event: event.to_hash, key: 'abcdef123456', tag: nil}])
45
45
  output.receive(event)
46
46
  end
47
47
 
@@ -50,7 +50,7 @@ describe 'outputs/loggly' do
50
50
  event.set('token', 'xxxxxxx1234567')
51
51
  config['key'] = '%{token}'
52
52
 
53
- expect(output).to receive(:send_batch).with([{event: event.to_hash, key: 'xxxxxxx1234567', tag: 'logstash'}])
53
+ expect(output).to receive(:send_batch).with([{event: event.to_hash, key: 'xxxxxxx1234567', tag: nil}])
54
54
  output.receive(event)
55
55
  end
56
56
 
@@ -60,9 +60,9 @@ describe 'outputs/loggly' do
60
60
  output.receive(event)
61
61
  end
62
62
 
63
- it 'should default tag to logstash if interpolated field for tag does not exist' do
63
+ it 'should have no tag if the interpolated field for the tag does not exist' do
64
64
  config['tag'] = '%{foobar}'
65
- expect(output).to receive(:send_batch).with([{event: event.to_hash, key: 'abcdef123456', tag: 'logstash'}])
65
+ expect(output).to receive(:send_batch).with([{event: event.to_hash, key: 'abcdef123456', tag: nil}])
66
66
  output.receive(event)
67
67
  end
68
68
 
@@ -72,7 +72,7 @@ describe 'outputs/loggly' do
72
72
  event2 = event.clone
73
73
  event2.remove('custom_key')
74
74
 
75
- expect(output).to receive(:send_batch).once.with([{event: event.to_hash, key: 'a_key', tag: 'logstash'}, nil])
75
+ expect(output).to receive(:send_batch).once.with([{event: event.to_hash, key: 'a_key', tag: nil}, nil])
76
76
  logger = logger_for(output)
77
77
  expect(logger).to receive(:warn).with(/No key provided/)
78
78
  expect(logger).to receive(:debug).with(/Dropped message/, kind_of(Hash))
@@ -94,11 +94,11 @@ describe 'outputs/loggly' do
94
94
  expect(output).to receive(:perform_api_call) { |url, body|
95
95
  expect(body).to match /"event1"/
96
96
  expect(body).to match /"event4"/
97
- expect(url).to eq('http://logs-01.loggly.com/bulk/generally_used_key/tag/logstash')
97
+ expect(url).to eq('http://logs-01.loggly.com/bulk/generally_used_key')
98
98
  }
99
99
  expect(output).to receive(:perform_api_call) { |url, body|
100
100
  expect(body).to match /"event2"/
101
- expect(url).to eq('http://logs-01.loggly.com/bulk/other_key/tag/logstash')
101
+ expect(url).to eq('http://logs-01.loggly.com/bulk/other_key')
102
102
  }
103
103
  expect(output).to receive(:perform_api_call) { |url, body|
104
104
  expect(body).to match /"event3"/
@@ -110,6 +110,54 @@ describe 'outputs/loggly' do
110
110
  end
111
111
  end
112
112
 
113
+ context 'when computing the tags' do
114
+ it 'should not leave a failed interpolation in the tag list' do
115
+ config['tag'] = '%{field1},%{field2}'
116
+ event.set('field1', 'some_value1')
117
+
118
+ meta_event = output.send :prepare_meta, event
119
+ expect(meta_event[:tag]).to eq('some_value1')
120
+ end
121
+
122
+ it 'should support no interpolation' do
123
+ config['tag'] = 'some_tag'
124
+
125
+ meta_event = output.send :prepare_meta, event
126
+ expect(meta_event[:tag]).to eq('some_tag')
127
+ end
128
+
129
+ it 'should support interpolation of one tag' do
130
+ config['tag'] = '%{field1}'
131
+ event.set('field1', 'some_value1')
132
+
133
+ meta_event = output.send :prepare_meta, event
134
+ expect(meta_event[:tag]).to eq('some_value1')
135
+ end
136
+
137
+ it 'should support interpolation of one tag in a list of tags' do
138
+ config['tag'] = '%{field1},some_value2'
139
+ event.set('field1', 'some_value1')
140
+
141
+ meta_event = output.send :prepare_meta, event
142
+ expect(meta_event[:tag]).to eq('some_value1,some_value2')
143
+ end
144
+
145
+ it 'should remove duplicate tags' do
146
+ config['tag'] = 'some_value,some_value'
147
+
148
+ meta_event = output.send :prepare_meta, event
149
+ expect(meta_event[:tag]).to eq('some_value')
150
+ end
151
+
152
+ it 'should remove tag if field interpolated to empty string' do
153
+ config['tag'] = '%{field1}'
154
+ event.set('field1', '')
155
+
156
+ meta_event = output.send :prepare_meta, event
157
+ expect(meta_event[:tag]).to eq(nil)
158
+ end
159
+ end
160
+
113
161
  context 'timestamp mingling' do
114
162
  context 'when convert_timestamp is false' do
115
163
  let(:config) { super.merge('convert_timestamp' => false) }
@@ -173,14 +221,21 @@ describe 'outputs/loggly' do
173
221
  {event: :event5, key: 'key2', tag: 'tag1'},
174
222
  {event: :event6, key: 'key1', tag: 'tag1'},
175
223
  {event: :event7, key: 'key1', tag: 'tag1'},
224
+ {event: :event8, key: 'key1', tag: 'tag1,tag2'},
225
+ {event: :event9, key: 'key2', tag: 'tag1,tag2'},
176
226
  ])
177
- expect(batches.size).to eq(3)
227
+ expect(batches.size).to eq(5)
178
228
  expect(batches).to eq(
179
229
  { ['key1', 'tag1'] => [:event1, :event4, :event6, :event7],
180
230
  ['key2', 'tag1'] => [:event2, :event5],
181
231
  ['key2', 'tag2'] => [:event3],
232
+ ['key1', 'tag1,tag2'] => [:event8],
233
+ ['key2', 'tag1,tag2'] => [:event9],
182
234
  })
183
235
  end
236
+
237
+
238
+
184
239
  end
185
240
  end
186
241
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-loggly
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-21 00:00:00.000000000 Z
11
+ date: 2018-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -92,7 +92,7 @@ files:
92
92
  - spec/outputs/loggly_spec.rb
93
93
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
94
94
  licenses:
95
- - Apache License (2.0)
95
+ - Apache-2.0
96
96
  metadata:
97
97
  logstash_plugin: 'true'
98
98
  logstash_group: output