logstash-input-signalsciences 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef2ac72345f4918d2c16f7d0a72e256a8ec06ce4
4
- data.tar.gz: 6999e82e6d7e4d86b130fb971c93bcaa2dffc645
3
+ metadata.gz: 49e1f0ae15ed2dc2b8d8fb079c3d6de416b3d7fc
4
+ data.tar.gz: 011cc2201fc62fea29b465e22f73b5203205e055
5
5
  SHA512:
6
- metadata.gz: 7add1bc93c67072363afac43d244840b5743b8ba4d9b9bd3b0471fb0e89efa403a128e0b5462398f6925b1f72706059b891c6b582d85750b79961db2b9760e6d
7
- data.tar.gz: e4ddf8193986d9637e812f5b5c35439227fae81886c50a3433f7d6f496dd2ffc6dc8f9ab2a7261dc0b12788f5ac22d2b9b52433c90cae7986529d1578bea5fe4
6
+ metadata.gz: f6a2fb3ac45c9b8435bea206baa4b40306deaa069dd471cdb7aeadba859cab51a25fc89dcfc7bb74d4718ef932b71b73ba1e0f28a7943e62993b21436ddc83ce
7
+ data.tar.gz: c2c8c28854869195dcb9ec9a02b2c1bb08af6307cbd105149f1cf089181f35011e28d659b2aa6127835fcb16662b168990425b8320cc0946a64c53c480b74e00
@@ -19,7 +19,9 @@ class LogStash::Inputs::Signalsciences < LogStash::Inputs::Base
19
19
  # Signal Sciences API account username.
20
20
  config :email, :validate => :string, :default => "nobody@signalsciences.com"
21
21
  # Signal Sciences API password.
22
- config :password, :validate => :string, :default => "nobody"
22
+ config :password, :validate => :string, :default => ""
23
+ # Signal Sciences API access token.
24
+ config :token, :validate => :string, :default => ""
23
25
  # Corp and site to pull data from.
24
26
  config :corp, :validate => :string, :default => "not_provided"
25
27
  config :site, :validate => :string, :default => "not_provided"
@@ -37,9 +39,15 @@ class LogStash::Inputs::Signalsciences < LogStash::Inputs::Base
37
39
  @http = Net::HTTP.new('dashboard.signalsciences.net', 443)
38
40
  @http.set_debug_output($stdout) if @debug
39
41
  @login = Net::HTTP::Post.new("/api/v0/auth")
42
+ @auth_mode = "password"
40
43
  @get = Net::HTTP::Get.new("/api/v0/corps/#{@corp}/sites/#{@site}/feed/requests")
41
44
  @http.use_ssl = true
42
45
 
46
+ # determine authentication mode
47
+ if @token != ""
48
+ @auth_mode = "token"
49
+ end
50
+
43
51
  # check if from value is less than 1 min
44
52
  if @from < 60
45
53
  @logger.warn("from value is less than 1 min, increasing from value to 1 minute.")
@@ -56,7 +64,7 @@ class LogStash::Inputs::Signalsciences < LogStash::Inputs::Base
56
64
  @interval = @from
57
65
 
58
66
  # set version for UA string
59
- @version = "0.3.1"
67
+ @version = "1.0.0"
60
68
 
61
69
  @logger.info("Fetching Signal Sciences request data every #{@interval / 60} minutes.")
62
70
  end # def register
@@ -64,8 +72,10 @@ class LogStash::Inputs::Signalsciences < LogStash::Inputs::Base
64
72
  def run(queue)
65
73
  # we can abort the loop if stop? becomes true
66
74
  while !stop?
67
- @login['User-Agent'] = "logstash-signalsciences/#{@version}"
68
- @login.body = URI.encode_www_form({"email" => @email, "password" => @password})
75
+ if @auth_mode == "password"
76
+ @login['User-Agent'] = "logstash-signalsciences/#{@version}"
77
+ @login.body = URI.encode_www_form({"email" => @email, "password" => @password})
78
+ end
69
79
 
70
80
  if fetch(queue)
71
81
  @logger.info("Requests feed retreived successfully.")
@@ -84,112 +94,142 @@ class LogStash::Inputs::Signalsciences < LogStash::Inputs::Base
84
94
  end # def run
85
95
 
86
96
  def fetch(queue)
87
- begin
88
- response = @http.request(@login)
89
- @logger.warn("login response: #{response.code}")
90
- rescue
91
- @logger.warn("Could not reach API endpoint to login!")
92
- return false
97
+ if @auth_mode == "password"
98
+ begin
99
+ response = @http.request(@login)
100
+ @logger.warn("login response: #{response.code}")
101
+ rescue
102
+ @logger.warn("Could not reach API endpoint to login!")
103
+ return false
104
+ end
105
+
106
+ json = JSON.parse(response.body)
107
+
108
+ if json.has_key? "message"
109
+ # failed to login
110
+ @logger.warn("login: #{json['message']}")
111
+ return false
112
+ end
113
+
114
+ bearer_token = json['token']
93
115
  end
94
116
 
95
- json = JSON.parse(response.body)
117
+
118
+ # Both the from and until parameters must fall on full minute boundaries,
119
+ # see https://docs.signalsciences.net/faq/extract-your-data/.
120
+ t = Time.now.utc.strftime("%Y-%m-%d %H:%M:0")
121
+ dt = DateTime.parse(t)
122
+ timestamp_until = dt.to_time.to_i - 300 # now - 5 minutes
123
+ timestamp_from = (timestamp_until - @from) # @until - @from
124
+
125
+ if @debug
126
+ hfrom = Time.at(timestamp_from).to_datetime
127
+ huntil = Time.at(timestamp_until).to_datetime
128
+ @logger.info("From #{hfrom} Until #{huntil}")
129
+ end
96
130
 
97
- if json.has_key? "message"
98
- # failed to login
99
- @logger.warn("login: #{json['message']}")
100
- return false
131
+ # Set up iniital get request and initial next_uri
132
+ @logger.info("Requesting data: /api/v0/corps/#{@corp}/sites/#{@site}/feed/requests?from=#{timestamp_from}&until=#{timestamp_until}")
133
+ get = Net::HTTP::Get.new("/api/v0/corps/#{@corp}/sites/#{@site}/feed/requests?from=#{timestamp_from}&until=#{timestamp_until}")
134
+ next_uri = "not empty on first pass"
101
135
 
102
- else
103
- token = json['token']
104
- # Both the from and until parameters must fall on full minute boundaries,
105
- # see https://docs.signalsciences.net/faq/extract-your-data/.
106
- t = Time.now.utc.strftime("%Y-%m-%d %H:%M:0")
107
- dt = DateTime.parse(t)
108
- timestamp_until = dt.to_time.to_i - 300 # now - 5 minutes
109
- timestamp_from = (timestamp_until - @from) # @until - @from
136
+ # Loop through results until next_uri is empty.
137
+ while !next_uri.empty?
138
+ if @auth_mode == "password"
139
+ get["Authorization"] = "Bearer #{bearer_token}"
140
+ else
141
+ get["x-api-user"] = @email
142
+ get["x-api-token"] = @token
143
+ end
144
+ get['User-Agent'] = "logstash-signalsciences/#{@version}"
110
145
 
111
- if @debug
112
- hfrom = Time.at(timestamp_from).to_datetime
113
- huntil = Time.at(timestamp_until).to_datetime
114
- @logger.info("From #{hfrom} Until #{huntil}")
146
+ begin
147
+ response = @http.request(get)
148
+ rescue
149
+ @logger.warn("Could not reach API endpoint to retreive reqeusts feed!")
150
+ return false
151
+ end
152
+
153
+ if response.code == "524"
154
+ @logger.warn("524 - Origin Timeout!")
155
+ @logger.info("Another attempt will be made later.")
156
+ return false
157
+ end
158
+
159
+ if response.code == "429"
160
+ @logger.warn("429 - Too Many Requests!")
161
+ @logger.info("API request throttling as been triggered, another attempt will be made later. Contact support if this error continues.")
162
+ return false
163
+ end
164
+
165
+ if response.code == "404"
166
+ @logger.warn("404 - Not Found!")
167
+ return false
115
168
  end
116
169
 
117
- # Set up iniital get request and initial next_uri
118
- @logger.info("Requesting data: /api/v0/corps/#{@corp}/sites/#{@site}/feed/requests?from=#{timestamp_from}&until=#{timestamp_until}")
119
- get = Net::HTTP::Get.new("/api/v0/corps/#{@corp}/sites/#{@site}/feed/requests?from=#{timestamp_from}&until=#{timestamp_until}")
120
- next_uri = "not empty on first pass"
170
+ if response.code == "401"
171
+ @logger.warn("401 - Unauthorized!")
172
+ return false
173
+ end
174
+
175
+ json = JSON.parse(response.body)
121
176
 
122
- # Loop through results until next_uri is empty.
123
- while !next_uri.empty?
124
- get["Authorization"] = "Bearer #{token}"
125
- get['User-Agent'] = "logstash-signalsciences/#{@version}"
177
+ #check for message, error, e.g. missing query string parameter
178
+ if json.has_key? "message"
179
+ # some error occured, report it.
180
+ @logger.warn("Error accessing API (auth mode: #{@auth_mode}), status code: #{response.code} with message: #{json['message']}")
181
+ return false
182
+ end
126
183
 
184
+ # log json payloads
185
+ json['data'].each do |payload|
186
+
187
+ # explode headersIn out to headerIn entries
188
+ temp = {}
127
189
  begin
128
- response = @http.request(get)
129
- rescue
130
- @logger.warn("Could not reach API endpoint to retreive reqeusts feed!")
131
- return false
132
- end
133
- json = JSON.parse(response.body)
134
-
135
- #check for message, error, e.g. missing query string parameter
136
- if json.has_key? "message"
137
- # some error occured, report it.
138
- @logger.warn("Error accessing API (#{token}), status code: #{response.code} with message: #{json['message']}")
139
- return false
140
-
141
- else
142
- # log json payloads
143
- json['data'].each do |payload|
144
-
145
- # explode headersIn out to headerIn entries
146
- temp = {}
147
- begin
148
- payload['headersIn'].each { |k,v| temp[k] = v }
149
- payload["headerIn"] = temp
150
- rescue NoMethodError
151
- if @debug
152
- @logger.debug("payload['headersIn'] is empty for id #{payload['id']}, skipping append.")
153
- end
154
- end
155
-
156
- # explode headersOut out to headerOut entries
157
- temp = {}
158
- begin
159
- payload['headersOut'].each { |k,v| temp[k] = v }
160
- payload["headerOut"] = temp
161
- rescue NoMethodError
162
- if @debug
163
- @logger.info("payload['headersOut'] is empty for id #{payload['id']}, skipping append.")
164
- end
165
- end
166
-
167
- # explode tags out to tag entries
168
- temp = {}
169
- payload['tags'].each do |x|
170
- temp[x['type']] = x
171
- end
172
- payload['tag'] = temp
173
-
174
- # add the event
175
-
176
- event = LogStash::Event.new("message" => payload, "host" => @host)
177
-
178
- decorate(event)
179
- queue << event
190
+ payload['headersIn'].each { |k,v| temp[k] = v }
191
+ payload["headerIn"] = temp
192
+ rescue NoMethodError
193
+ if @debug
194
+ @logger.debug("payload['headersIn'] is empty for id #{payload['id']}, skipping append.")
180
195
  end
196
+ end
181
197
 
182
- # get the next uri value
183
- next_uri = json['next']['uri']
198
+ # explode headersOut out to headerOut entries
199
+ temp = {}
200
+ begin
201
+ payload['headersOut'].each { |k,v| temp[k] = v }
202
+ payload["headerOut"] = temp
203
+ rescue NoMethodError
184
204
  if @debug
185
- logger.info("Next URI: #{next_uri}")
205
+ @logger.info("payload['headersOut'] is empty for id #{payload['id']}, skipping append.")
186
206
  end
207
+ end
187
208
 
188
- # continue retreiving next_uri if it exists
189
- if !next_uri.empty?
190
- get = Net::HTTP::Get.new(next_uri)
191
- end
209
+ # explode tags out to tag entries
210
+ temp = {}
211
+ payload['tags'].each do |x|
212
+ temp[x['type']] = x
192
213
  end
214
+ payload['tag'] = temp
215
+
216
+ # add the event
217
+
218
+ event = LogStash::Event.new("message" => payload, "host" => @host)
219
+
220
+ decorate(event)
221
+ queue << event
222
+ end
223
+
224
+ # get the next uri value
225
+ next_uri = json['next']['uri']
226
+ if @debug
227
+ logger.info("Next URI: #{next_uri}")
228
+ end
229
+
230
+ # continue retreiving next_uri if it exists
231
+ if !next_uri.empty?
232
+ get = Net::HTTP::Get.new(next_uri)
193
233
  end
194
234
  end
195
235
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-input-signalsciences'
3
- s.version = '0.3.1'
3
+ s.version = '1.0.0'
4
4
  s.licenses = ['Apache-2.0']
5
5
  s.summary = 'Logstash input plugin for Signal Sciences.'
6
6
  s.description = 'Logstash input plugin for the Signal Sciences request feed endpoint https://docs.signalsciences.net/api/#get-request-feed'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-signalsciences
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - foospidy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-03 00:00:00.000000000 Z
11
+ date: 2020-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logstash-core-plugin-api