resurfaceio-logger 1.10.0 → 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 +4 -4
- data/lib/resurfaceio/all.rb +1 -1
- data/lib/resurfaceio/base_logger.rb +22 -5
- data/lib/resurfaceio/http_logger.rb +19 -89
- data/lib/resurfaceio/http_logger_for_rack.rb +3 -2
- data/lib/resurfaceio/http_logger_for_rails.rb +3 -2
- data/lib/resurfaceio/http_message.rb +30 -9
- data/lib/resurfaceio/http_request_impl.rb +1 -1
- data/lib/resurfaceio/http_response_impl.rb +1 -1
- data/lib/resurfaceio/http_rule.rb +1 -1
- data/lib/resurfaceio/http_rules.rb +173 -25
- data/lib/resurfaceio/usage_loggers.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78d67f05915dcaee82ef7e3809856549bf09d01ac1f26d32f4dcb02003d317f3
|
4
|
+
data.tar.gz: f3d3598661aed83877882554183991ef228ac92d3f875f087eafddd3221cfa59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5aa5de88c997daddb5f345e4e41d5a173e59adb449dec141ee015747a48ef2f82a7ec623a6b1630d913f5a018f72c4aa1907e310fa1a7808f5c5c579db0281d9
|
7
|
+
data.tar.gz: e998c80806e0488c0790e551285e3ae90b7897aa7e027019ad18fd9c9794f0bb37add6d5aaeddb8eb275e66da18b3b9e21b042af636009966d9b6773f200ae88
|
data/lib/resurfaceio/all.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
# © 2016-
|
2
|
+
# © 2016-2020 Resurface Labs Inc.
|
3
3
|
|
4
4
|
require 'uri'
|
5
5
|
require 'net/http'
|
@@ -51,7 +51,12 @@ class BaseLogger
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
# finalize internal properties
|
54
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
|
55
60
|
end
|
56
61
|
|
57
62
|
def agent
|
@@ -102,10 +107,10 @@ class BaseLogger
|
|
102
107
|
|
103
108
|
def submit(msg)
|
104
109
|
if msg.nil? || @skip_submission || !enabled?
|
105
|
-
|
110
|
+
# do nothing
|
106
111
|
elsif @queue
|
107
112
|
@queue << msg
|
108
|
-
|
113
|
+
@submit_successes_lock.synchronize { @submit_successes += 1 }
|
109
114
|
else
|
110
115
|
begin
|
111
116
|
@url_parsed ||= URI.parse(@url)
|
@@ -119,14 +124,26 @@ class BaseLogger
|
|
119
124
|
request.body = Zlib::Deflate.deflate(msg)
|
120
125
|
end
|
121
126
|
response = @url_connection.request(request)
|
122
|
-
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
|
123
132
|
rescue SocketError
|
133
|
+
@submit_failures_lock.synchronize { @submit_failures += 1 }
|
124
134
|
@url_connection = nil
|
125
|
-
false
|
126
135
|
end
|
127
136
|
end
|
128
137
|
end
|
129
138
|
|
139
|
+
def submit_failures
|
140
|
+
@submit_failures
|
141
|
+
end
|
142
|
+
|
143
|
+
def submit_successes
|
144
|
+
@submit_successes
|
145
|
+
end
|
146
|
+
|
130
147
|
def url
|
131
148
|
@url
|
132
149
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
# © 2016-
|
2
|
+
# © 2016-2020 Resurface Labs Inc.
|
3
3
|
|
4
4
|
require 'json'
|
5
5
|
require 'resurfaceio/base_logger'
|
@@ -11,53 +11,20 @@ class HttpLogger < BaseLogger
|
|
11
11
|
|
12
12
|
AGENT = 'http_logger.rb'.freeze
|
13
13
|
|
14
|
-
@@default_rules = HttpRules.strict_rules
|
15
|
-
|
16
|
-
def self.default_rules
|
17
|
-
@@default_rules
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.default_rules=(val)
|
21
|
-
@@default_rules = val.gsub(/^\s*include default\s*$/, '')
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.string_content_type?(s)
|
25
|
-
!s.nil? && !(s =~ /^(text\/(html|plain|xml))|(application\/(json|soap|xml|x-www-form-urlencoded))/i).nil?
|
26
|
-
end
|
27
|
-
|
28
14
|
def initialize(options = {})
|
29
15
|
super(AGENT, options)
|
30
16
|
|
31
|
-
#
|
17
|
+
# parse specified rules
|
32
18
|
if options.respond_to?(:has_key?) && options.has_key?(:rules)
|
33
|
-
@rules = options[:rules]
|
34
|
-
@rules = @@default_rules unless @rules.strip.length > 0
|
19
|
+
@rules = HttpRules.new(options[:rules])
|
35
20
|
else
|
36
|
-
@rules =
|
21
|
+
@rules = HttpRules.new(nil)
|
37
22
|
end
|
38
23
|
|
39
|
-
#
|
40
|
-
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@rules_remove = prs.select {|r| 'remove' == r.verb}
|
44
|
-
@rules_remove_if = prs.select {|r| 'remove_if' == r.verb}
|
45
|
-
@rules_remove_if_found = prs.select {|r| 'remove_if_found' == r.verb}
|
46
|
-
@rules_remove_unless = prs.select {|r| 'remove_unless' == r.verb}
|
47
|
-
@rules_remove_unless_found = prs.select {|r| 'remove_unless_found' == r.verb}
|
48
|
-
@rules_replace = prs.select {|r| 'replace' == r.verb}
|
49
|
-
@rules_sample = prs.select {|r| 'sample' == r.verb}
|
50
|
-
@rules_stop = prs.select {|r| 'stop' == r.verb}
|
51
|
-
@rules_stop_if = prs.select {|r| 'stop_if' == r.verb}
|
52
|
-
@rules_stop_if_found = prs.select {|r| 'stop_if_found' == r.verb}
|
53
|
-
@rules_stop_unless = prs.select {|r| 'stop_unless' == r.verb}
|
54
|
-
@rules_stop_unless_found = prs.select {|r| 'stop_unless_found' == r.verb}
|
55
|
-
@skip_compression = prs.select {|r| 'skip_compression' == r.verb}.length > 0
|
56
|
-
@skip_submission = prs.select {|r| 'skip_submission' == r.verb}.length > 0
|
57
|
-
|
58
|
-
# finish validating rules
|
59
|
-
raise RuntimeError.new('Multiple sample rules') if @rules_sample.length > 1
|
60
|
-
unless @url.nil? || @url.start_with?('https') || @rules_allow_http_url
|
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
|
61
28
|
@enableable = false
|
62
29
|
@enabled = false
|
63
30
|
end
|
@@ -67,58 +34,21 @@ class HttpLogger < BaseLogger
|
|
67
34
|
@rules
|
68
35
|
end
|
69
36
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
def format(request, response, response_body = nil, request_body = nil, now = nil)
|
75
|
-
details = HttpMessage.build(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?
|
76
41
|
|
77
|
-
#
|
78
|
-
unless @rules_copy_session_field.empty?
|
79
|
-
ssn = request.session
|
80
|
-
if !ssn.nil? && ssn.respond_to?(:keys)
|
81
|
-
@rules_copy_session_field.each do |r|
|
82
|
-
ssn.keys.each {|d| (details << ["session_field:#{d}", ssn[d].to_s]) if r.param1.match(d)}
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# quit early based on stop rules if configured
|
88
|
-
@rules_stop.each {|r| details.each {|d| return nil if r.scope.match(d[0])}}
|
89
|
-
@rules_stop_if_found.each {|r| details.each {|d| return nil if r.scope.match(d[0]) && r.param1.match(d[1])}}
|
90
|
-
@rules_stop_if.each {|r| details.each {|d| return nil if r.scope.match(d[0]) && r.param1.match(d[1])}}
|
91
|
-
passed = 0
|
92
|
-
@rules_stop_unless_found.each {|r| details.each {|d| passed += 1 if r.scope.match(d[0]) && r.param1.match(d[1])}}
|
93
|
-
return nil if passed != @rules_stop_unless_found.length
|
94
|
-
passed = 0
|
95
|
-
@rules_stop_unless.each {|r| details.each {|d| passed += 1 if r.scope.match(d[0]) && r.param1.match(d[1])}}
|
96
|
-
return nil if passed != @rules_stop_unless.length
|
97
|
-
|
98
|
-
# do sampling if configured
|
99
|
-
return nil if !@rules_sample[0].nil? && (rand * 100 >= @rules_sample[0].param1)
|
100
|
-
|
101
|
-
# winnow sensitive details based on remove rules if configured
|
102
|
-
@rules_remove.each {|r| details.delete_if {|d| r.scope.match(d[0])}}
|
103
|
-
@rules_remove_unless_found.each {|r| details.delete_if {|d| r.scope.match(d[0]) && !r.param1.match(d[1])}}
|
104
|
-
@rules_remove_if_found.each {|r| details.delete_if {|d| r.scope.match(d[0]) && r.param1.match(d[1])}}
|
105
|
-
@rules_remove_unless.each {|r| details.delete_if {|d| r.scope.match(d[0]) && !r.param1.match(d[1])}}
|
106
|
-
@rules_remove_if.each {|r| details.delete_if {|d| r.scope.match(d[0]) && r.param1.match(d[1])}}
|
107
|
-
return nil if details.empty?
|
108
|
-
|
109
|
-
# mask sensitive details based on replace rules if configured
|
110
|
-
@rules_replace.each {|r| details.each {|d| d[1] = d[1].gsub(r.param1, r.param2) if r.scope.match(d[0])}}
|
111
|
-
|
112
|
-
# remove any details with empty values
|
113
|
-
details.delete_if {|d| '' == d[1]}
|
114
|
-
return nil if details.empty?
|
115
|
-
|
116
|
-
# finish message
|
117
|
-
details << ['now', now.nil? ? (Time.now.to_f * 1000).floor.to_s : now]
|
42
|
+
# finalize message
|
118
43
|
details << ['agent', @agent]
|
119
44
|
details << ['host', @host]
|
120
45
|
details << ['version', @version]
|
121
|
-
|
46
|
+
|
47
|
+
# let's do this thing
|
48
|
+
submit(JSON.generate(details))
|
122
49
|
end
|
123
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
|
124
54
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
# © 2016-
|
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,7 +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
|
-
|
25
|
+
HttpMessage.send(logger, request, response) # todo add timing details
|
25
26
|
end
|
26
27
|
end
|
27
28
|
[status, headers, body]
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
# © 2016-
|
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,7 +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
|
-
|
24
|
+
HttpMessage.send(logger, request, response) # todo add timing details
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
@@ -1,10 +1,33 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
# © 2016-
|
2
|
+
# © 2016-2020 Resurface Labs Inc.
|
3
3
|
|
4
4
|
require 'json'
|
5
5
|
|
6
6
|
class HttpMessage
|
7
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
|
30
|
+
|
8
31
|
def self.build(request, response, response_body = nil, request_body = nil)
|
9
32
|
message = []
|
10
33
|
append_value message, 'request_method', request.request_method unless request.request_method.nil?
|
@@ -19,8 +42,6 @@ class HttpMessage
|
|
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 HttpMessage
|
|
74
95
|
unless key.nil?
|
75
96
|
unless value.nil?
|
76
97
|
case value
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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,37 +1,39 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
# © 2016-
|
2
|
+
# © 2016-2020 Resurface Labs Inc.
|
3
3
|
|
4
4
|
class HttpRules
|
5
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
|
+
|
6
27
|
def self.debug_rules
|
7
|
-
|
28
|
+
DEBUG_RULES
|
8
29
|
end
|
9
30
|
|
10
31
|
def self.standard_rules
|
11
|
-
|
12
|
-
/(request|response)_body|request_param/ replace /[a-zA-Z0-9.!#$%&’*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)/, /x@y.com/
|
13
|
-
/request_body|request_param|response_body/ replace /[0-9\.\-\/]{9,}/, /xyxy/
|
14
|
-
)
|
32
|
+
STANDARD_RULES
|
15
33
|
end
|
16
34
|
|
17
35
|
def self.strict_rules
|
18
|
-
|
19
|
-
/request_body|response_body|request_param:.*|request_header:(?!user-agent).*|response_header:(?!(content-length)|(content-type)).*/ remove
|
20
|
-
)
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.parse(rules)
|
24
|
-
result = []
|
25
|
-
unless rules.nil?
|
26
|
-
rules = rules.gsub(/^\s*include debug\s*$/, debug_rules)
|
27
|
-
rules = rules.gsub(/^\s*include standard\s*$/, standard_rules)
|
28
|
-
rules = rules.gsub(/^\s*include strict\s*$/, strict_rules)
|
29
|
-
rules.each_line do |rule|
|
30
|
-
parsed = parse_rule(rule)
|
31
|
-
result << parsed unless parsed.nil?
|
32
|
-
end
|
33
|
-
end
|
34
|
-
result
|
36
|
+
STRICT_RULES
|
35
37
|
end
|
36
38
|
|
37
39
|
def self.parse_rule(r)
|
@@ -76,8 +78,6 @@ class HttpRules
|
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
|
-
protected
|
80
|
-
|
81
81
|
def self.parse_regex(r, regex)
|
82
82
|
s = parse_string(r, regex)
|
83
83
|
raise RuntimeError.new("Invalid regex (#{regex}) in rule: #{r}") if '*' == s || '+' == s || '?' == s
|
@@ -109,6 +109,154 @@ class HttpRules
|
|
109
109
|
raise RuntimeError.new("Invalid expression (#{expr}) in rule: #{r}")
|
110
110
|
end
|
111
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
|
+
|
112
260
|
REGEX_ALLOW_HTTP_URL = /^\s*allow_http_url\s*(#.*)?$/.freeze
|
113
261
|
REGEX_BLANK_OR_COMMENT = /^\s*([#].*)*$/.freeze
|
114
262
|
REGEX_COPY_SESSION_FIELD = /^\s*copy_session_field\s+([~!%|\/].+[~!%|\/])\s*(#.*)?$/.freeze
|
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:
|
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:
|
11
|
+
date: 2020-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|