resurfaceio-logger 1.8.4 → 2.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
- SHA1:
3
- metadata.gz: a583801501358c56e7f049b70bb41f3695612f7a
4
- data.tar.gz: a3db5f5fad430ecadbcef92b75011ec62e478d54
2
+ SHA256:
3
+ metadata.gz: 78d67f05915dcaee82ef7e3809856549bf09d01ac1f26d32f4dcb02003d317f3
4
+ data.tar.gz: f3d3598661aed83877882554183991ef228ac92d3f875f087eafddd3221cfa59
5
5
  SHA512:
6
- metadata.gz: a65d4f79c84c6c8b3768184c205e527e67704d963e154db0f4d1b1ff3d7ab9a8c3f8f09623a19d55f5eaae194830a3e1cfb0ceffd481cbe581f76050c82ce3ab
7
- data.tar.gz: 47a2f99ed81a16fbddd0248f743a63a124a67da57f8f2ba02363cf954f563bc3039b34f06f926685ad5fb3db527fa79eb901c5af13adbe1c405e5306c1ef73f3
6
+ metadata.gz: 5aa5de88c997daddb5f345e4e41d5a173e59adb449dec141ee015747a48ef2f82a7ec623a6b1630d913f5a018f72c4aa1907e310fa1a7808f5c5c579db0281d9
7
+ data.tar.gz: e998c80806e0488c0790e551285e3ae90b7897aa7e027019ad18fd9c9794f0bb37add6d5aaeddb8eb275e66da18b3b9e21b042af636009966d9b6773f200ae88
@@ -1,13 +1,15 @@
1
1
  # coding: utf-8
2
- # © 2016-2018 Resurface Labs LLC
2
+ # © 2016-2020 Resurface Labs Inc.
3
3
 
4
4
  require 'resurfaceio/base_logger'
5
5
  require 'resurfaceio/http_logger'
6
6
  require 'resurfaceio/http_logger_for_rack'
7
7
  require 'resurfaceio/http_logger_for_rails'
8
- require 'resurfaceio/http_message_impl'
8
+ require 'resurfaceio/http_message'
9
9
  require 'resurfaceio/http_request_impl'
10
10
  require 'resurfaceio/http_response_impl'
11
+ require 'resurfaceio/http_rule'
12
+ require 'resurfaceio/http_rules'
11
13
  require 'resurfaceio/usage_loggers'
12
14
 
13
15
  module Resurfaceio
@@ -24,7 +26,7 @@ module Resurfaceio
24
26
  class HttpLoggerForRails < HttpLoggerForRails
25
27
  end
26
28
 
27
- class HttpMessageImpl < HttpMessageImpl
29
+ class HttpMessage < HttpMessage
28
30
  end
29
31
 
30
32
  class HttpRequestImpl < HttpRequestImpl
@@ -33,6 +35,12 @@ module Resurfaceio
33
35
  class HttpResponseImpl < HttpResponseImpl
34
36
  end
35
37
 
38
+ class HttpRule < HttpRule
39
+ end
40
+
41
+ class HttpRules < HttpRules
42
+ end
43
+
36
44
  class UsageLoggers < UsageLoggers
37
45
  end
38
46
 
@@ -1,9 +1,10 @@
1
1
  # coding: utf-8
2
- # © 2016-2018 Resurface Labs LLC
2
+ # © 2016-2020 Resurface Labs Inc.
3
3
 
4
4
  require 'uri'
5
5
  require 'net/http'
6
6
  require 'net/https'
7
+ require 'socket'
7
8
  require 'zlib'
8
9
  require 'resurfaceio/usage_loggers'
9
10
 
@@ -11,6 +12,7 @@ class BaseLogger
11
12
 
12
13
  def initialize(agent, options = {})
13
14
  @agent = agent
15
+ @host = BaseLogger.host_lookup
14
16
  @skip_compression = false
15
17
  @skip_submission = false
16
18
  @version = BaseLogger.version_lookup
@@ -49,7 +51,12 @@ class BaseLogger
49
51
  end
50
52
  end
51
53
 
54
+ # finalize internal properties
52
55
  @enableable = !@queue.nil? || !@url.nil?
56
+ @submit_failures = 0
57
+ @submit_failures_lock = Mutex.new
58
+ @submit_successes = 0
59
+ @submit_successes_lock = Mutex.new
53
60
  end
54
61
 
55
62
  def agent
@@ -74,6 +81,14 @@ class BaseLogger
74
81
  @enabled && UsageLoggers.enabled?
75
82
  end
76
83
 
84
+ def host
85
+ @host
86
+ end
87
+
88
+ def queue
89
+ @queue
90
+ end
91
+
77
92
  def skip_compression?
78
93
  @skip_compression
79
94
  end
@@ -90,12 +105,12 @@ class BaseLogger
90
105
  @skip_submission = value
91
106
  end
92
107
 
93
- def submit(json)
94
- if @skip_submission || !enabled?
95
- true
108
+ def submit(msg)
109
+ if msg.nil? || @skip_submission || !enabled?
110
+ # do nothing
96
111
  elsif @queue
97
- @queue << json
98
- true
112
+ @queue << msg
113
+ @submit_successes_lock.synchronize { @submit_successes += 1 }
99
114
  else
100
115
  begin
101
116
  @url_parsed ||= URI.parse(@url)
@@ -103,20 +118,32 @@ class BaseLogger
103
118
  @url_connection.use_ssl = @url.include?('https')
104
119
  request = Net::HTTP::Post.new(@url_parsed.path)
105
120
  if @skip_compression
106
- request.body = json
121
+ request.body = msg
107
122
  else
108
123
  request.add_field('Content-Encoding', 'deflated')
109
- request.body = Zlib::Deflate.deflate(json)
124
+ request.body = Zlib::Deflate.deflate(msg)
110
125
  end
111
126
  response = @url_connection.request(request)
112
- response.code.to_i == 204
127
+ if response.code.to_i == 204
128
+ @submit_successes_lock.synchronize { @submit_successes += 1 }
129
+ else
130
+ @submit_failures_lock.synchronize { @submit_failures += 1 }
131
+ end
113
132
  rescue SocketError
133
+ @submit_failures_lock.synchronize { @submit_failures += 1 }
114
134
  @url_connection = nil
115
- false
116
135
  end
117
136
  end
118
137
  end
119
138
 
139
+ def submit_failures
140
+ @submit_failures
141
+ end
142
+
143
+ def submit_successes
144
+ @submit_successes
145
+ end
146
+
120
147
  def url
121
148
  @url
122
149
  end
@@ -125,6 +152,16 @@ class BaseLogger
125
152
  @version
126
153
  end
127
154
 
155
+ def self.host_lookup
156
+ dyno = ENV['DYNO']
157
+ return dyno unless dyno.nil?
158
+ begin
159
+ Socket.gethostname
160
+ rescue
161
+ 'unknown'
162
+ end
163
+ end
164
+
128
165
  def self.version_lookup
129
166
  Gem.loaded_specs['resurfaceio-logger'].version.to_s
130
167
  end
@@ -1,32 +1,54 @@
1
1
  # coding: utf-8
2
- # © 2016-2018 Resurface Labs LLC
2
+ # © 2016-2020 Resurface Labs Inc.
3
3
 
4
4
  require 'json'
5
5
  require 'resurfaceio/base_logger'
6
- require 'resurfaceio/http_message_impl'
6
+ require 'resurfaceio/http_message'
7
+ require 'resurfaceio/http_rule'
8
+ require 'resurfaceio/http_rules'
7
9
 
8
10
  class HttpLogger < BaseLogger
9
11
 
10
12
  AGENT = 'http_logger.rb'.freeze
11
13
 
12
- def self.string_content_type?(s)
13
- !s.nil? && !(s =~ /^(text\/(html|plain|xml))|(application\/(json|soap|xml|x-www-form-urlencoded))/i).nil?
14
- end
15
-
16
14
  def initialize(options = {})
17
15
  super(AGENT, options)
16
+
17
+ # parse specified rules
18
+ if options.respond_to?(:has_key?) && options.has_key?(:rules)
19
+ @rules = HttpRules.new(options[:rules])
20
+ else
21
+ @rules = HttpRules.new(nil)
22
+ end
23
+
24
+ # apply configuration rules
25
+ @skip_compression = @rules.skip_compression
26
+ @skip_submission = @rules.skip_submission
27
+ unless @url.nil? || @url.start_with?('https') || @rules.allow_http_url
28
+ @enableable = false
29
+ @enabled = false
30
+ end
18
31
  end
19
32
 
20
- def format(request, response, response_body = nil, request_body = nil, now = nil)
21
- message = HttpMessageImpl.build(request, response, response_body, request_body)
22
- message << ['agent', @agent]
23
- message << ['version', @version]
24
- message << ['now', now.nil? ? (Time.now.to_f * 1000).floor.to_s : now]
25
- JSON.generate message
33
+ def rules
34
+ @rules
26
35
  end
27
36
 
28
- def log(request, response, response_body = nil, request_body = nil)
29
- !enabled? || submit(format(request, response, response_body, request_body))
37
+ def submit_if_passing(details)
38
+ # apply active rules
39
+ details = @rules.apply(details)
40
+ return nil if details.nil?
41
+
42
+ # finalize message
43
+ details << ['agent', @agent]
44
+ details << ['host', @host]
45
+ details << ['version', @version]
46
+
47
+ # let's do this thing
48
+ submit(JSON.generate(details))
30
49
  end
31
50
 
51
+ def self.string_content_type?(s)
52
+ !s.nil? && !(s =~ /^(text\/(html|plain|xml))|(application\/(json|soap|xml|x-www-form-urlencoded))/i).nil?
53
+ end
32
54
  end
@@ -1,8 +1,9 @@
1
1
  # coding: utf-8
2
- # © 2016-2018 Resurface Labs LLC
2
+ # © 2016-2020 Resurface Labs Inc.
3
3
 
4
4
  require 'rack'
5
5
  require 'resurfaceio/http_logger'
6
+ require 'resurfaceio/http_message'
6
7
 
7
8
  class HttpLoggerForRack # http://rack.rubyforge.org/doc/SPEC.html
8
9
 
@@ -21,8 +22,7 @@ class HttpLoggerForRack # http://rack.rubyforge.org/doc/SPEC.html
21
22
  response = Rack::Response.new(body, status, headers)
22
23
  if HttpLogger::string_content_type?(response.content_type)
23
24
  request = Rack::Request.new(env)
24
- message = @logger.format(request, response)
25
- @logger.submit(message)
25
+ HttpMessage.send(logger, request, response) # todo add timing details
26
26
  end
27
27
  end
28
28
  [status, headers, body]
@@ -1,7 +1,8 @@
1
1
  # coding: utf-8
2
- # © 2016-2018 Resurface Labs LLC
2
+ # © 2016-2020 Resurface Labs Inc.
3
3
 
4
4
  require 'resurfaceio/http_logger'
5
+ require 'resurfaceio/http_message'
5
6
 
6
7
  class HttpLoggerForRails
7
8
 
@@ -20,8 +21,7 @@ class HttpLoggerForRails
20
21
  response = controller.response
21
22
  status = response.status
22
23
  if (status < 300 || status == 302) && HttpLogger::string_content_type?(response.content_type)
23
- message = @logger.format(request, response)
24
- @logger.submit(message)
24
+ HttpMessage.send(logger, request, response) # todo add timing details
25
25
  end
26
26
  end
27
27
  end
@@ -1,15 +1,38 @@
1
1
  # coding: utf-8
2
- # © 2016-2018 Resurface Labs LLC
2
+ # © 2016-2020 Resurface Labs Inc.
3
3
 
4
4
  require 'json'
5
5
 
6
- class HttpMessageImpl
6
+ class HttpMessage
7
+
8
+ def self.send(logger, request, response, response_body = nil, request_body = nil, now = nil, interval = nil)
9
+ return unless logger.enabled?
10
+
11
+ # copy details from request & response
12
+ message = build(request, response, response_body, request_body)
13
+
14
+ # copy details from active session
15
+ unless logger.rules.copy_session_field.empty?
16
+ ssn = request.session
17
+ if !ssn.nil? && ssn.respond_to?(:keys)
18
+ logger.rules.copy_session_field.each do |r|
19
+ ssn.keys.each {|d| (message << ["session_field:#{d}", ssn[d].to_s]) if r.param1.match(d)}
20
+ end
21
+ end
22
+ end
23
+
24
+ # add timing details
25
+ message << ['now', now.nil? ? (Time.now.to_f * 1000).floor.to_s : now]
26
+ message << ['interval', interval] unless interval.nil?
27
+
28
+ logger.submit_if_passing(message)
29
+ end
7
30
 
8
31
  def self.build(request, response, response_body = nil, request_body = nil)
9
32
  message = []
10
- append_value message, 'request_method', request.request_method
11
- append_value message, 'request_url', request.url
12
- append_value message, 'response_code', response.status
33
+ append_value message, 'request_method', request.request_method unless request.request_method.nil?
34
+ append_value message, 'request_url', request.url unless request.url.nil?
35
+ append_value message, 'response_code', response.status unless response.status.nil?
13
36
  append_request_headers message, request
14
37
  append_request_params message, request
15
38
  append_response_headers message, response
@@ -19,8 +42,6 @@ class HttpMessageImpl
19
42
  return message
20
43
  end
21
44
 
22
- protected
23
-
24
45
  def self.append_request_headers(message, request)
25
46
  respond_to_env = request.respond_to?(:env)
26
47
  if respond_to_env || request.respond_to?(:headers)
@@ -74,12 +95,12 @@ class HttpMessageImpl
74
95
  unless key.nil?
75
96
  unless value.nil?
76
97
  case value
77
- when Array
78
- message << [key, value.join]
79
- when String
80
- message << [key, value]
81
- else
82
- message << [key, value.to_s]
98
+ when Array
99
+ message << [key, value.join]
100
+ when String
101
+ message << [key, value]
102
+ else
103
+ message << [key, value.to_s]
83
104
  end
84
105
  end
85
106
  end
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- # © 2016-2018 Resurface Labs LLC
2
+ # © 2016-2020 Resurface Labs Inc.
3
3
 
4
4
  class HttpRequestImpl
5
5
 
@@ -7,6 +7,7 @@ class HttpRequestImpl
7
7
  @form_hash = Hash.new
8
8
  @headers = Hash.new
9
9
  @query_hash = Hash.new
10
+ @session = Hash.new
10
11
  end
11
12
 
12
13
  def add_header(key, value)
@@ -40,6 +41,10 @@ class HttpRequestImpl
40
41
  @query_hash
41
42
  end
42
43
 
44
+ def session
45
+ @session
46
+ end
47
+
43
48
  attr_accessor :request_method
44
49
  attr_accessor :url
45
50
 
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- # © 2016-2018 Resurface Labs LLC
2
+ # © 2016-2020 Resurface Labs Inc.
3
3
 
4
4
  class HttpResponseImpl
5
5
 
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+ # © 2016-2020 Resurface Labs Inc.
3
+
4
+ class HttpRule
5
+
6
+ def initialize(verb, scope = nil, param1 = nil, param2 = nil)
7
+ @verb = verb
8
+ @scope = scope
9
+ @param1 = param1
10
+ @param2 = param2
11
+ end
12
+
13
+ attr_reader :verb, :scope, :param1, :param2
14
+
15
+ end
@@ -0,0 +1,278 @@
1
+ # coding: utf-8
2
+ # © 2016-2020 Resurface Labs Inc.
3
+
4
+ class HttpRules
5
+
6
+ DEBUG_RULES = "allow_http_url\ncopy_session_field /.*/\n".freeze
7
+
8
+ STANDARD_RULES = %q(/request_header:cookie|response_header:set-cookie/ remove
9
+ /(request|response)_body|request_param/ replace /[a-zA-Z0-9.!#$%&’*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)/, /x@y.com/
10
+ /request_body|request_param|response_body/ replace /[0-9\.\-\/]{9,}/, /xyxy/
11
+ ).freeze
12
+
13
+ STRICT_RULES = %q(/request_url/ replace /([^\?;]+).*/, !\\\\1!
14
+ /request_body|response_body|request_param:.*|request_header:(?!user-agent).*|response_header:(?!(content-length)|(content-type)).*/ remove
15
+ ).freeze
16
+
17
+ @@default_rules = STRICT_RULES
18
+
19
+ def self.default_rules
20
+ @@default_rules
21
+ end
22
+
23
+ def self.default_rules=(val)
24
+ @@default_rules = val.gsub(/^\s*include default\s*$/, '')
25
+ end
26
+
27
+ def self.debug_rules
28
+ DEBUG_RULES
29
+ end
30
+
31
+ def self.standard_rules
32
+ STANDARD_RULES
33
+ end
34
+
35
+ def self.strict_rules
36
+ STRICT_RULES
37
+ end
38
+
39
+ def self.parse_rule(r)
40
+ if r.nil? || r.match(REGEX_BLANK_OR_COMMENT)
41
+ nil
42
+ elsif r.match(REGEX_ALLOW_HTTP_URL)
43
+ HttpRule.new('allow_http_url')
44
+ elsif (m = r.match(REGEX_COPY_SESSION_FIELD))
45
+ HttpRule.new('copy_session_field', nil, parse_regex(r, m[1]))
46
+ elsif (m = r.match(REGEX_REMOVE))
47
+ HttpRule.new('remove', parse_regex(r, m[1]))
48
+ elsif (m = r.match(REGEX_REMOVE_IF))
49
+ HttpRule.new('remove_if', parse_regex(r, m[1]), parse_regex(r, m[2]))
50
+ elsif (m = r.match(REGEX_REMOVE_IF_FOUND))
51
+ HttpRule.new('remove_if_found', parse_regex(r, m[1]), parse_regex_find(r, m[2]))
52
+ elsif (m = r.match(REGEX_REMOVE_UNLESS))
53
+ HttpRule.new('remove_unless', parse_regex(r, m[1]), parse_regex(r, m[2]))
54
+ elsif (m = r.match(REGEX_REMOVE_UNLESS_FOUND))
55
+ HttpRule.new('remove_unless_found', parse_regex(r, m[1]), parse_regex_find(r, m[2]))
56
+ elsif (m = r.match(REGEX_REPLACE))
57
+ HttpRule.new('replace', parse_regex(r, m[1]), parse_regex_find(r, m[2]), parse_string(r, m[3]))
58
+ elsif (m = r.match(REGEX_SAMPLE))
59
+ m1 = m[1].to_i
60
+ raise RuntimeError.new("Invalid sample percent: #{m1}") if m1 < 1 || m1 > 99
61
+ HttpRule.new('sample', nil, m1)
62
+ elsif r.match(REGEX_SKIP_COMPRESSION)
63
+ HttpRule.new('skip_compression')
64
+ elsif r.match(REGEX_SKIP_SUBMISSION)
65
+ HttpRule.new('skip_submission')
66
+ elsif (m = r.match(REGEX_STOP))
67
+ HttpRule.new('stop', parse_regex(r, m[1]))
68
+ elsif (m = r.match(REGEX_STOP_IF))
69
+ HttpRule.new('stop_if', parse_regex(r, m[1]), parse_regex(r, m[2]))
70
+ elsif (m = r.match(REGEX_STOP_IF_FOUND))
71
+ HttpRule.new('stop_if_found', parse_regex(r, m[1]), parse_regex_find(r, m[2]))
72
+ elsif (m = r.match(REGEX_STOP_UNLESS))
73
+ HttpRule.new('stop_unless', parse_regex(r, m[1]), parse_regex(r, m[2]))
74
+ elsif (m = r.match(REGEX_STOP_UNLESS_FOUND))
75
+ HttpRule.new('stop_unless_found', parse_regex(r, m[1]), parse_regex_find(r, m[2]))
76
+ else
77
+ raise RuntimeError.new("Invalid rule: #{r}")
78
+ end
79
+ end
80
+
81
+ def self.parse_regex(r, regex)
82
+ s = parse_string(r, regex)
83
+ raise RuntimeError.new("Invalid regex (#{regex}) in rule: #{r}") if '*' == s || '+' == s || '?' == s
84
+ s = "^#{s}" unless s.start_with?('^')
85
+ s = "#{s}$" unless s.end_with?('$')
86
+ begin
87
+ return Regexp.compile(s)
88
+ rescue RegexpError
89
+ raise RuntimeError.new("Invalid regex (#{regex}) in rule: #{r}")
90
+ end
91
+ end
92
+
93
+ def self.parse_regex_find(r, regex)
94
+ begin
95
+ return Regexp.compile(parse_string(r, regex))
96
+ rescue RegexpError
97
+ raise RuntimeError.new("Invalid regex (#{regex}) in rule: #{r}")
98
+ end
99
+ end
100
+
101
+ def self.parse_string(r, expr)
102
+ %w(~ ! % | /).each do |sep|
103
+ if (m = expr.match(/^[#{sep}](.*)[#{sep}]$/))
104
+ m1 = m[1]
105
+ raise RuntimeError.new("Unescaped separator (#{sep}) in rule: #{r}") if m1.match(/^[#{sep}].*|.*[^\\][#{sep}].*/)
106
+ return m1.gsub("\\#{sep}", sep)
107
+ end
108
+ end
109
+ raise RuntimeError.new("Invalid expression (#{expr}) in rule: #{r}")
110
+ end
111
+
112
+ def initialize(rules)
113
+ rules = HttpRules.default_rules if rules.nil?
114
+
115
+ # todo load rules from external files
116
+
117
+ # force default rules if necessary
118
+ rules = rules.gsub(/^\s*include default\s*$/, HttpRules.default_rules)
119
+ rules = HttpRules.default_rules unless rules.strip.length > 0
120
+
121
+ # expand rule inclues
122
+ rules = rules.gsub(/^\s*include debug\s*$/, DEBUG_RULES)
123
+ rules = rules.gsub(/^\s*include standard\s*$/, STANDARD_RULES)
124
+ rules = rules.gsub(/^\s*include strict\s*$/, STRICT_RULES)
125
+ @text = rules
126
+
127
+ # parse all rules
128
+ prs = []
129
+ rules.each_line do |rule|
130
+ parsed = HttpRules.parse_rule(rule)
131
+ prs << parsed unless parsed.nil?
132
+ end
133
+ @length = prs.length
134
+
135
+ # break out rules by verb
136
+ @allow_http_url = prs.select {|r| 'allow_http_url' == r.verb}.length > 0
137
+ @copy_session_field = prs.select {|r| 'copy_session_field' == r.verb}
138
+ @remove = prs.select {|r| 'remove' == r.verb}
139
+ @remove_if = prs.select {|r| 'remove_if' == r.verb}
140
+ @remove_if_found = prs.select {|r| 'remove_if_found' == r.verb}
141
+ @remove_unless = prs.select {|r| 'remove_unless' == r.verb}
142
+ @remove_unless_found = prs.select {|r| 'remove_unless_found' == r.verb}
143
+ @replace = prs.select {|r| 'replace' == r.verb}
144
+ @sample = prs.select {|r| 'sample' == r.verb}
145
+ @skip_compression = prs.select {|r| 'skip_compression' == r.verb}.length > 0
146
+ @skip_submission = prs.select {|r| 'skip_submission' == r.verb}.length > 0
147
+ @stop = prs.select {|r| 'stop' == r.verb}
148
+ @stop_if = prs.select {|r| 'stop_if' == r.verb}
149
+ @stop_if_found = prs.select {|r| 'stop_if_found' == r.verb}
150
+ @stop_unless = prs.select {|r| 'stop_unless' == r.verb}
151
+ @stop_unless_found = prs.select {|r| 'stop_unless_found' == r.verb}
152
+
153
+ # validate rules
154
+ raise RuntimeError.new('Multiple sample rules') if @sample.length > 1
155
+ end
156
+
157
+ def allow_http_url
158
+ @allow_http_url
159
+ end
160
+
161
+ def copy_session_field
162
+ @copy_session_field
163
+ end
164
+
165
+ def length
166
+ @length
167
+ end
168
+
169
+ def remove
170
+ @remove
171
+ end
172
+
173
+ def remove_if
174
+ @remove_if
175
+ end
176
+
177
+ def remove_if_found
178
+ @remove_if_found
179
+ end
180
+
181
+ def remove_unless
182
+ @remove_unless
183
+ end
184
+
185
+ def remove_unless_found
186
+ @remove_unless_found
187
+ end
188
+
189
+ def replace
190
+ @replace
191
+ end
192
+
193
+ def sample
194
+ @sample
195
+ end
196
+
197
+ def skip_compression
198
+ @skip_compression
199
+ end
200
+
201
+ def skip_submission
202
+ @skip_submission
203
+ end
204
+
205
+ def stop
206
+ @stop
207
+ end
208
+
209
+ def stop_if
210
+ @stop_if
211
+ end
212
+
213
+ def stop_if_found
214
+ @stop_if_found
215
+ end
216
+
217
+ def stop_unless
218
+ @stop_unless
219
+ end
220
+
221
+ def stop_unless_found
222
+ @stop_unless_found
223
+ end
224
+
225
+ def text
226
+ @text
227
+ end
228
+
229
+ def apply(details)
230
+ # stop rules come first
231
+ @stop.each {|r| details.each {|d| return nil if r.scope.match(d[0])}}
232
+ @stop_if_found.each {|r| details.each {|d| return nil if r.scope.match(d[0]) && r.param1.match(d[1])}}
233
+ @stop_if.each {|r| details.each {|d| return nil if r.scope.match(d[0]) && r.param1.match(d[1])}}
234
+ passed = 0
235
+ @stop_unless_found.each {|r| details.each {|d| passed += 1 if r.scope.match(d[0]) && r.param1.match(d[1])}}
236
+ return nil if passed != @stop_unless_found.length
237
+ passed = 0
238
+ @stop_unless.each {|r| details.each {|d| passed += 1 if r.scope.match(d[0]) && r.param1.match(d[1])}}
239
+ return nil if passed != @stop_unless.length
240
+
241
+ # do sampling if configured
242
+ return nil if !@sample[0].nil? && (rand * 100 >= @sample[0].param1)
243
+
244
+ # winnow sensitive details based on remove rules if configured
245
+ @remove.each {|r| details.delete_if {|d| r.scope.match(d[0])}}
246
+ @remove_unless_found.each {|r| details.delete_if {|d| r.scope.match(d[0]) && !r.param1.match(d[1])}}
247
+ @remove_if_found.each {|r| details.delete_if {|d| r.scope.match(d[0]) && r.param1.match(d[1])}}
248
+ @remove_unless.each {|r| details.delete_if {|d| r.scope.match(d[0]) && !r.param1.match(d[1])}}
249
+ @remove_if.each {|r| details.delete_if {|d| r.scope.match(d[0]) && r.param1.match(d[1])}}
250
+ return nil if details.empty?
251
+
252
+ # mask sensitive details based on replace rules if configured
253
+ @replace.each {|r| details.each {|d| d[1] = d[1].gsub(r.param1, r.param2) if r.scope.match(d[0])}}
254
+
255
+ # remove any details with empty values
256
+ details.delete_if {|d| '' == d[1]}
257
+ details.empty? ? nil : details
258
+ end
259
+
260
+ REGEX_ALLOW_HTTP_URL = /^\s*allow_http_url\s*(#.*)?$/.freeze
261
+ REGEX_BLANK_OR_COMMENT = /^\s*([#].*)*$/.freeze
262
+ REGEX_COPY_SESSION_FIELD = /^\s*copy_session_field\s+([~!%|\/].+[~!%|\/])\s*(#.*)?$/.freeze
263
+ REGEX_REMOVE = /^\s*([~!%|\/].+[~!%|\/])\s*remove\s*(#.*)?$/.freeze
264
+ REGEX_REMOVE_IF = /^\s*([~!%|\/].+[~!%|\/])\s*remove_if\s+([~!%|\/].+[~!%|\/])\s*(#.*)?$/.freeze
265
+ REGEX_REMOVE_IF_FOUND = /^\s*([~!%|\/].+[~!%|\/])\s*remove_if_found\s+([~!%|\/].+[~!%|\/])\s*(#.*)?$/.freeze
266
+ REGEX_REMOVE_UNLESS = /^\s*([~!%|\/].+[~!%|\/])\s*remove_unless\s+([~!%|\/].+[~!%|\/])\s*(#.*)?$/.freeze
267
+ REGEX_REMOVE_UNLESS_FOUND = /^\s*([~!%|\/].+[~!%|\/])\s*remove_unless_found\s+([~!%|\/].+[~!%|\/])\s*(#.*)?$/.freeze
268
+ REGEX_REPLACE = /^\s*([~!%|\/].+[~!%|\/])\s*replace[\s]+([~!%|\/].+[~!%|\/]),[\s]+([~!%|\/].*[~!%|\/])\s*(#.*)?$/.freeze
269
+ REGEX_SAMPLE = /^\s*sample\s+(\d+)\s*(#.*)?$/.freeze
270
+ REGEX_SKIP_COMPRESSION = /^\s*skip_compression\s*(#.*)?$/.freeze
271
+ REGEX_SKIP_SUBMISSION = /^\s*skip_submission\s*(#.*)?$/.freeze
272
+ REGEX_STOP = /^\s*([~!%|\/].+[~!%|\/])\s*stop\s*(#.*)?$/.freeze
273
+ REGEX_STOP_IF = /^\s*([~!%|\/].+[~!%|\/])\s*stop_if\s+([~!%|\/].+[~!%|\/])\s*(#.*)?$/.freeze
274
+ REGEX_STOP_IF_FOUND = /^\s*([~!%|\/].+[~!%|\/])\s*stop_if_found\s+([~!%|\/].+[~!%|\/])\s*(#.*)?$/.freeze
275
+ REGEX_STOP_UNLESS = /^\s*([~!%|\/].+[~!%|\/])\s*stop_unless\s+([~!%|\/].+[~!%|\/])\s*(#.*)?$/.freeze
276
+ REGEX_STOP_UNLESS_FOUND = /^\s*([~!%|\/].+[~!%|\/])\s*stop_unless_found\s+([~!%|\/].+[~!%|\/])\s*(#.*)?$/.freeze
277
+
278
+ end
@@ -1,18 +1,18 @@
1
1
  # coding: utf-8
2
- # © 2016-2018 Resurface Labs LLC
2
+ # © 2016-2020 Resurface Labs Inc.
3
3
 
4
4
  class UsageLoggers
5
5
 
6
- @@DISABLED = 'true'.eql?(ENV['USAGE_LOGGERS_DISABLE'])
6
+ @@BRICKED = 'true'.eql?(ENV['USAGE_LOGGERS_DISABLE'])
7
7
 
8
- @@disabled = @@DISABLED
8
+ @@disabled = @@BRICKED
9
9
 
10
10
  def self.disable
11
11
  @@disabled = true
12
12
  end
13
13
 
14
14
  def self.enable
15
- @@disabled = false unless @@DISABLED
15
+ @@disabled = false unless @@BRICKED
16
16
  end
17
17
 
18
18
  def self.enabled?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resurfaceio-logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - RobDickinson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-30 00:00:00.000000000 Z
11
+ date: 2020-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -77,9 +77,11 @@ files:
77
77
  - lib/resurfaceio/http_logger.rb
78
78
  - lib/resurfaceio/http_logger_for_rack.rb
79
79
  - lib/resurfaceio/http_logger_for_rails.rb
80
- - lib/resurfaceio/http_message_impl.rb
80
+ - lib/resurfaceio/http_message.rb
81
81
  - lib/resurfaceio/http_request_impl.rb
82
82
  - lib/resurfaceio/http_response_impl.rb
83
+ - lib/resurfaceio/http_rule.rb
84
+ - lib/resurfaceio/http_rules.rb
83
85
  - lib/resurfaceio/usage_loggers.rb
84
86
  homepage: https://github.com/resurfaceio/logger-ruby
85
87
  licenses:
@@ -101,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
103
  version: '0'
102
104
  requirements: []
103
105
  rubyforge_project:
104
- rubygems_version: 2.5.2
106
+ rubygems_version: 2.7.7
105
107
  signing_key:
106
108
  specification_version: 4
107
109
  summary: Library for usage logging