Class: CrashLog::Reporter

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/crash_log/reporter.rb

Constant Summary

Constants included from Logging

Logging::ANSI

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

included

Constructor Details

#initialize(config) ⇒ Reporter

Returns a new instance of Reporter.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/crash_log/reporter.rb', line 13

def initialize(config)
  @config     = config
  @scheme     = config.scheme
  @host       = config.host
  @port       = config.port
  @endpoint   = config.endpoint
  @announce_endpoint = config.announce == true ?
                       config.announce_endpoint : nil

  if MultiJson.respond_to?(:use)
    MultiJson.use(config.json_parser || MultiJson.default_adapter)
  elsif MultiJson.respond_to?(:engine=)
    MultiJson.engine = (config.json_parser || MultiJson.default_engine)
  end
end

Instance Attribute Details

#announce_endpointObject (readonly)

Returns the value of attribute announce_endpoint.



10
11
12
# File 'lib/crash_log/reporter.rb', line 10

def announce_endpoint
  @announce_endpoint
end

#configObject (readonly)

Returns the value of attribute config.



11
12
13
# File 'lib/crash_log/reporter.rb', line 11

def config
  @config
end

#endpointObject (readonly)

Returns the value of attribute endpoint.



10
11
12
# File 'lib/crash_log/reporter.rb', line 10

def endpoint
  @endpoint
end

#hostObject (readonly)

Returns the value of attribute host.



10
11
12
# File 'lib/crash_log/reporter.rb', line 10

def host
  @host
end

#portObject (readonly)

Returns the value of attribute port.



10
11
12
# File 'lib/crash_log/reporter.rb', line 10

def port
  @port
end

#responseObject (readonly)

Returns the value of attribute response.



11
12
13
# File 'lib/crash_log/reporter.rb', line 11

def response
  @response
end

#resultObject (readonly)

Returns the value of attribute result.



11
12
13
# File 'lib/crash_log/reporter.rb', line 11

def result
  @result
end

#schemeObject (readonly)

Returns the value of attribute scheme.



10
11
12
# File 'lib/crash_log/reporter.rb', line 10

def scheme
  @scheme
end

Instance Method Details

#adapterObject



117
118
119
# File 'lib/crash_log/reporter.rb', line 117

def adapter
  config.adapter
end

#announceObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/crash_log/reporter.rb', line 49

def announce
  return if dry_run?
  return "Unknown application" unless announce_endpoint

  response = post(config.announce_endpoint, encode({:payload => identification_hash}))
  if response.status == 201
    decode(response.body).symbolize_keys.fetch(:application_name, 'Default')
  else
    nil
  end
rescue => e
  error("Failed to announce application launch")
  raise if config.development_mode?
  nil
end

#connectionObject



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/crash_log/reporter.rb', line 100

def connection
  @connection ||= begin
    Faraday.new(:url => url) do |faraday|
      faraday.request :hmac_authentication, config.api_key, config.secret, {:service_id => config.service_name}
      faraday.adapter(adapter)
      faraday.request :url_encoded
      # faraday.response :logger

      if config.secure?
        faraday.ssl[:verify]        = true
        faraday.ssl[:verify_mode]   = OpenSSL::SSL::VERIFY_PEER
        faraday.ssl[:ca_path]       = config.ca_bundle_path
      end
    end
  end
end

#decode(string, options = {}) ⇒ Object



134
135
136
137
138
139
140
141
142
# File 'lib/crash_log/reporter.rb', line 134

def decode(string, options = {})
  if MultiJson.respond_to?(:load)
    # MultiJson >= 1.3
    MultiJson.load(string, options)
  elsif MultiJson.respond_to?(:decode)
    # MultiJson < 1.3
    MultiJson.decode(string, options)
  end
end

#dry_run?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/crash_log/reporter.rb', line 86

def dry_run?
  config.dry_run == true
end

#encode(object) ⇒ Object

FIXME: This is some seriously annoying shit. MultiJson should not have deprecated its old API and we wouldn’t need to do this.



124
125
126
127
128
129
130
131
132
# File 'lib/crash_log/reporter.rb', line 124

def encode(object)
  if MultiJson.respond_to?(:dump)
    # MultiJson >= 1.3
    MultiJson.dump(object)
  elsif MultiJson.respond_to?(:encode)
    # MultiJson < 1.3
    MultiJson.encode(object)
  end
end

#identification_hashObject



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/crash_log/reporter.rb', line 73

def identification_hash
  {
    :hostname => SystemInformation.hostname,
    :timestamp => Time.now.utc.to_i,
    :stage => config.stage,
    :notifier => {
      :name => "crashlog",
      :version => CrashLog::VERSION,
      :language => 'Ruby'
    }
  }
end

#notify(payload) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/crash_log/reporter.rb', line 29

def notify(payload)
  return if dry_run?

  # TODO: Move this to Payload.
  payload[:data] = CrashLog::Helpers.cleanup_obj(payload[:data])
  payload_string = encode({:payload => payload})

  # Useful to make sure we're successfully capturing the right data
  debug(payload.inspect) if config.development_mode?

  response = post(endpoint, payload_string)
  @response = response
  report_result(response.body)
  response.success?
rescue => e
  error("Sending exception failed due to a connectivity issue")
  raise if config.development_mode?
  nil
end

#post(endpoint, body) ⇒ Object



90
91
92
93
94
95
96
97
98
# File 'lib/crash_log/reporter.rb', line 90

def post(endpoint, body)
  connection.post do |req|
    req.url(endpoint)
    req.headers['Content-Type'] = 'application/json; charset=UTF-8'
    req.options[:timeout]       = config.http_read_timeout
    req.options[:open_timeout]  = config.http_open_timeout
    req.body                    = body
  end
end

#report_result(body) ⇒ Object



65
66
67
# File 'lib/crash_log/reporter.rb', line 65

def report_result(body)
  @result = decode(body).symbolize_keys
end

#urlObject



69
70
71
# File 'lib/crash_log/reporter.rb', line 69

def url
  URI.parse("#{scheme}://#{host}:#{port}").to_s
end