crashdesk 0.1.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.
- data/crashdesk.gemspec +16 -0
- data/lib/crashdesk/backtrace.rb +102 -0
- data/lib/crashdesk/configuration.rb +53 -0
- data/lib/crashdesk/context_base.rb +57 -0
- data/lib/crashdesk/crashlog.rb +61 -0
- data/lib/crashdesk/environment.rb +31 -0
- data/lib/crashdesk/reporters/remote.rb +137 -0
- data/lib/crashdesk/reporters/screen.rb +16 -0
- data/lib/crashdesk/serializers/json.rb +25 -0
- data/lib/crashdesk/version.rb +3 -0
- data/lib/crashdesk.rb +51 -0
- data/spec/backtrace_spec.rb +64 -0
- data/spec/configuration_spec.rb +45 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/stubs/backtrace_basic.txt +17 -0
- metadata +61 -0
data/crashdesk.gemspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/crashdesk/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = 'crashdesk'
|
6
|
+
gem.version = Crashdesk::VERSION
|
7
|
+
gem.authors = ["Ladislav Martincik"]
|
8
|
+
gem.summary = "Crashde.sk is helping you track crashes of your application online"
|
9
|
+
gem.description = "crashdesk is the Ruby gem for containing core functionality for communication with crashde.sk servers"
|
10
|
+
gem.email = "info@crashde.sk"
|
11
|
+
gem.files = Dir['lib/**/*'] + Dir['spec/**/*'] + Dir['*.rb'] + ["crashdesk.gemspec"]
|
12
|
+
gem.homepage = "http://crashde.sk"
|
13
|
+
gem.require_paths = ["lib"]
|
14
|
+
gem.rubyforge_project = "crashdesk"
|
15
|
+
gem.requirements << "json_pure, json-jruby or json gem required"
|
16
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'zlib'
|
3
|
+
|
4
|
+
module Crashdesk
|
5
|
+
|
6
|
+
class Backtrace
|
7
|
+
|
8
|
+
class Line
|
9
|
+
# regexp taken from Airbrake
|
10
|
+
INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in `([^']+)')?$}.freeze
|
11
|
+
|
12
|
+
attr_reader :file, :number, :method
|
13
|
+
|
14
|
+
def self.parse(unparsed_line)
|
15
|
+
_, file, number, method = unparsed_line.match(INPUT_FORMAT).to_a
|
16
|
+
new(file, number, method)
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(file, number, method)
|
20
|
+
self.file = file
|
21
|
+
self.number = number
|
22
|
+
self.method = method
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
"#{file}:#{number}:in `#{method}'"
|
27
|
+
end
|
28
|
+
|
29
|
+
def ==(other)
|
30
|
+
to_s == other.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
def inspect
|
34
|
+
"<Line:#{to_s}>"
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
attr_writer :file, :number, :method
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :lines
|
42
|
+
|
43
|
+
def self.parse(backtrace, opts = {})
|
44
|
+
code_lines = split_multiline_backtrace(backtrace)
|
45
|
+
|
46
|
+
lines = unless code_lines.nil?
|
47
|
+
code_lines.collect do |unparsed_line|
|
48
|
+
Line.parse(unparsed_line)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
[]
|
52
|
+
end
|
53
|
+
|
54
|
+
instance = new(lines)
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize(lines)
|
58
|
+
self.lines = lines
|
59
|
+
end
|
60
|
+
|
61
|
+
def inspect
|
62
|
+
"<Backtrace: " + lines.collect { |line| line.inspect }.join(", ") + ">"
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s
|
66
|
+
lines.join("\n\s")
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_a
|
70
|
+
lines.map { |l| l.to_s }
|
71
|
+
end
|
72
|
+
|
73
|
+
def ==(other)
|
74
|
+
if other.respond_to?(:lines)
|
75
|
+
lines == other.lines
|
76
|
+
else
|
77
|
+
false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def hash_id
|
82
|
+
Digest::MD5.hexdigest(to_s)
|
83
|
+
end
|
84
|
+
|
85
|
+
def crc
|
86
|
+
Zlib::crc32(to_s).to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
attr_writer :lines
|
92
|
+
|
93
|
+
def self.split_multiline_backtrace(backtrace)
|
94
|
+
if (a = Array(backtrace)).size == 1
|
95
|
+
a.first.split(/\n\s*/)
|
96
|
+
else
|
97
|
+
backtrace
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Crashdesk
|
2
|
+
|
3
|
+
class Configuration
|
4
|
+
|
5
|
+
# Basic connection settings
|
6
|
+
attr_accessor :api_key
|
7
|
+
|
8
|
+
# Proxy server
|
9
|
+
attr_accessor :proxy_host, :proxy_port, :proxy_user, :proxy_pass
|
10
|
+
|
11
|
+
# HTTP
|
12
|
+
attr_accessor :host, :port
|
13
|
+
|
14
|
+
# Where to log Crashdesk output?
|
15
|
+
attr_accessor :logger
|
16
|
+
|
17
|
+
# Framework is string representing framework
|
18
|
+
# @example
|
19
|
+
# Crashdesk.configure do |config|
|
20
|
+
# config.api_key = 'YOUR API KEY HERE'
|
21
|
+
# config.project_root = ::Rails.root
|
22
|
+
# config.environment_name = ::Rails.env
|
23
|
+
# config.logger = ::Rails.logger
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
attr_accessor :environment_name, :project_root
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@host = 'crashde.sk'
|
30
|
+
end
|
31
|
+
|
32
|
+
# Hash like access
|
33
|
+
def [](option)
|
34
|
+
send(option)
|
35
|
+
end
|
36
|
+
|
37
|
+
def port
|
38
|
+
@port || default_port
|
39
|
+
end
|
40
|
+
|
41
|
+
def protocol
|
42
|
+
'http'
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def default_port
|
48
|
+
80
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Crashdesk
|
2
|
+
|
3
|
+
class ContextBase
|
4
|
+
MAX_DATA_LENGTH = 2048
|
5
|
+
|
6
|
+
def to_hash
|
7
|
+
{ 'context' => {} }
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def sanitize_unserializable_data(data, stack = [])
|
13
|
+
return "[recursion halted]" if stack.any? { |item| item == data.object_id }
|
14
|
+
|
15
|
+
if data.respond_to?(:to_hash)
|
16
|
+
data.to_hash.inject({}) do |result, (key, value)|
|
17
|
+
result.merge(key => sanitize_unserializable_data(value, stack + [data.object_id]))
|
18
|
+
end
|
19
|
+
elsif data.respond_to?(:to_ary)
|
20
|
+
data.to_ary.collect do |value|
|
21
|
+
sanitize_unserializable_data(value, stack + [data.object_id])
|
22
|
+
end
|
23
|
+
else
|
24
|
+
data.to_s.slice(0, MAX_DATA_LENGTH)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def extract_http_headers(env)
|
29
|
+
headers = {}
|
30
|
+
env.select{|k, v| k =~ /^HTTP_/}.each do |name, value|
|
31
|
+
proper_name = name.sub(/^HTTP_/, '').split('_').map{|upper_case| upper_case.capitalize}.join('-')
|
32
|
+
headers[proper_name] = value
|
33
|
+
end
|
34
|
+
unless headers['Cookie'].nil?
|
35
|
+
headers['Cookie'] = headers['Cookie'].sub(/_session=\S+/, '_session=[FILTERED]')
|
36
|
+
end
|
37
|
+
headers
|
38
|
+
end
|
39
|
+
|
40
|
+
def extract_session(request)
|
41
|
+
session_hash = {'session_id' => "", 'data' => {}}
|
42
|
+
|
43
|
+
if request.respond_to?(:session)
|
44
|
+
session = request.session
|
45
|
+
session_hash['session_id'] = request.session_options ? request.session_options[:id] : nil
|
46
|
+
session_hash['session_id'] ||= session.respond_to?(:session_id) ? session.session_id : session.instance_variable_get("@session_id")
|
47
|
+
session_hash['data'] = session.respond_to?(:to_hash) ? session.to_hash : session.instance_variable_get("@data") || {}
|
48
|
+
session_hash['session_id'] ||= session_hash['data'][:session_id]
|
49
|
+
session_hash['data'].delete(:session_id)
|
50
|
+
end
|
51
|
+
|
52
|
+
sanitize_unserializable_data(session_hash)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Crashdesk
|
2
|
+
|
3
|
+
class Crashlog
|
4
|
+
|
5
|
+
attr_accessor :options, :exception, :backtrace, :environment, :exception_class,
|
6
|
+
:exception_message, :context, :occurred_at,
|
7
|
+
:reporter
|
8
|
+
|
9
|
+
def initialize(exception, request, context, options = {})
|
10
|
+
self.options = options
|
11
|
+
|
12
|
+
# Anatomy of Exception
|
13
|
+
self.exception = exception
|
14
|
+
self.backtrace = Crashdesk::Backtrace.parse(exception.backtrace || caller)
|
15
|
+
self.exception_class = exception.class.name
|
16
|
+
self.exception_message = exception.message
|
17
|
+
|
18
|
+
# Environment
|
19
|
+
self.environment = Crashdesk::Environment.new(
|
20
|
+
:environment_name => options[:environment_name],
|
21
|
+
:project_root => Crashdesk.configure.project_root)
|
22
|
+
|
23
|
+
# Context
|
24
|
+
self.context = context
|
25
|
+
self.occurred_at = Time.now.utc.iso8601
|
26
|
+
|
27
|
+
# How to report?
|
28
|
+
self.reporter = options[:reporter] ||
|
29
|
+
Crashdesk::Reporter::Remote.new(:host => 'localhost',
|
30
|
+
:port => 4567) # Need to pass HTTP params
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_hash
|
34
|
+
{
|
35
|
+
:api_key => Crashdesk.configuration.api_key,
|
36
|
+
:hash_id => backtrace.hash_id,
|
37
|
+
:crc => backtrace.crc,
|
38
|
+
:occurred_at => occurred_at,
|
39
|
+
|
40
|
+
:environment => environment.to_hash,
|
41
|
+
|
42
|
+
:backtrace => backtrace.to_a,
|
43
|
+
:exception_class => self.exception_class,
|
44
|
+
:exception_message => self.exception_message,
|
45
|
+
|
46
|
+
:context => context.to_hash
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def report
|
51
|
+
json = Crashdesk::Serializer::Json.new(self.to_hash).process
|
52
|
+
reporter.run(json)
|
53
|
+
end
|
54
|
+
|
55
|
+
def crc
|
56
|
+
session_data.crc
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Crashdesk
|
4
|
+
|
5
|
+
class Environment
|
6
|
+
|
7
|
+
attr_reader :project_root, :environment_name, :framework_string
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
self.project_root = args[:project_root]
|
11
|
+
self.environment_name = args[:environment_name]
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_hash
|
15
|
+
{
|
16
|
+
:project_root => project_root,
|
17
|
+
:environment_name => environment_name,
|
18
|
+
:hostname => Socket.gethostname,
|
19
|
+
:language => 'ruby',
|
20
|
+
:language_version => RUBY_VERSION,
|
21
|
+
:language_platform => RUBY_PLATFORM
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_writer :project_root, :environment_name
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
|
4
|
+
module Crashdesk
|
5
|
+
module Reporter
|
6
|
+
|
7
|
+
module QueryParams
|
8
|
+
def self.encode(value, key = nil)
|
9
|
+
case value
|
10
|
+
when Hash then value.map { |k,v| encode(v, append_key(key,k)) }.join('&')
|
11
|
+
when Array then value.map { |v| encode(v, "#{key}[]") }.join('&')
|
12
|
+
when nil then ''
|
13
|
+
else
|
14
|
+
"#{key}=#{CGI.escape(value.to_s)}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def self.append_key(root_key, key)
|
20
|
+
root_key.nil? ? key : "#{root_key}[#{key.to_s}]"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Remote
|
25
|
+
NOTICES_URI = '/v1/crashes'.freeze
|
26
|
+
HTTP_ERRORS = [Timeout::Error,
|
27
|
+
Errno::EINVAL,
|
28
|
+
Errno::ECONNRESET,
|
29
|
+
EOFError,
|
30
|
+
Net::HTTPBadResponse,
|
31
|
+
Net::HTTPHeaderSyntaxError,
|
32
|
+
Net::ProtocolError,
|
33
|
+
Errno::ECONNREFUSED].freeze
|
34
|
+
HEADERS = {
|
35
|
+
'Content-type' => 'application/json',
|
36
|
+
'Accept' => 'application/json'
|
37
|
+
}
|
38
|
+
|
39
|
+
def initialize(options = {})
|
40
|
+
[ :proxy_host,
|
41
|
+
:proxy_port,
|
42
|
+
:proxy_user,
|
43
|
+
:proxy_pass,
|
44
|
+
:protocol,
|
45
|
+
:host,
|
46
|
+
:port,
|
47
|
+
:secure,
|
48
|
+
:use_system_ssl_cert_chain,
|
49
|
+
:http_open_timeout,
|
50
|
+
:http_read_timeout
|
51
|
+
].each do |option|
|
52
|
+
instance_variable_set("@#{option}", options[option])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def run(data)
|
57
|
+
http = setup_http_connection
|
58
|
+
headers = HEADERS.merge('X-Crashdesk-ApiKey' => Crashdesk.configuration.api_key)
|
59
|
+
|
60
|
+
response = begin
|
61
|
+
http.post(url.path, data, headers)
|
62
|
+
rescue *HTTP_ERRORS => e
|
63
|
+
logger.error "Unable to connect the Creashdesk server. HTTP Error=#{e}"
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
|
67
|
+
case response
|
68
|
+
when Net::HTTPSuccess then
|
69
|
+
logger.info "Success: #{response.class} #{response}"
|
70
|
+
else
|
71
|
+
logger.info "Failure: #{response.class} #{response}"
|
72
|
+
end
|
73
|
+
rescue => e
|
74
|
+
logger.error "Error sending: #{e.class} - #{e.message}\nBacktrace:\n#{e.backtrace.join("\n\t")}"
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
attr_reader :proxy_host,
|
79
|
+
:proxy_port,
|
80
|
+
:proxy_user,
|
81
|
+
:proxy_pass,
|
82
|
+
:protocol,
|
83
|
+
:host,
|
84
|
+
:port,
|
85
|
+
:secure,
|
86
|
+
:use_system_ssl_cert_chain,
|
87
|
+
:http_open_timeout,
|
88
|
+
:http_read_timeout
|
89
|
+
|
90
|
+
alias_method :secure?, :secure
|
91
|
+
alias_method :use_system_ssl_cert_chain?, :use_system_ssl_cert_chain
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def logger
|
96
|
+
Crashdesk.logger
|
97
|
+
end
|
98
|
+
|
99
|
+
def url
|
100
|
+
URI.parse("#{protocol}://#{host}:#{port}").merge(NOTICES_URI)
|
101
|
+
end
|
102
|
+
|
103
|
+
def protocol
|
104
|
+
'http'
|
105
|
+
end
|
106
|
+
|
107
|
+
def host
|
108
|
+
@host || 'crashde.sk'
|
109
|
+
end
|
110
|
+
|
111
|
+
def port
|
112
|
+
@port || 80
|
113
|
+
end
|
114
|
+
|
115
|
+
def setup_http_connection
|
116
|
+
http =
|
117
|
+
Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass).
|
118
|
+
new(url.host, url.port)
|
119
|
+
|
120
|
+
http.read_timeout = http_read_timeout
|
121
|
+
http.open_timeout = http_open_timeout
|
122
|
+
|
123
|
+
if secure?
|
124
|
+
http.use_ssl = true
|
125
|
+
http.ca_file = Crashdesk.configuration.ca_bundle_path
|
126
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
127
|
+
else
|
128
|
+
http.use_ssl = false
|
129
|
+
end
|
130
|
+
|
131
|
+
http
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Crashdesk
|
2
|
+
module Serializer
|
3
|
+
|
4
|
+
class Json
|
5
|
+
|
6
|
+
def initialize(data)
|
7
|
+
unless data.respond_to? :to_json
|
8
|
+
require 'json'
|
9
|
+
unless data.respond_to? :to_json
|
10
|
+
raise StandardError.new("You need a json gem/library installed to send errors to as JSON (Object.to_json not defined).
|
11
|
+
\nInstall json_pure, yajl-ruby, json-jruby, or the c-based json gem")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
@data = data
|
16
|
+
end
|
17
|
+
|
18
|
+
def process
|
19
|
+
@data.to_json
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/lib/crashdesk.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
require 'digest/md5'
|
5
|
+
|
6
|
+
require 'crashdesk/version'
|
7
|
+
require 'crashdesk/configuration'
|
8
|
+
|
9
|
+
require 'crashdesk/context_base'
|
10
|
+
require 'crashdesk/crashlog'
|
11
|
+
require 'crashdesk/backtrace'
|
12
|
+
require 'crashdesk/environment'
|
13
|
+
require 'crashdesk/reporters/remote'
|
14
|
+
require 'crashdesk/serializers/json'
|
15
|
+
|
16
|
+
module Crashdesk
|
17
|
+
|
18
|
+
class << self
|
19
|
+
LOG_PREFIX = "[Crashdesk] "
|
20
|
+
|
21
|
+
attr_writer :configuration
|
22
|
+
|
23
|
+
# Call this method to modify defaults for Crashdesk.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# Crashdesk.configure do |config|
|
27
|
+
# config.api_key = 'someapikey'
|
28
|
+
# end
|
29
|
+
def configure(silent = false)
|
30
|
+
yield(configuration) if block_given?
|
31
|
+
configuration
|
32
|
+
end
|
33
|
+
|
34
|
+
# The configuration object.
|
35
|
+
# @see Crashdesk.configure
|
36
|
+
def configuration
|
37
|
+
@configuration ||= Configuration.new
|
38
|
+
end
|
39
|
+
|
40
|
+
def log(message)
|
41
|
+
configuration.logger.info(LOG_PREFIX + message) if configuration.logger
|
42
|
+
end
|
43
|
+
|
44
|
+
# Main method how to build crashlog from exception, context, and environment
|
45
|
+
# @see Craslog.initialize
|
46
|
+
def crashlog(exception, request, context, options = {})
|
47
|
+
Crashlog.new(exception, request, context, options)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Crashdesk::Backtrace do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@backtrace_basic = File.read(File.join(File.dirname(__FILE__), 'stubs', 'backtrace_basic.txt'))
|
7
|
+
end
|
8
|
+
|
9
|
+
context "parsing raw backtrace to Backtrace object composed of Lines" do
|
10
|
+
it "backtrace as string" do
|
11
|
+
backtrace = Crashdesk::Backtrace.parse(@backtrace_basic)
|
12
|
+
|
13
|
+
backtrace.lines.length.should == 17
|
14
|
+
end
|
15
|
+
|
16
|
+
it "backtrace as array" do
|
17
|
+
backtrace = Array(@backtrace_basic.split(/\n\s*/))
|
18
|
+
backtrace = Crashdesk::Backtrace.parse(backtrace)
|
19
|
+
|
20
|
+
backtrace.lines.length.should == 17
|
21
|
+
end
|
22
|
+
|
23
|
+
it "backtrace with caller object" do
|
24
|
+
backtrace = Crashdesk::Backtrace.parse(caller)
|
25
|
+
backtrace.lines.should_not be_empty
|
26
|
+
backtrace.hash_id.should_not == 'd41d8cd98f00b204e9800998ecf8427e'
|
27
|
+
backtrace.crc.should_not == '0'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "backtrace with nil object" do
|
31
|
+
backtrace = Crashdesk::Backtrace.parse(nil)
|
32
|
+
backtrace.lines.should be_empty
|
33
|
+
backtrace.to_s.should be_empty
|
34
|
+
backtrace.hash_id.should == 'd41d8cd98f00b204e9800998ecf8427e'
|
35
|
+
backtrace.crc.should == '0'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "stripping backtrace from project root path" do
|
40
|
+
it "generate 2 hashes" do
|
41
|
+
backtrace = Crashdesk::Backtrace.parse(@backtrace_basic)
|
42
|
+
|
43
|
+
backtrace.hash_id.should == '00912f3bc04ea70cc305951c43c48332'
|
44
|
+
backtrace.crc.should == '2467818820'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "generate 2 hashes that must be unique" do
|
48
|
+
backtrace = Crashdesk::Backtrace.parse(@backtrace_basic)
|
49
|
+
backtrace_modified = Crashdesk::Backtrace.parse(@backtrace_basic + "1")
|
50
|
+
|
51
|
+
backtrace.should_not == backtrace_modified
|
52
|
+
backtrace.hash_id.should_not == backtrace_modified.hash_id
|
53
|
+
backtrace.crc.should_not == backtrace_modified.crc
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "serialization" do
|
58
|
+
it "should generate as array of lines" do
|
59
|
+
backtrace = Crashdesk::Backtrace.parse(@backtrace_basic)
|
60
|
+
backtrace.to_a.length.should == 17
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Crashdesk::Configuration do
|
4
|
+
|
5
|
+
context "with defaults" do
|
6
|
+
before do
|
7
|
+
@config = Crashdesk.configure
|
8
|
+
end
|
9
|
+
|
10
|
+
it "point to crashdes.sk host" do
|
11
|
+
@config[:host].should == 'crashde.sk'
|
12
|
+
@config.host.should == 'crashde.sk'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "port is 80" do
|
16
|
+
@config[:port].should == 80
|
17
|
+
@config.port.should == 80
|
18
|
+
end
|
19
|
+
|
20
|
+
it "protocol is HTTP" do
|
21
|
+
@config[:protocol].should == 'http'
|
22
|
+
@config.protocol.should == 'http'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with modifications" do
|
27
|
+
before do
|
28
|
+
@config = Crashdesk.configure do |c|
|
29
|
+
c.host = 'api.crashde.sk'
|
30
|
+
c.port = 443
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "point to crashdes.sk host" do
|
35
|
+
@config[:host].should == 'api.crashde.sk'
|
36
|
+
@config.host.should == 'api.crashde.sk'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "port is 80" do
|
40
|
+
@config[:port].should == 443
|
41
|
+
@config.port.should == 443
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
/Users/ladislav/Projects/personal/crashdesk-rails-test/spec/lib/crashdesk/backtrace_spec.rb:11:in `block (2 levels) in <top (required)>'
|
2
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/example.rb:80:in `instance_eval'
|
3
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/example.rb:80:in `block in run'
|
4
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/example.rb:173:in `with_around_hooks'
|
5
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/example.rb:77:in `run'
|
6
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:355:in `block in run_examples'
|
7
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:351:in `map'
|
8
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:351:in `run_examples'
|
9
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:337:in `run'
|
10
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'
|
11
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/command_line.rb:28:in `map'
|
12
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/command_line.rb:28:in `block in run'
|
13
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/reporter.rb:34:in `report'
|
14
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/command_line.rb:25:in `run'
|
15
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/runner.rb:80:in `run_in_process'
|
16
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/runner.rb:69:in `run'
|
17
|
+
/Users/ladislav/.rvm/gems/ruby-1.9.3-p194/gems/rspec-core-2.8.0/lib/rspec/core/runner.rb:10:in `block in autorun'
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: crashdesk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ladislav Martincik
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-26 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: crashdesk is the Ruby gem for containing core functionality for communication
|
15
|
+
with crashde.sk servers
|
16
|
+
email: info@crashde.sk
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/crashdesk/backtrace.rb
|
22
|
+
- lib/crashdesk/configuration.rb
|
23
|
+
- lib/crashdesk/context_base.rb
|
24
|
+
- lib/crashdesk/crashlog.rb
|
25
|
+
- lib/crashdesk/environment.rb
|
26
|
+
- lib/crashdesk/reporters/remote.rb
|
27
|
+
- lib/crashdesk/reporters/screen.rb
|
28
|
+
- lib/crashdesk/serializers/json.rb
|
29
|
+
- lib/crashdesk/version.rb
|
30
|
+
- lib/crashdesk.rb
|
31
|
+
- spec/backtrace_spec.rb
|
32
|
+
- spec/configuration_spec.rb
|
33
|
+
- spec/spec_helper.rb
|
34
|
+
- spec/stubs/backtrace_basic.txt
|
35
|
+
- crashdesk.gemspec
|
36
|
+
homepage: http://crashde.sk
|
37
|
+
licenses: []
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
requirements:
|
55
|
+
- json_pure, json-jruby or json gem required
|
56
|
+
rubyforge_project: crashdesk
|
57
|
+
rubygems_version: 1.8.24
|
58
|
+
signing_key:
|
59
|
+
specification_version: 3
|
60
|
+
summary: Crashde.sk is helping you track crashes of your application online
|
61
|
+
test_files: []
|