Class: Logster::Message
- Inherits:
-
Object
- Object
- Logster::Message
- Defined in:
- lib/logster/message.rb
Constant Summary collapse
- LOGSTER_ENV =
"_logster_env".freeze
- ALLOWED_ENV =
%w[ HTTP_HOST REQUEST_URI REQUEST_METHOD HTTP_USER_AGENT HTTP_ACCEPT HTTP_REFERER HTTP_X_FORWARDED_FOR HTTP_X_REAL_IP hostname process_id application_version time ]
Instance Attribute Summary collapse
-
#backtrace ⇒ Object
Returns the value of attribute backtrace.
-
#count ⇒ Object
Returns the value of attribute count.
-
#env ⇒ Object
Returns the value of attribute env.
-
#env_buffer ⇒ Object
Returns the value of attribute env_buffer.
-
#first_timestamp ⇒ Object
Returns the value of attribute first_timestamp.
-
#key ⇒ Object
Returns the value of attribute key.
-
#message ⇒ Object
readonly
Returns the value of attribute message.
-
#progname ⇒ Object
Returns the value of attribute progname.
-
#protected ⇒ Object
Returns the value of attribute protected.
-
#severity ⇒ Object
Returns the value of attribute severity.
-
#timestamp ⇒ Object
Returns the value of attribute timestamp.
Class Method Summary collapse
- .default_env ⇒ Object
- .from_json(json) ⇒ Object
- .hostname ⇒ Object
- .populate_env_helper(env) ⇒ Object
- .populate_from_env(env) ⇒ Object
- .scrub_params(params) ⇒ Object
Instance Method Summary collapse
- #<=>(other) ⇒ Object
- #=~(pattern) ⇒ Object
- #apply_env_size_limit(size_limit) ⇒ Object
- #apply_message_size_limit(limit, gems_dir: nil) ⇒ Object
- #drop_redundant_envs(limit) ⇒ Object
-
#grouping_hash ⇒ Object
in its own method so it can be overridden.
-
#grouping_key ⇒ Object
todo - memoize?.
- #has_env_buffer? ⇒ Boolean
-
#initialize(severity, progname, message, timestamp = nil, key = nil, count: 1) ⇒ Message
constructor
A new instance of Message.
- #merge_similar_message(other) ⇒ Object
- #populate_from_env(env) ⇒ Object
-
#solved_keys ⇒ Object
todo - memoize?.
- #to_h(exclude_env: false) ⇒ Object
- #to_json(opts = nil) ⇒ Object
- #truncate_backtrace(bytes_limit) ⇒ Object
Constructor Details
#initialize(severity, progname, message, timestamp = nil, key = nil, count: 1) ⇒ Message
Returns a new instance of Message.
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/logster/message.rb', line 35 def initialize(severity, progname, , = nil, key = nil, count: 1) @timestamp = || @severity = severity @progname = progname @message = @key = key || SecureRandom.hex @backtrace = nil @count = count || 1 @protected = false @first_timestamp = nil @env_buffer = [] end |
Instance Attribute Details
#backtrace ⇒ Object
Returns the value of attribute backtrace.
24 25 26 |
# File 'lib/logster/message.rb', line 24 def backtrace @backtrace end |
#count ⇒ Object
Returns the value of attribute count.
24 25 26 |
# File 'lib/logster/message.rb', line 24 def count @count end |
#env ⇒ Object
Returns the value of attribute env.
33 34 35 |
# File 'lib/logster/message.rb', line 33 def env @env end |
#env_buffer ⇒ Object
Returns the value of attribute env_buffer.
24 25 26 |
# File 'lib/logster/message.rb', line 24 def env_buffer @env_buffer end |
#first_timestamp ⇒ Object
Returns the value of attribute first_timestamp.
24 25 26 |
# File 'lib/logster/message.rb', line 24 def @first_timestamp end |
#key ⇒ Object
Returns the value of attribute key.
24 25 26 |
# File 'lib/logster/message.rb', line 24 def key @key end |
#message ⇒ Object (readonly)
Returns the value of attribute message.
33 34 35 |
# File 'lib/logster/message.rb', line 33 def @message end |
#progname ⇒ Object
Returns the value of attribute progname.
24 25 26 |
# File 'lib/logster/message.rb', line 24 def progname @progname end |
#protected ⇒ Object
Returns the value of attribute protected.
24 25 26 |
# File 'lib/logster/message.rb', line 24 def protected @protected end |
#severity ⇒ Object
Returns the value of attribute severity.
24 25 26 |
# File 'lib/logster/message.rb', line 24 def severity @severity end |
#timestamp ⇒ Object
Returns the value of attribute timestamp.
24 25 26 |
# File 'lib/logster/message.rb', line 24 def @timestamp end |
Class Method Details
.default_env ⇒ Object
122 123 124 125 126 127 128 |
# File 'lib/logster/message.rb', line 122 def self.default_env env = { "hostname" => hostname, "process_id" => Process.pid } env[ "application_version" ] = Logster.config.application_version if Logster.config.application_version env end |
.from_json(json) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/logster/message.rb', line 71 def self.from_json(json) parsed = ::JSON.parse(json) msg = new( parsed["severity"], parsed["progname"], parsed["message"], parsed["timestamp"], parsed["key"], ) msg.backtrace = parsed["backtrace"] msg.env = parsed["env"] msg.count = parsed["count"] msg.protected = parsed["protected"] msg. = parsed["first_timestamp"] msg end |
.hostname ⇒ Object
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/logster/message.rb', line 93 def self.hostname @hostname ||= begin command = Logster.config.use_full_hostname ? `hostname -f` : `hostname` command.strip! command rescue StandardError "<unknown>" end end |
.populate_env_helper(env) ⇒ Object
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/logster/message.rb', line 183 def self.populate_env_helper(env) env[LOGSTER_ENV] ||= begin if !env.include? "rack.input" # Not a web request return env end scrubbed = default_env request = Rack::Request.new(env) params = {} request.params.each do |k, v| if k.include? "password" params[k] = "[redacted]" elsif Array === v params[k] = v[0..20] else params[k] = v && v[0..100] end end scrubbed["params"] = params if params.length > 0 ALLOWED_ENV.map { |k| scrubbed[k] = env[k] if env[k] } scrubbed end end |
.populate_from_env(env) ⇒ Object
175 176 177 178 179 180 181 |
# File 'lib/logster/message.rb', line 175 def self.populate_from_env(env) if Array === env env.map { |single_env| self.populate_env_helper(single_env) } else self.populate_env_helper(env) end end |
.scrub_params(params) ⇒ Object
229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/logster/message.rb', line 229 def self.scrub_params(params) if Array === params params.map! { |p| scrub_params(p) } params elsif Hash === params params.each { |k, v| params[k] = scrub_params(v) } params elsif String === params scrubbed = params.scrub if !params.valid_encoding? scrubbed || params else params end end |
Instance Method Details
#<=>(other) ⇒ Object
207 208 209 210 211 212 |
# File 'lib/logster/message.rb', line 207 def <=>(other) time = self. <=> other. return time if time && time != 0 self.key <=> other.key end |
#=~(pattern) ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/logster/message.rb', line 214 def =~(pattern) case pattern when Hash IgnorePattern.new(nil, pattern).matches? self when String IgnorePattern.new(pattern, nil).matches? self when Regexp IgnorePattern.new(pattern, nil).matches? self when IgnorePattern pattern.matches? self else nil end end |
#apply_env_size_limit(size_limit) ⇒ Object
248 249 250 251 252 253 254 |
# File 'lib/logster/message.rb', line 248 def apply_env_size_limit(size_limit) if Array === env env.each { |e| truncate_env(e, size_limit) } elsif Hash === env truncate_env(env, size_limit) end end |
#apply_message_size_limit(limit, gems_dir: nil) ⇒ Object
256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/logster/message.rb', line 256 def (limit, gems_dir: nil) size = self.to_json(exclude_env: true).bytesize if size > limit && @backtrace @backtrace.gsub!(gems_dir, "") if gems_dir @backtrace.strip! size = self.to_json(exclude_env: true).bytesize backtrace_limit = limit - (size - @backtrace.bytesize) return if backtrace_limit <= 0 || size <= limit truncate_backtrace(backtrace_limit) end end |
#drop_redundant_envs(limit) ⇒ Object
244 245 246 |
# File 'lib/logster/message.rb', line 244 def drop_redundant_envs(limit) env.slice!(limit..-1) if Array === env end |
#grouping_hash ⇒ Object
in its own method so it can be overridden
131 132 133 |
# File 'lib/logster/message.rb', line 131 def grouping_hash { message: , severity: self.severity, backtrace: self.backtrace } end |
#grouping_key ⇒ Object
todo - memoize?
136 137 138 |
# File 'lib/logster/message.rb', line 136 def grouping_key Digest::SHA1.hexdigest JSON.fast_generate grouping_hash end |
#has_env_buffer? ⇒ Boolean
171 172 173 |
# File 'lib/logster/message.rb', line 171 def has_env_buffer? env_buffer.size > 0 end |
#merge_similar_message(other) ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/logster/message.rb', line 154 def (other) self. ||= self. self. = [self., other.].max self.count += other.count || 1 if Hash === other.env && !other.env.key?("time") && !other.env.key?(:time) other.env["time"] = other. end if Array === other.env env_buffer.unshift(*other.env) else env_buffer.unshift(other.env) end true end |
#populate_from_env(env) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/logster/message.rb', line 104 def populate_from_env(env) env ||= {} if Array === env env = env.map do |single_env| single_env = self.class.default_env.merge(single_env) if !single_env.key?("time") && !single_env.key?(:time) single_env["time"] = @timestamp || end single_env end else env = self.class.default_env.merge(env) env["time"] = @timestamp || if !env.key?("time") && !env.key?(:time) end self.env = Message.populate_from_env(env) end |
#solved_keys ⇒ Object
todo - memoize?
141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/logster/message.rb', line 141 def solved_keys if Array === env versions = env.map { |single_env| single_env["application_version"] } else versions = [env["application_version"]] end versions.compact! if backtrace && backtrace.length > 0 versions.map { |version| Digest::SHA1.hexdigest "#{version} #{backtrace}" } end end |
#to_h(exclude_env: false) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/logster/message.rb', line 48 def to_h(exclude_env: false) h = { message: @message, progname: @progname, severity: @severity, timestamp: @timestamp, key: @key, backtrace: @backtrace, count: @count, protected: @protected, } h[:first_timestamp] = @first_timestamp if @first_timestamp h[:env] = @env unless exclude_env h end |
#to_json(opts = nil) ⇒ Object
66 67 68 69 |
# File 'lib/logster/message.rb', line 66 def to_json(opts = nil) exclude_env = Hash === opts && opts.delete(:exclude_env) JSON.fast_generate(to_h(exclude_env: exclude_env), opts) end |
#truncate_backtrace(bytes_limit) ⇒ Object
268 269 270 271 |
# File 'lib/logster/message.rb', line 268 def truncate_backtrace(bytes_limit) @backtrace = @backtrace.byteslice(0...bytes_limit) @backtrace.slice!(-1) while !@backtrace[-1].valid_encoding? && @backtrace.size > 1 end |