readme-metrics 0.1.0 → 0.2.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: 00a1c3d34d8c61c9fbcaacc3914ddb3e03837ce22bd3325dbabd30ba5b4c373e
4
- data.tar.gz: 34665a455715eaf423370cba89b31575dc87d53169c9bb8680f8b87a847e1704
3
+ metadata.gz: 66f7b071458adb5af02621626935bc6d9520bad8e246369a5f500f9037c3ea3b
4
+ data.tar.gz: f3d313877ae15673722a1c749a5529e971ec17491a7eef639924cf3991419c49
5
5
  SHA512:
6
- metadata.gz: '05980a5c1bbdb0b23d438f18c8fcb27f931e3781e2e41ce938dff13611bfc6b70d8c61c141f644d4eeb3b1381019a3eff38e52da2adeb223cd1761ba8b6e53e7'
7
- data.tar.gz: 0a084c22580cc59868089773b85dec83ad295c1984ac616f1ad8a947a8914130f35c19c78bf05b8945188cddbf49882391a8375581c5f5f50d0af0531e9db2ea
6
+ metadata.gz: be4ec7898257dbd67adf3e27070ea4cb1ee37b0d54d80de7ca2418356bfe3330a0fcdfa8ea3b16fed15afaa03a65ae0c58882f634385f37e76c275a2209f681d
7
+ data.tar.gz: 76323ca324090a903898b7bd0ff818097272a6270466b4ed9eb58e06897c9becc6cc47264a0e64ee81e4a5a577aa7241ebd09f4d2bda9c3027e914b512b946e9
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Track your API metrics within ReadMe.
4
4
 
5
+ [![Build](https://github.com/readmeio/metrics-sdks/workflows/ruby/badge.svg)](https://github.com/readmeio/metrics-sdks)
6
+
5
7
  [![](https://d3vv6lp55qjaqc.cloudfront.net/items/1M3C3j0I0s0j3T362344/Untitled-2.png)](https://readme.io)
6
8
 
7
9
  ## Installation
@@ -45,6 +45,10 @@ class HttpRequest
45
45
  @request.content_length.to_i
46
46
  end
47
47
 
48
+ def options?
49
+ @request.request_method == "OPTIONS"
50
+ end
51
+
48
52
  def headers
49
53
  @request
50
54
  .each_header
@@ -5,6 +5,10 @@ module Readme
5
5
  ALLOW_ONLY_ERROR = "The `allow_only` option must be an array of strings"
6
6
  BUFFER_LENGTH_ERROR = "The `buffer_length` must be an Integer"
7
7
  DEVELOPMENT_ERROR = "The `development` option must be a boolean"
8
+ LOGGER_ERROR = <<~MESSAGE
9
+ The `logger` option must be class that responds to the following messages:
10
+ :unkown, :fatal, :error, :warn, :info, :debug, :level
11
+ MESSAGE
8
12
 
9
13
  MISSING_BLOCK_ERROR = <<~MESSAGE
10
14
  Missing block argument. You must provide a block when configuring the
@@ -1,5 +1,4 @@
1
1
  require "rack"
2
- require "http_request"
3
2
  require "readme/metrics"
4
3
  require "readme/har/request_serializer"
5
4
  require "readme/har/response_serializer"
@@ -10,8 +9,8 @@ module Readme
10
9
  class Serializer
11
10
  HAR_VERSION = "1.2"
12
11
 
13
- def initialize(env, response, start_time, end_time, filter)
14
- @http_request = HttpRequest.new(env)
12
+ def initialize(request, response, start_time, end_time, filter)
13
+ @http_request = request
15
14
  @response = response
16
15
  @start_time = start_time
17
16
  @end_time = end_time
@@ -4,7 +4,9 @@ require "readme/filter"
4
4
  require "readme/payload"
5
5
  require "readme/request_queue"
6
6
  require "readme/errors"
7
+ require "http_request"
7
8
  require "httparty"
9
+ require "logger"
8
10
 
9
11
  module Readme
10
12
  class Metrics
@@ -13,6 +15,10 @@ module Readme
13
15
  ENDPOINT = "https://metrics.readme.io/v1/request"
14
16
  USER_INFO_KEYS = [:id, :label, :email]
15
17
 
18
+ def self.logger
19
+ @@logger
20
+ end
21
+
16
22
  def initialize(app, options, &get_user_info)
17
23
  validate_options(options)
18
24
  raise Errors::ConfigurationError, Errors::MISSING_BLOCK_ERROR if get_user_info.nil?
@@ -27,32 +33,46 @@ module Readme
27
33
 
28
34
  buffer_length = options[:buffer_length] || DEFAULT_BUFFER_LENGTH
29
35
  @@request_queue = Readme::RequestQueue.new(options[:api_key], buffer_length)
36
+ @@logger = options[:logger] || Logger.new($stdout)
30
37
  end
31
38
 
32
39
  def call(env)
33
40
  start_time = Time.now
34
41
  status, headers, body = @app.call(env)
35
42
  end_time = Time.now
36
-
37
43
  response = Rack::Response.new(body, status, headers)
38
44
 
39
- har = Har::Serializer.new(env, response, start_time, end_time, @filter)
45
+ begin
46
+ process_response(
47
+ response: response,
48
+ env: env,
49
+ start_time: start_time,
50
+ end_time: end_time
51
+ )
52
+ rescue
53
+ [status, headers, body]
54
+ end
55
+
56
+ [status, headers, body]
57
+ end
58
+
59
+ private
40
60
 
61
+ def process_response(response:, env:, start_time:, end_time:)
62
+ request = HttpRequest.new(env)
63
+ har = Har::Serializer.new(request, response, start_time, end_time, @filter)
41
64
  user_info = @get_user_info.call(env)
42
65
 
43
66
  if user_info_invalid?(user_info)
44
- puts Errors.bad_block_message(user_info)
45
- return [status, headers, body]
67
+ Readme::Metrics.logger.error Errors.bad_block_message(user_info)
68
+ elsif request.options?
69
+ Readme::Metrics.logger.info "OPTIONS request omitted from ReadMe API logging"
46
70
  else
47
71
  payload = Payload.new(har, user_info, development: @development)
48
72
  @@request_queue.push(payload.to_json)
49
73
  end
50
-
51
- [status, headers, body]
52
74
  end
53
75
 
54
- private
55
-
56
76
  def validate_options(options)
57
77
  raise Errors::ConfigurationError, Errors::API_KEY_ERROR if options[:api_key].nil?
58
78
 
@@ -71,6 +91,21 @@ module Readme
71
91
  if options[:development] && !is_a_boolean?(options[:development])
72
92
  raise Errors::ConfigurationError, Errors::DEVELOPMENT_ERROR
73
93
  end
94
+
95
+ if options[:logger] && has_logger_inferface?(options[:logger])
96
+ raise Errors::ConfigurationError, Errors::LOGGER_ERROR
97
+ end
98
+ end
99
+
100
+ def has_logger_inferface?(logger)
101
+ [
102
+ :unknown,
103
+ :fatal,
104
+ :error,
105
+ :warn,
106
+ :info,
107
+ :debug
108
+ ].any? { |message| !logger.respond_to? message }
74
109
  end
75
110
 
76
111
  def is_a_boolean?(arg)
@@ -1,5 +1,5 @@
1
1
  module Readme
2
2
  class Metrics
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -2,19 +2,32 @@ require "readme/metrics"
2
2
 
3
3
  module Readme
4
4
  class RequestQueue
5
- attr_reader :queue
6
-
7
5
  def initialize(api_key, buffer_length)
8
6
  @queue = []
9
7
  @buffer_length = buffer_length
10
8
  @api_key = api_key
9
+ @lock = Mutex.new
11
10
  end
12
11
 
13
12
  def push(request)
14
- @queue << request
13
+ @lock.synchronize do
14
+ @queue << request
15
+
16
+ if ready_to_send?
17
+ payloads = @queue.slice!(0, @buffer_length)
18
+ send_payloads(payloads)
19
+ end
20
+ end
21
+ end
22
+
23
+ def length
24
+ @queue.length
25
+ end
26
+
27
+ private
15
28
 
16
- if ready_to_send?
17
- payloads = @queue.slice!(0, @buffer_length)
29
+ def send_payloads(payloads)
30
+ Thread.new do
18
31
  HTTParty.post(
19
32
  Readme::Metrics::ENDPOINT,
20
33
  basic_auth: {username: @api_key, password: ""},
@@ -24,10 +37,8 @@ module Readme
24
37
  end
25
38
  end
26
39
 
27
- private
28
-
29
40
  def ready_to_send?
30
- @queue.length >= @buffer_length
41
+ length >= @buffer_length
31
42
  end
32
43
 
33
44
  def to_json(payloads)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: readme-metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ReadMe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-20 00:00:00.000000000 Z
11
+ date: 2020-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty