logstash-output-lmlogs 1.2.1 → 1.3.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: 3236f68981e8e3fb68a9335240874b9f8fb93b59372893425992f0c9c86f2895
4
- data.tar.gz: 850265953883226fd2c82b3ad00acf894667aaca86396af454af6d9d59411acc
3
+ metadata.gz: 870bd26e9fabeb697cb8dd8f66eeb7f243b4be3fcf51c0d3babb81260a08b3d9
4
+ data.tar.gz: 548fff67d397ef9a6c51a2bebb0c4f44d2b3decd57faa801bd9ac2e1048edad2
5
5
  SHA512:
6
- metadata.gz: 86a1e6be32d0c8f976371dd9441aa282c980a7886e4940b5e298ae28406c5f9e1934b751264a40010e7b94a307076248274c350ae87e51ce33d1b5cea1a1b57a
7
- data.tar.gz: 01ca2ae8f258141614eef6312fe18c394b7602bd9e88e86c57d6f810471ee204889da918da4704c999d2942ef368925ba675df9a6bc2fb4169e842beb4fe7455
6
+ metadata.gz: 504cdc43d302a8d504a38627e3b914e8514331ae889dbcfba7fa3f0da6f010aeb09aa19437f5d32e73e100db4d0f839f9c182eb4135b78cfb1d538a6ea0f4314
7
+ data.tar.gz: 78a8b8b391c4887bfa5a06b12d044d03c9d3b9f2cfdc9231ae5a9d0a70ac28d824e59ce493cf8a4f3d2fc7675ecd0a7ce8b7d71c60fa8fc57664a7937793ad07
data/CHANGELOG.md CHANGED
@@ -1,2 +1,14 @@
1
1
  ## 1.0.0
2
2
  - First version of the plugin
3
+ ## 1.0.1
4
+ - Proxy support
5
+ ## 1.0.2
6
+ - Update debug logs
7
+ ## 1.1.0
8
+ - Disable mfa for gem push
9
+ ## 1.2.0
10
+ - Add metadata by default to every log
11
+ ## 1.2.1
12
+ - Fix ensuring metadata exists before deleting the original while forwarding to lm-logs
13
+ ## 1.3.0
14
+ - Add bearer token support for authentication with Logicmonitor
@@ -30,7 +30,7 @@ class LogStash::Outputs::LMLogs < LogStash::Outputs::Base
30
30
 
31
31
  # Keep logstash timestamp
32
32
  config :keep_timestamp, :validate => :boolean, :default => true
33
-
33
+
34
34
  # Use a configured message key for timestamp values
35
35
  # Valid timestamp formats are ISO8601 strings or epoch in seconds, milliseconds or nanoseconds
36
36
  config :timestamp_is_key, :validate => :boolean, :default => false
@@ -91,13 +91,16 @@ class LogStash::Outputs::LMLogs < LogStash::Outputs::Base
91
91
  config :portal_name, :validate => :string, :required => true
92
92
 
93
93
  # Username to use for HTTP auth.
94
- config :access_id, :validate => :string, :required => true
94
+ config :access_id, :validate => :string, :required => false, :default => nil
95
95
 
96
96
  # Include/Exclude metadata from sending to LM Logs
97
97
  config :include_metadata, :validate => :boolean, :default => true
98
98
 
99
99
  # Password to use for HTTP auth
100
- config :access_key, :validate => :password, :required => true
100
+ config :access_key, :validate => :password, :required => false, :default => nil
101
+
102
+ # Use bearer token instead of access key/id for authentication.
103
+ config :bearer_token, :validate => :password, :required => false, :default => nil
101
104
 
102
105
  @@MAX_PAYLOAD_SIZE = 8*1024*1024
103
106
 
@@ -110,9 +113,9 @@ class LogStash::Outputs::LMLogs < LogStash::Outputs::Base
110
113
  @total_failed = 0
111
114
  logger.info("Initialized LogicMonitor output plugin with configuration",
112
115
  :host => @host)
113
- logger.info("Max Payload Size: ",
116
+ logger.info("Max Payload Size: ",
114
117
  :size => @@MAX_PAYLOAD_SIZE)
115
-
118
+ configure_auth
116
119
  end # def register
117
120
 
118
121
  def client_config
@@ -137,19 +140,7 @@ class LogStash::Outputs::LMLogs < LogStash::Outputs::Base
137
140
  @proxy
138
141
  end
139
142
 
140
- if @access_id
141
- if !@access_key || !@access_key.value
142
- raise ::LogStash::ConfigurationError, "access_id '#{@access_id}' specified without access_key!"
143
- end
144
-
145
- # Symbolize keys if necessary
146
- # c[:auth] = {
147
- # :user => @access_id,
148
- # :password => @access_key.value,
149
- # :eager => true
150
- # }
151
- end
152
- log_debug("manticore client config: ", :client => c)
143
+ log_debug("manticore client config: ", :client => c)
153
144
  return c
154
145
  end
155
146
 
@@ -168,21 +159,35 @@ class LogStash::Outputs::LMLogs < LogStash::Outputs::Base
168
159
  @client.close
169
160
  end
170
161
 
171
-
162
+ def configure_auth
163
+ @use_bearer_instead_of_lmv1 = false
164
+ if @access_id == nil || @access_key.value == nil
165
+ @logger.info "Access Id or access key null. Using bearer token for authentication."
166
+ @use_bearer_instead_of_lmv1 = true
167
+ end
168
+ if @use_bearer_instead_of_lmv1 && @bearer_token.value == nil
169
+ @logger.error "Bearer token not specified. Either access_id and access_key both or bearer_token must be specified for authentication with Logicmonitor."
170
+ raise LogStash::ConfigurationError, 'No valid authentication specified. Either access_id and access_key both or bearer_token must be specified for authentication with Logicmonitor.'
171
+ end
172
+ end
172
173
  def generate_auth_string(body)
173
- timestamp = DateTime.now.strftime('%Q')
174
- hash_this = "POST#{timestamp}#{body}/log/ingest"
175
- sign_this = OpenSSL::HMAC.hexdigest(
176
- OpenSSL::Digest.new('sha256'),
177
- "#{@access_key.value}",
178
- hash_this
179
- )
180
- signature = Base64.strict_encode64(sign_this)
181
- "LMv1 #{@access_id}:#{signature}:#{timestamp}"
174
+ if @use_bearer_instead_of_lmv1
175
+ return "Bearer #{@bearer_token.value}"
176
+ else
177
+ timestamp = DateTime.now.strftime('%Q')
178
+ hash_this = "POST#{timestamp}#{body}/log/ingest"
179
+ sign_this = OpenSSL::HMAC.hexdigest(
180
+ OpenSSL::Digest.new('sha256'),
181
+ "#{@access_key.value}",
182
+ hash_this
183
+ )
184
+ signature = Base64.strict_encode64(sign_this)
185
+ return "LMv1 #{@access_id}:#{signature}:#{timestamp}"
186
+ end
182
187
  end
183
188
 
184
189
  def send_batch(events)
185
- log_debug("Started sending logs to LM: ",
190
+ log_debug("Started sending logs to LM: ",
186
191
  :time => Time::now.utc)
187
192
  url = "https://" + @portal_name + ".logicmonitor.com/rest/log/ingest"
188
193
  body = events.to_json
@@ -249,7 +254,7 @@ class LogStash::Outputs::LMLogs < LogStash::Outputs::Base
249
254
  elsif debug
250
255
  @logger.debug(message, *opts)
251
256
  end
252
- end
257
+ end
253
258
 
254
259
  public
255
260
  def multi_receive(events)
@@ -268,7 +273,7 @@ class LogStash::Outputs::LMLogs < LogStash::Outputs::Base
268
273
  lmlogs_event.delete("@timestamp") # remove redundant timestamp field
269
274
  if lmlogs_event.dig("event", "original") != nil
270
275
  lmlogs_event["event"].delete("original") # remove redundant log field
271
- end
276
+ end
272
277
  end
273
278
 
274
279
  lmlogs_event["message"] = event.get(@message_key).to_s
@@ -278,7 +283,7 @@ class LogStash::Outputs::LMLogs < LogStash::Outputs::Base
278
283
  if @keep_timestamp
279
284
  lmlogs_event["timestamp"] = event.get("@timestamp")
280
285
  end
281
-
286
+
282
287
  if @timestamp_is_key
283
288
  lmlogs_event["timestamp"] = event.get(@timestamp_key.to_s)
284
289
  end
@@ -295,10 +300,10 @@ class LogStash::Outputs::LMLogs < LogStash::Outputs::Base
295
300
  end
296
301
 
297
302
  def isValidPayloadSize(documents,lmlogs_event,max_payload_size)
298
- if (documents.to_json.bytesize + lmlogs_event.to_json.bytesize) > max_payload_size
303
+ if (documents.to_json.bytesize + lmlogs_event.to_json.bytesize) > max_payload_size
299
304
  send_batch(documents)
300
305
  documents = []
301
-
306
+
302
307
  end
303
308
  documents.push(lmlogs_event)
304
309
  return documents
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-lmlogs'
3
- s.version = '1.2.1'
3
+ s.version = '1.3.0'
4
4
  s.licenses = ['Apache-2.0']
5
5
  s.summary = "Logstash output plugin for LM Logs"
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"
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/lmlogs"
4
+ require "logstash/event"
5
+
6
+ describe LogStash::Outputs::LMLogs do
7
+
8
+ let(:sample_lm_logs_event){{"message" => "hello this is log 1", "_lm.resourceId" => {"test.property" => "host1"}, "timestamp" => "2021-03-22T04:28:55.907121106Z"}}
9
+
10
+ def create_output_plugin_with_conf(conf)
11
+ return LogStash::Outputs::LMLogs.new(conf)
12
+ end
13
+
14
+ it "with no auth specified" do
15
+ puts "auth test"
16
+ plugin = create_output_plugin_with_conf({
17
+ "portal_name" => "localhost"
18
+ })
19
+ expect { plugin.configure_auth() }.to raise_error(LogStash::ConfigurationError)
20
+ end
21
+
22
+ it "access_key id is specified with no bearer" do
23
+ puts "auth test"
24
+ plugin = create_output_plugin_with_conf({
25
+ "portal_name" => "localhost",
26
+ "access_id" => "abcd",
27
+ "access_key" => "abcd"
28
+ })
29
+ plugin.configure_auth()
30
+ auth_string = plugin.generate_auth_string([sample_lm_logs_event])
31
+
32
+ expect(auth_string).to start_with("LMv1 abcd:")
33
+ end
34
+
35
+ it "when access id /key not specified but bearer specified" do
36
+ plugin = create_output_plugin_with_conf({
37
+ "portal_name" => "localhost",
38
+ "access_id" => "abcd",
39
+ "bearer_token" => "abcd"
40
+ })
41
+ plugin.configure_auth()
42
+ auth_string = plugin.generate_auth_string([sample_lm_logs_event])
43
+
44
+ expect(auth_string).to eq("Bearer abcd")
45
+ end
46
+
47
+ it "when access id /key bearer all specified, use lmv1" do
48
+ puts "auth test"
49
+ plugin = create_output_plugin_with_conf({
50
+ "portal_name" => "localhost",
51
+ "access_id" => "abcd",
52
+ "access_key" => "abcd",
53
+ "bearer_token" => "abcd"
54
+ })
55
+ plugin.configure_auth()
56
+ auth_string = plugin.generate_auth_string([sample_lm_logs_event])
57
+
58
+ expect(auth_string).to start_with("LMv1 abcd:")
59
+ end
60
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-lmlogs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - LogicMonitor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-23 00:00:00.000000000 Z
11
+ date: 2023-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -91,6 +91,7 @@ files:
91
91
  - README.md
92
92
  - lib/logstash/outputs/lmlogs.rb
93
93
  - logstash-output-lmlogs.gemspec
94
+ - spec/outputs/auth_spec.rb
94
95
  - spec/outputs/lmlogs_spec.rb
95
96
  homepage: https://www.logicmonitor.com
96
97
  licenses:
@@ -119,4 +120,5 @@ signing_key:
119
120
  specification_version: 4
120
121
  summary: Logstash output plugin for LM Logs
121
122
  test_files:
123
+ - spec/outputs/auth_spec.rb
122
124
  - spec/outputs/lmlogs_spec.rb