logster 1.3.0 → 1.3.1
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/.gitignore +18 -18
- data/.travis.yml +15 -15
- data/CHANGELOG.md +137 -130
- data/Gemfile +4 -4
- data/Guardfile +8 -8
- data/LICENSE.txt +22 -22
- data/README.md +99 -99
- data/Rakefile +24 -24
- data/assets/fonts/FontAwesome.otf +0 -0
- data/assets/fonts/fontawesome-webfont.eot +0 -0
- data/assets/fonts/fontawesome-webfont.svg +639 -639
- data/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/assets/fonts/fontawesome-webfont.woff +0 -0
- data/assets/fonts/fontawesome-webfont.woff2 +0 -0
- data/assets/images/Icon-144_rounded.png +0 -0
- data/assets/images/Icon-144_square.png +0 -0
- data/assets/images/icon_144x144.png +0 -0
- data/assets/images/icon_64x64.png +0 -0
- data/assets/javascript/client-app.js +81 -81
- data/assets/javascript/vendor.js +5302 -5302
- data/assets/stylesheets/client-app.css +0 -0
- data/assets/stylesheets/vendor.css +3 -3
- data/build_client_app.sh +12 -12
- data/client-app/.editorconfig +20 -20
- data/client-app/.ember-cli +9 -9
- data/client-app/.eslintignore +19 -19
- data/client-app/.eslintrc.js +46 -46
- data/client-app/.gitignore +23 -23
- data/client-app/.travis.yml +27 -27
- data/client-app/.watchmanconfig +3 -3
- data/client-app/README.md +57 -57
- data/client-app/app/app.js +14 -14
- data/client-app/app/components/message-info.js +18 -18
- data/client-app/app/components/message-row.js +45 -45
- data/client-app/app/components/panel-resizer.js +75 -75
- data/client-app/app/components/tab-contents.js +27 -27
- data/client-app/app/components/tab-link.js +5 -5
- data/client-app/app/components/tabbed-section.js +32 -32
- data/client-app/app/components/time-formatter.js +25 -25
- data/client-app/app/components/update-time.js +21 -21
- data/client-app/app/controllers/index.js +83 -83
- data/client-app/app/controllers/show.js +13 -13
- data/client-app/app/index.html +29 -29
- data/client-app/app/initializers/app-init.js +55 -55
- data/client-app/app/lib/preload.js +14 -14
- data/client-app/app/lib/utilities.js +140 -140
- data/client-app/app/models/message-collection.js +158 -158
- data/client-app/app/models/message.js +99 -99
- data/client-app/app/resolver.js +3 -3
- data/client-app/app/router.js +14 -14
- data/client-app/app/routes/index.js +53 -53
- data/client-app/app/routes/show.js +14 -14
- data/client-app/app/styles/app.css +387 -387
- data/client-app/app/templates/application.hbs +2 -2
- data/client-app/app/templates/components/message-info.hbs +44 -44
- data/client-app/app/templates/components/message-row.hbs +17 -17
- data/client-app/app/templates/components/tabbed-section.hbs +10 -10
- data/client-app/app/templates/components/time-formatter.hbs +1 -1
- data/client-app/app/templates/index.hbs +57 -57
- data/client-app/app/templates/show.hbs +4 -4
- data/client-app/config/environment.js +51 -51
- data/client-app/config/optional-features.json +3 -3
- data/client-app/config/targets.js +18 -18
- data/client-app/ember-cli-build.js +29 -29
- data/client-app/package-lock.json +11365 -11365
- data/client-app/package.json +56 -56
- data/client-app/testem.js +25 -25
- data/client-app/tests/index.html +34 -34
- data/client-app/tests/integration/components/message-info-test.js +26 -26
- data/client-app/tests/integration/components/message-row-test.js +26 -26
- data/client-app/tests/integration/components/panel-resizer-test.js +26 -26
- data/client-app/tests/integration/components/tab-contents-test.js +26 -26
- data/client-app/tests/integration/components/tab-link-test.js +26 -26
- data/client-app/tests/integration/components/tabbed-section-test.js +26 -26
- data/client-app/tests/integration/components/time-formatter-test.js +26 -26
- data/client-app/tests/integration/components/update-time-test.js +26 -26
- data/client-app/tests/test-helper.js +8 -8
- data/client-app/tests/unit/controllers/index-test.js +12 -12
- data/client-app/tests/unit/controllers/show-test.js +12 -12
- data/client-app/tests/unit/initializers/app-init-test.js +31 -31
- data/client-app/tests/unit/routes/index-test.js +11 -11
- data/client-app/tests/unit/routes/show-test.js +11 -11
- data/lib/examples/sidekiq_logster_reporter.rb +21 -21
- data/lib/logster.rb +54 -54
- data/lib/logster/base_store.rb +130 -130
- data/lib/logster/configuration.rb +25 -25
- data/lib/logster/ignore_pattern.rb +65 -65
- data/lib/logster/logger.rb +108 -102
- data/lib/logster/message.rb +227 -227
- data/lib/logster/middleware/debug_exceptions.rb +26 -26
- data/lib/logster/middleware/reporter.rb +56 -56
- data/lib/logster/middleware/viewer.rb +220 -220
- data/lib/logster/rails/railtie.rb +58 -58
- data/lib/logster/redis_store.rb +481 -481
- data/lib/logster/version.rb +3 -3
- data/lib/logster/web.rb +14 -14
- data/logster.gemspec +34 -34
- data/test/examples/test_sidekiq_reporter_example.rb +46 -46
- data/test/fake_data/Gemfile +4 -4
- data/test/fake_data/generate.rb +10 -10
- data/test/logster/middleware/test_reporter.rb +21 -21
- data/test/logster/middleware/test_viewer.rb +96 -96
- data/test/logster/test_base_store.rb +147 -147
- data/test/logster/test_ignore_pattern.rb +41 -41
- data/test/logster/test_logger.rb +80 -74
- data/test/logster/test_message.rb +34 -34
- data/test/logster/test_redis_rate_limiter.rb +230 -230
- data/test/logster/test_redis_store.rb +427 -427
- data/test/test_helper.rb +38 -38
- data/vendor/assets/javascripts/logster.js.erb +39 -39
- metadata +3 -3
data/lib/logster/message.rb
CHANGED
|
@@ -1,227 +1,227 @@
|
|
|
1
|
-
require 'digest/sha1'
|
|
2
|
-
require 'securerandom'
|
|
3
|
-
|
|
4
|
-
module Logster
|
|
5
|
-
|
|
6
|
-
MAX_GROUPING_LENGTH = 50
|
|
7
|
-
|
|
8
|
-
class Message
|
|
9
|
-
LOGSTER_ENV = "_logster_env".freeze
|
|
10
|
-
ALLOWED_ENV = %w{
|
|
11
|
-
HTTP_HOST
|
|
12
|
-
REQUEST_URI
|
|
13
|
-
REQUEST_METHOD
|
|
14
|
-
HTTP_USER_AGENT
|
|
15
|
-
HTTP_ACCEPT
|
|
16
|
-
HTTP_REFERER
|
|
17
|
-
HTTP_X_FORWARDED_FOR
|
|
18
|
-
HTTP_X_REAL_IP
|
|
19
|
-
hostname
|
|
20
|
-
process_id
|
|
21
|
-
application_version
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
attr_accessor :timestamp, :severity, :progname, :message, :key, :backtrace, :count, :env, :protected, :first_timestamp
|
|
25
|
-
|
|
26
|
-
def initialize(severity, progname, message, timestamp = nil, key = nil)
|
|
27
|
-
@timestamp = timestamp || get_timestamp
|
|
28
|
-
@severity = severity
|
|
29
|
-
@progname = progname
|
|
30
|
-
@message = message
|
|
31
|
-
@key = key || SecureRandom.hex
|
|
32
|
-
@backtrace = nil
|
|
33
|
-
@count = 1
|
|
34
|
-
@protected = false
|
|
35
|
-
@first_timestamp = nil
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def to_h
|
|
39
|
-
h = {
|
|
40
|
-
message: @message,
|
|
41
|
-
progname: @progname,
|
|
42
|
-
severity: @severity,
|
|
43
|
-
timestamp: @timestamp,
|
|
44
|
-
key: @key,
|
|
45
|
-
backtrace: @backtrace,
|
|
46
|
-
count: @count,
|
|
47
|
-
env: @env,
|
|
48
|
-
protected: @protected
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if @first_timestamp
|
|
52
|
-
h[:first_timestamp] = @first_timestamp
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
h
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def to_json(opts = nil)
|
|
59
|
-
JSON.fast_generate(to_h, opts)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def self.from_json(json)
|
|
63
|
-
parsed = ::JSON.parse(json)
|
|
64
|
-
msg = new( parsed["severity"],
|
|
65
|
-
parsed["progname"],
|
|
66
|
-
parsed["message"],
|
|
67
|
-
parsed["timestamp"],
|
|
68
|
-
parsed["key"] )
|
|
69
|
-
msg.backtrace = parsed["backtrace"]
|
|
70
|
-
msg.env = parsed["env"]
|
|
71
|
-
msg.count = parsed["count"]
|
|
72
|
-
msg.protected = parsed["protected"]
|
|
73
|
-
msg.first_timestamp = parsed["first_timestamp"]
|
|
74
|
-
msg
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def self.hostname
|
|
78
|
-
@hostname ||= `hostname`.strip! rescue "<unknown>"
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def populate_from_env(env)
|
|
82
|
-
env ||= {}
|
|
83
|
-
@env = Message.populate_from_env(self.class.default_env.merge env)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def self.default_env
|
|
87
|
-
env = {
|
|
88
|
-
"hostname" => hostname,
|
|
89
|
-
"process_id" => Process.pid
|
|
90
|
-
}
|
|
91
|
-
env["application_version"] = Logster.config.application_version if Logster.config.application_version
|
|
92
|
-
env
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# in its own method so it can be overridden
|
|
96
|
-
def grouping_hash
|
|
97
|
-
return { message: self.message, severity: self.severity, backtrace: self.backtrace }
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
# todo - memoize?
|
|
101
|
-
def grouping_key
|
|
102
|
-
Digest::SHA1.hexdigest JSON.fast_generate grouping_hash
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# todo - memoize?
|
|
106
|
-
def solved_keys
|
|
107
|
-
if (versions=env["application_version"]) &&
|
|
108
|
-
(backtrace && backtrace.length > 0)
|
|
109
|
-
versions = [versions] if String === versions
|
|
110
|
-
|
|
111
|
-
versions.map do |version|
|
|
112
|
-
Digest::SHA1.hexdigest "#{version} #{backtrace}"
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def is_similar?(other)
|
|
118
|
-
self.grouping_key == other.grouping_key
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def merge_similar_message(other)
|
|
122
|
-
self.first_timestamp ||= self.timestamp
|
|
123
|
-
self.timestamp = [self.timestamp,other.timestamp].max
|
|
124
|
-
other_env = JSON.load JSON.fast_generate other.env
|
|
125
|
-
other_env.keys.each do |env_key|
|
|
126
|
-
self.env[env_key] = Message.env_merge_helper(self.env[env_key], other_env[env_key])
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def self.populate_from_env(env)
|
|
131
|
-
env[LOGSTER_ENV] ||= begin
|
|
132
|
-
unless env.include? "rack.input"
|
|
133
|
-
# Not a web request
|
|
134
|
-
return env
|
|
135
|
-
end
|
|
136
|
-
scrubbed = default_env
|
|
137
|
-
request = Rack::Request.new(env)
|
|
138
|
-
params = {}
|
|
139
|
-
request.params.each do |k,v|
|
|
140
|
-
if k.include? "password"
|
|
141
|
-
params[k] = "[redacted]"
|
|
142
|
-
elsif Array === v
|
|
143
|
-
params[k] = v[0..20]
|
|
144
|
-
else
|
|
145
|
-
params[k] = v && v[0..100]
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
scrubbed["params"] = params if params.length > 0
|
|
149
|
-
ALLOWED_ENV.map{ |k|
|
|
150
|
-
scrubbed[k] = env[k] if env[k]
|
|
151
|
-
}
|
|
152
|
-
scrubbed
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def <=>(other)
|
|
157
|
-
time = self.timestamp <=> other.timestamp
|
|
158
|
-
return time if time && time != 0
|
|
159
|
-
|
|
160
|
-
self.key <=> other.key
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def =~(pattern)
|
|
164
|
-
case pattern
|
|
165
|
-
when Hash
|
|
166
|
-
IgnorePattern.new(nil, pattern).matches? self
|
|
167
|
-
when String
|
|
168
|
-
IgnorePattern.new(pattern, nil).matches? self
|
|
169
|
-
when Regexp
|
|
170
|
-
IgnorePattern.new(pattern, nil).matches? self
|
|
171
|
-
when IgnorePattern
|
|
172
|
-
pattern.matches? self
|
|
173
|
-
else
|
|
174
|
-
nil
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
protected
|
|
179
|
-
|
|
180
|
-
def get_timestamp
|
|
181
|
-
(Time.new.to_f * 1000).to_i
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
private
|
|
185
|
-
|
|
186
|
-
def self.env_merge_helper(self_value, other_value)
|
|
187
|
-
other_value = other_value.to_s if Symbol === other_value
|
|
188
|
-
|
|
189
|
-
if (Hash === self_value || self_value.nil?) && (Hash === other_value || other_value.nil?) && (!self_value.nil? || !other_value.nil?)
|
|
190
|
-
# one or both is a hash but not neither -> recurse on the keys
|
|
191
|
-
self_value = {} unless self_value
|
|
192
|
-
other_value = {} unless other_value
|
|
193
|
-
shared_keys = self_value.keys | (other_value.keys rescue [])
|
|
194
|
-
shared_keys.each do |key|
|
|
195
|
-
self_value[key] = env_merge_helper(self_value[key], other_value[key])
|
|
196
|
-
end
|
|
197
|
-
self_value
|
|
198
|
-
elsif self_value.is_a?(Array) && !other_value.is_a?(Array)
|
|
199
|
-
# Already have grouped data, so append to array (it's actually a set)
|
|
200
|
-
self_value << other_value unless self_value.include?(other_value) || self_value.length >= Logster::MAX_GROUPING_LENGTH
|
|
201
|
-
self_value
|
|
202
|
-
elsif !self_value.is_a?(Array)
|
|
203
|
-
if self_value == other_value
|
|
204
|
-
self_value
|
|
205
|
-
else
|
|
206
|
-
[self_value, other_value]
|
|
207
|
-
end
|
|
208
|
-
else
|
|
209
|
-
# They're both arrays.
|
|
210
|
-
# Three cases:
|
|
211
|
-
# self = [1,2,3] and other = [1,2,4] -> make into array of array
|
|
212
|
-
# self = [] and other = [1,2,4] -> make into array of array
|
|
213
|
-
# self = [[1,2,3], [1,2,5]] and other = [1,2,4] -> append to array
|
|
214
|
-
if self_value.length > 0 && self_value[0].is_a?(Array)
|
|
215
|
-
self_value << other_value unless self_value.include?(other_value) || self_value.length >= Logster::MAX_GROUPING_LENGTH
|
|
216
|
-
self_value
|
|
217
|
-
else
|
|
218
|
-
if self_value == other_value
|
|
219
|
-
self_value
|
|
220
|
-
else
|
|
221
|
-
[self_value, other_value]
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
end
|
|
1
|
+
require 'digest/sha1'
|
|
2
|
+
require 'securerandom'
|
|
3
|
+
|
|
4
|
+
module Logster
|
|
5
|
+
|
|
6
|
+
MAX_GROUPING_LENGTH = 50
|
|
7
|
+
|
|
8
|
+
class Message
|
|
9
|
+
LOGSTER_ENV = "_logster_env".freeze
|
|
10
|
+
ALLOWED_ENV = %w{
|
|
11
|
+
HTTP_HOST
|
|
12
|
+
REQUEST_URI
|
|
13
|
+
REQUEST_METHOD
|
|
14
|
+
HTTP_USER_AGENT
|
|
15
|
+
HTTP_ACCEPT
|
|
16
|
+
HTTP_REFERER
|
|
17
|
+
HTTP_X_FORWARDED_FOR
|
|
18
|
+
HTTP_X_REAL_IP
|
|
19
|
+
hostname
|
|
20
|
+
process_id
|
|
21
|
+
application_version
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
attr_accessor :timestamp, :severity, :progname, :message, :key, :backtrace, :count, :env, :protected, :first_timestamp
|
|
25
|
+
|
|
26
|
+
def initialize(severity, progname, message, timestamp = nil, key = nil)
|
|
27
|
+
@timestamp = timestamp || get_timestamp
|
|
28
|
+
@severity = severity
|
|
29
|
+
@progname = progname
|
|
30
|
+
@message = message
|
|
31
|
+
@key = key || SecureRandom.hex
|
|
32
|
+
@backtrace = nil
|
|
33
|
+
@count = 1
|
|
34
|
+
@protected = false
|
|
35
|
+
@first_timestamp = nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def to_h
|
|
39
|
+
h = {
|
|
40
|
+
message: @message,
|
|
41
|
+
progname: @progname,
|
|
42
|
+
severity: @severity,
|
|
43
|
+
timestamp: @timestamp,
|
|
44
|
+
key: @key,
|
|
45
|
+
backtrace: @backtrace,
|
|
46
|
+
count: @count,
|
|
47
|
+
env: @env,
|
|
48
|
+
protected: @protected
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if @first_timestamp
|
|
52
|
+
h[:first_timestamp] = @first_timestamp
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
h
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def to_json(opts = nil)
|
|
59
|
+
JSON.fast_generate(to_h, opts)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.from_json(json)
|
|
63
|
+
parsed = ::JSON.parse(json)
|
|
64
|
+
msg = new( parsed["severity"],
|
|
65
|
+
parsed["progname"],
|
|
66
|
+
parsed["message"],
|
|
67
|
+
parsed["timestamp"],
|
|
68
|
+
parsed["key"] )
|
|
69
|
+
msg.backtrace = parsed["backtrace"]
|
|
70
|
+
msg.env = parsed["env"]
|
|
71
|
+
msg.count = parsed["count"]
|
|
72
|
+
msg.protected = parsed["protected"]
|
|
73
|
+
msg.first_timestamp = parsed["first_timestamp"]
|
|
74
|
+
msg
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.hostname
|
|
78
|
+
@hostname ||= `hostname`.strip! rescue "<unknown>"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def populate_from_env(env)
|
|
82
|
+
env ||= {}
|
|
83
|
+
@env = Message.populate_from_env(self.class.default_env.merge env)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.default_env
|
|
87
|
+
env = {
|
|
88
|
+
"hostname" => hostname,
|
|
89
|
+
"process_id" => Process.pid
|
|
90
|
+
}
|
|
91
|
+
env["application_version"] = Logster.config.application_version if Logster.config.application_version
|
|
92
|
+
env
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# in its own method so it can be overridden
|
|
96
|
+
def grouping_hash
|
|
97
|
+
return { message: self.message, severity: self.severity, backtrace: self.backtrace }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# todo - memoize?
|
|
101
|
+
def grouping_key
|
|
102
|
+
Digest::SHA1.hexdigest JSON.fast_generate grouping_hash
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# todo - memoize?
|
|
106
|
+
def solved_keys
|
|
107
|
+
if (versions=env["application_version"]) &&
|
|
108
|
+
(backtrace && backtrace.length > 0)
|
|
109
|
+
versions = [versions] if String === versions
|
|
110
|
+
|
|
111
|
+
versions.map do |version|
|
|
112
|
+
Digest::SHA1.hexdigest "#{version} #{backtrace}"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def is_similar?(other)
|
|
118
|
+
self.grouping_key == other.grouping_key
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def merge_similar_message(other)
|
|
122
|
+
self.first_timestamp ||= self.timestamp
|
|
123
|
+
self.timestamp = [self.timestamp,other.timestamp].max
|
|
124
|
+
other_env = JSON.load JSON.fast_generate other.env
|
|
125
|
+
other_env.keys.each do |env_key|
|
|
126
|
+
self.env[env_key] = Message.env_merge_helper(self.env[env_key], other_env[env_key])
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def self.populate_from_env(env)
|
|
131
|
+
env[LOGSTER_ENV] ||= begin
|
|
132
|
+
unless env.include? "rack.input"
|
|
133
|
+
# Not a web request
|
|
134
|
+
return env
|
|
135
|
+
end
|
|
136
|
+
scrubbed = default_env
|
|
137
|
+
request = Rack::Request.new(env)
|
|
138
|
+
params = {}
|
|
139
|
+
request.params.each do |k,v|
|
|
140
|
+
if k.include? "password"
|
|
141
|
+
params[k] = "[redacted]"
|
|
142
|
+
elsif Array === v
|
|
143
|
+
params[k] = v[0..20]
|
|
144
|
+
else
|
|
145
|
+
params[k] = v && v[0..100]
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
scrubbed["params"] = params if params.length > 0
|
|
149
|
+
ALLOWED_ENV.map{ |k|
|
|
150
|
+
scrubbed[k] = env[k] if env[k]
|
|
151
|
+
}
|
|
152
|
+
scrubbed
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def <=>(other)
|
|
157
|
+
time = self.timestamp <=> other.timestamp
|
|
158
|
+
return time if time && time != 0
|
|
159
|
+
|
|
160
|
+
self.key <=> other.key
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def =~(pattern)
|
|
164
|
+
case pattern
|
|
165
|
+
when Hash
|
|
166
|
+
IgnorePattern.new(nil, pattern).matches? self
|
|
167
|
+
when String
|
|
168
|
+
IgnorePattern.new(pattern, nil).matches? self
|
|
169
|
+
when Regexp
|
|
170
|
+
IgnorePattern.new(pattern, nil).matches? self
|
|
171
|
+
when IgnorePattern
|
|
172
|
+
pattern.matches? self
|
|
173
|
+
else
|
|
174
|
+
nil
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
protected
|
|
179
|
+
|
|
180
|
+
def get_timestamp
|
|
181
|
+
(Time.new.to_f * 1000).to_i
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
private
|
|
185
|
+
|
|
186
|
+
def self.env_merge_helper(self_value, other_value)
|
|
187
|
+
other_value = other_value.to_s if Symbol === other_value
|
|
188
|
+
|
|
189
|
+
if (Hash === self_value || self_value.nil?) && (Hash === other_value || other_value.nil?) && (!self_value.nil? || !other_value.nil?)
|
|
190
|
+
# one or both is a hash but not neither -> recurse on the keys
|
|
191
|
+
self_value = {} unless self_value
|
|
192
|
+
other_value = {} unless other_value
|
|
193
|
+
shared_keys = self_value.keys | (other_value.keys rescue [])
|
|
194
|
+
shared_keys.each do |key|
|
|
195
|
+
self_value[key] = env_merge_helper(self_value[key], other_value[key])
|
|
196
|
+
end
|
|
197
|
+
self_value
|
|
198
|
+
elsif self_value.is_a?(Array) && !other_value.is_a?(Array)
|
|
199
|
+
# Already have grouped data, so append to array (it's actually a set)
|
|
200
|
+
self_value << other_value unless self_value.include?(other_value) || self_value.length >= Logster::MAX_GROUPING_LENGTH
|
|
201
|
+
self_value
|
|
202
|
+
elsif !self_value.is_a?(Array)
|
|
203
|
+
if self_value == other_value
|
|
204
|
+
self_value
|
|
205
|
+
else
|
|
206
|
+
[self_value, other_value]
|
|
207
|
+
end
|
|
208
|
+
else
|
|
209
|
+
# They're both arrays.
|
|
210
|
+
# Three cases:
|
|
211
|
+
# self = [1,2,3] and other = [1,2,4] -> make into array of array
|
|
212
|
+
# self = [] and other = [1,2,4] -> make into array of array
|
|
213
|
+
# self = [[1,2,3], [1,2,5]] and other = [1,2,4] -> append to array
|
|
214
|
+
if self_value.length > 0 && self_value[0].is_a?(Array)
|
|
215
|
+
self_value << other_value unless self_value.include?(other_value) || self_value.length >= Logster::MAX_GROUPING_LENGTH
|
|
216
|
+
self_value
|
|
217
|
+
else
|
|
218
|
+
if self_value == other_value
|
|
219
|
+
self_value
|
|
220
|
+
else
|
|
221
|
+
[self_value, other_value]
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|