Class: Logster::Message

Inherits:
Object
  • Object
show all
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
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(severity, progname, message, timestamp = nil, key = nil) ⇒ Message

Returns a new instance of Message.



25
26
27
28
29
30
31
32
33
34
# File 'lib/logster/message.rb', line 25

def initialize(severity, progname, message, timestamp = nil, key = nil)
  @timestamp = timestamp || get_timestamp
  @severity = severity
  @progname = progname
  @message = message
  @key = key || SecureRandom.hex
  @backtrace = nil
  @count = 1
  @protected = false
end

Instance Attribute Details

#backtraceObject

Returns the value of attribute backtrace.



23
24
25
# File 'lib/logster/message.rb', line 23

def backtrace
  @backtrace
end

#countObject

Returns the value of attribute count.



23
24
25
# File 'lib/logster/message.rb', line 23

def count
  @count
end

#envObject

Returns the value of attribute env.



23
24
25
# File 'lib/logster/message.rb', line 23

def env
  @env
end

#first_timestampObject

Returns the value of attribute first_timestamp.



23
24
25
# File 'lib/logster/message.rb', line 23

def first_timestamp
  @first_timestamp
end

#keyObject

Returns the value of attribute key.



23
24
25
# File 'lib/logster/message.rb', line 23

def key
  @key
end

#messageObject

Returns the value of attribute message.



23
24
25
# File 'lib/logster/message.rb', line 23

def message
  @message
end

#prognameObject

Returns the value of attribute progname.



23
24
25
# File 'lib/logster/message.rb', line 23

def progname
  @progname
end

#protectedObject

Returns the value of attribute protected.



23
24
25
# File 'lib/logster/message.rb', line 23

def protected
  @protected
end

#severityObject

Returns the value of attribute severity.



23
24
25
# File 'lib/logster/message.rb', line 23

def severity
  @severity
end

#timestampObject

Returns the value of attribute timestamp.



23
24
25
# File 'lib/logster/message.rb', line 23

def timestamp
  @timestamp
end

Class Method Details

.default_envObject



84
85
86
87
88
89
90
91
# File 'lib/logster/message.rb', line 84

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



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/logster/message.rb', line 60

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.first_timestamp = parsed["first_timestamp"]
  msg
end

.hostnameObject



75
76
77
# File 'lib/logster/message.rb', line 75

def self.hostname
  @hostname ||= `hostname`.strip! rescue "<unknown>"
end

.populate_from_env(env) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/logster/message.rb', line 128

def self.populate_from_env(env)
  env[LOGSTER_ENV] ||= begin
      unless 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

Instance Method Details

#<=>(other) ⇒ Object



154
155
156
157
158
159
# File 'lib/logster/message.rb', line 154

def <=>(other)
  time = self.timestamp <=> other.timestamp
  return time if time && time != 0

  self.key <=> other.key
end

#=~(pattern) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/logster/message.rb', line 161

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

#grouping_hashObject

in its own method so it can be overridden



94
95
96
# File 'lib/logster/message.rb', line 94

def grouping_hash
  return { message: self.message, severity: self.severity, backtrace: self.backtrace }
end

#grouping_keyObject

todo - memoize?



99
100
101
# File 'lib/logster/message.rb', line 99

def grouping_key
  Digest::SHA1.hexdigest JSON.fast_generate grouping_hash
end

#is_similar?(other) ⇒ Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/logster/message.rb', line 115

def is_similar?(other)
  self.grouping_key == other.grouping_key
end

#merge_similar_message(other) ⇒ Object



119
120
121
122
123
124
125
126
# File 'lib/logster/message.rb', line 119

def merge_similar_message(other)
  self.first_timestamp ||= self.timestamp
  self.timestamp = [self.timestamp,other.timestamp].max
  other_env = JSON.load JSON.fast_generate other.env
  other_env.keys.each do |env_key|
    self.env[env_key] = Message.env_merge_helper(self.env[env_key], other_env[env_key])
  end
end

#populate_from_env(env) ⇒ Object



79
80
81
82
# File 'lib/logster/message.rb', line 79

def populate_from_env(env)
  env ||= {}
  @env = Message.populate_from_env(self.class.default_env.merge env)
end

#solved_keysObject

todo - memoize?



104
105
106
107
108
109
110
111
112
113
# File 'lib/logster/message.rb', line 104

def solved_keys
  if (versions=env["application_version"]) &&
      (backtrace && backtrace.length > 0)
    versions = [versions] if String === versions

    versions.map do |version|
      Digest::SHA1.hexdigest "#{version} #{backtrace}"
    end
  end
end

#to_hObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/logster/message.rb', line 36

def to_h
  h = {
    message: @message,
    progname: @progname,
    severity: @severity,
    timestamp: @timestamp,
    key: @key,
    backtrace: @backtrace,
    count: @count,
    env: @env,
    protected: @protected
  }

  if @first_timestamp
    h[:first_timestamp] = @first_timestamp
  end

  h
end

#to_json(opts = nil) ⇒ Object



56
57
58
# File 'lib/logster/message.rb', line 56

def to_json(opts = nil)
  JSON.fast_generate(to_h, opts)
end