crashlog 0.0.2 → 1.0.0.rc1

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/Gemfile.lock CHANGED
@@ -8,7 +8,7 @@ GIT
8
8
  PATH
9
9
  remote: .
10
10
  specs:
11
- crashlog (0.0.1)
11
+ crashlog (1.0.0.rc1)
12
12
  activesupport
13
13
  crashlog-auth-hmac (~> 1.1.5)
14
14
  faraday
@@ -86,7 +86,7 @@ GEM
86
86
  multipart-post (1.1.5)
87
87
  pg (0.14.0)
88
88
  polyglot (0.3.3)
89
- rabl (0.7.0)
89
+ rabl (0.7.1)
90
90
  activesupport (>= 2.3.14)
91
91
  multi_json (~> 1.0)
92
92
  rack (1.4.1)
data/INSTALL CHANGED
@@ -3,8 +3,8 @@
3
3
  You should have something like this in config/initializers/crashlog.rb.
4
4
 
5
5
  CrashLog.configure do |config|
6
- config.api_key = 'AhHusJhJHAjJajA'
7
- config.project_id = 'ca9e5931-310f-4897-90c2-d0626f0f2a01'
6
+ config.api_key = 'API_KEY'
7
+ config.secret = 'SECRET'
8
8
  end
9
9
 
10
10
  (Please note that this configuration should be in a global configuration, and
@@ -18,5 +18,4 @@ this rake task (from RAILS_ROOT):
18
18
  rake crashlog:test
19
19
 
20
20
  If everything is configured properly, that task will send a notice to CrashLog
21
- which will be visible immediately.
22
-
21
+ which will be visible immediately.
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # CrashLog
2
2
 
3
+ [![Build Status](https://secure.travis-ci.org/crashlog/crashlog.png)](http://travis-ci.org/crashlog/crashlog)
4
+
3
5
  CrashLog is a exception tracking and notification service that gives you unparalleled
4
6
  insight into issues occurring within your production applications, in realtime.
5
7
 
data/Rakefile CHANGED
@@ -11,5 +11,4 @@ require "rspec/core/rake_task"
11
11
  desc "Run all examples"
12
12
  RSpec::Core::RakeTask.new
13
13
 
14
- task :default => :spec
15
-
14
+ task :default => :spec
@@ -39,14 +39,14 @@ module CrashLog
39
39
  #
40
40
  # Get this from your projects configuration page within http://CrashLog.io
41
41
  :api_key => nil,
42
- :project_id => nil,
42
+ :secret => nil,
43
43
 
44
44
  # Stages (environments) which we consider to be in a production environment
45
45
  # and thus you want to be sent notifications for.
46
46
  :release_stages => ['staging', 'production'],
47
47
 
48
48
  # The name of the current stage
49
- :stage => 'development',
49
+ :stage => 'production',
50
50
 
51
51
  # Project Root directory
52
52
  :project_root => nil,
@@ -127,7 +127,9 @@ module CrashLog
127
127
 
128
128
  # Internal
129
129
  # Do not change unless you know what this does.
130
- :service_name => 'CrashLog'
130
+ :service_name => 'CrashLog',
131
+
132
+ :json_parser => :yajl
131
133
 
132
134
  def root
133
135
  fetch(:project_root)
@@ -147,7 +149,7 @@ module CrashLog
147
149
 
148
150
  # Release stages are stages which send exceptions
149
151
  def release_stage?
150
- release_stages.include?(stage)
152
+ Array(release_stages).include?(stage)
151
153
  end
152
154
 
153
155
  # Set the current stage
@@ -159,9 +161,13 @@ module CrashLog
159
161
  #
160
162
  # Returns true if all required keys are provided, otherwise false
161
163
  def valid?
162
- [:api_key, :project_id, :host, :port].all? do |key|
163
- !__send__(key).nil?
164
- end
164
+ invalid_keys.empty?
165
+ end
166
+
167
+ def invalid_keys
168
+ [:api_key, :secret, :host, :port].map do |key|
169
+ key if send(key).nil?
170
+ end.compact
165
171
  end
166
172
 
167
173
  def ignored?(exception)
@@ -36,7 +36,10 @@ module CrashLog
36
36
  end
37
37
 
38
38
  def deliver
39
- Reporter.new(config).notify(self.body)
39
+ reporter = Reporter.new(config)
40
+ if reporter.notify(self.body)
41
+ reporter.result
42
+ end
40
43
  end
41
44
 
42
45
  attr_reader :event, :backtrace, :exception_object, :environment, :context
@@ -21,7 +21,7 @@ module CrashLog
21
21
 
22
22
  CrashLog.configure do |config|
23
23
  config.logger = rails_logger
24
- config.release_stage = RAILS_ENV if defined?(RAILS_ENV)
24
+ config.stage = RAILS_ENV if defined?(RAILS_ENV)
25
25
  config.project_root = RAILS_ROOT if defined?(RAILS_ROOT)
26
26
  config.framework = "Rails: #{::Rails::VERSION::STRING}" if defined?(::Rails::VERSION)
27
27
  end
@@ -7,9 +7,9 @@ module CrashLog
7
7
 
8
8
  config.after_initialize do
9
9
  CrashLog.configure do |config|
10
- config.logger ||= ::Rails.logger
11
- config.stage ||= ::Rails.env
12
- config.project_root ||= ::Rails.root
10
+ config.logger = ::Rails.logger
11
+ config.stage = ::Rails.env
12
+ config.project_root = ::Rails.root
13
13
  config.framework = "Rails: #{::Rails::VERSION::STRING}"
14
14
  end
15
15
 
@@ -1,6 +1,7 @@
1
1
  require 'faraday'
2
2
  require 'faraday/request/hmac_authentication'
3
3
  require 'uuid'
4
+ require 'multi_json'
4
5
  require 'yajl'
5
6
 
6
7
  module CrashLog
@@ -18,11 +19,12 @@ module CrashLog
18
19
  @endpoint = config.endpoint
19
20
  @announce_endpoint = config.announce == true ?
20
21
  config.announce_endpoint : nil
22
+ MultiJson.use(config.json_parser || :yajl)
21
23
  end
22
24
 
23
25
  def notify(payload)
24
- #return if dry_run?
25
- #MultiJson.use(:yajl)
26
+ return if dry_run?
27
+
26
28
  response = post(endpoint, MultiJson.encode({:payload => payload}))
27
29
  @response = response
28
30
  report_result(response.body)
@@ -30,6 +32,7 @@ module CrashLog
30
32
  rescue => e
31
33
  log_exception e
32
34
  error("Sending exception failed due to a connectivity issue")
35
+ nil
33
36
  end
34
37
 
35
38
  def announce
@@ -38,13 +41,11 @@ module CrashLog
38
41
 
39
42
  response = post(config.announce_endpoint, JSON.dump(identification_hash))
40
43
  if response.status == 201
41
- JSON.load(response.body).symbolize_keys.fetch(:application, 'Default')
44
+ JSON.load(response.body).symbolize_keys.fetch(:application_name, 'Default')
42
45
  else
43
- false
46
+ nil
44
47
  end
45
48
  rescue => e
46
- # We only want to log our mess when testing
47
- log_exception(e) # if respond_to?(:should)
48
49
  error("Failed to announce application launch")
49
50
  nil
50
51
  end
@@ -54,7 +55,7 @@ module CrashLog
54
55
  end
55
56
 
56
57
  def url
57
- URI.parse("#{scheme}://#{host}:#{port}")
58
+ URI.parse("#{scheme}://#{host}:#{port}").to_s
58
59
  end
59
60
 
60
61
  def identification_hash
@@ -64,10 +65,6 @@ module CrashLog
64
65
  }
65
66
  end
66
67
 
67
- def print_result
68
-
69
- end
70
-
71
68
  def dry_run?
72
69
  config.dry_run == true
73
70
  end
@@ -75,18 +72,15 @@ module CrashLog
75
72
  def post(endpoint, body)
76
73
  connection.post do |req|
77
74
  req.url(endpoint)
78
- # req.sign!(config.project_id, config.api_key)
79
75
  req.headers['Content-Type'] = 'application/json'
80
76
  req.body = body
81
77
  end
82
78
  end
83
79
 
84
- # private
85
-
86
80
  def connection
87
81
  @connection ||= begin
88
82
  Faraday.new(:url => url) do |faraday|
89
- faraday.request :hmac_authentication, config.project_id, config.api_key, {:service_id => config.service_name}
83
+ faraday.request :hmac_authentication, config.api_key, config.secret, {:service_id => config.service_name}
90
84
  faraday.adapter(adapter)
91
85
  faraday.request :url_encoded
92
86
  # faraday.request :token_auth, config.api_key
@@ -1,3 +1,3 @@
1
1
  module CrashLog
2
- VERSION = "0.0.2"
2
+ VERSION = "1.0.0.rc1"
3
3
  end
data/lib/crash_log.rb CHANGED
@@ -53,7 +53,15 @@ module CrashLog
53
53
  #
54
54
  # Returns true if successful, otherwise false
55
55
  def notify(exception, context = {})
56
- send_notification(exception, context)
56
+ send_notification(exception, context).tap do |notification|
57
+ if notification
58
+ info "Event sent to CrashLog.io"
59
+ info "Event URL: http://crashlog.io/locate/#{notification[:location_id]}" if notification.has_key?(:location_id)
60
+ else
61
+ error "Failed to send event to CrashLog.io"
62
+ log_exception(exception)
63
+ end
64
+ end
57
65
  end
58
66
 
59
67
  # Sends the notice unless it is one of the default ignored exceptions.
@@ -66,7 +74,7 @@ module CrashLog
66
74
  application = CrashLog::Reporter.new(configuration).announce
67
75
 
68
76
  if application
69
- info("Initialized and ready to handle exceptions for #{application}")
77
+ info("Configured correctly and ready to handle exceptions for '#{application}'")
70
78
  else
71
79
  error("Failed to report for duty, your application failed to authenticate correctly with stdin.crashlog.io")
72
80
  end
@@ -74,12 +82,15 @@ module CrashLog
74
82
 
75
83
  # Configure the gem to send notifications, at the very least an api_key is
76
84
  # required.
77
- def configure
78
- yield(configuration) if block_given?
79
- if configuration.valid?
80
- report_for_duty!
81
- else
82
- error('Not configured correctly')
85
+ def configure(&block)
86
+ if block_given?
87
+ yield(configuration)
88
+
89
+ if configuration.valid?
90
+ report_for_duty!
91
+ elsif !configuration.invalid_keys.include?(:api_key)
92
+ error("Not configured correctly. Missing the following keys: #{configuration.invalid_keys.join(', ')}")
93
+ end
83
94
  end
84
95
  end
85
96
 
@@ -111,7 +122,9 @@ module CrashLog
111
122
  private
112
123
 
113
124
  def send_notification(exception, context = {})
114
- build_payload(exception, context).deliver! if live?
125
+ if live?
126
+ build_payload(exception, context).deliver!
127
+ end
115
128
  end
116
129
 
117
130
  def build_payload(exception, context = {})
@@ -26,10 +26,6 @@ module Faraday
26
26
  request[:body]
27
27
  end
28
28
 
29
- # def request_path(request)
30
- # URI.parse(request[:url]).path
31
- # end
32
-
33
29
  def request_path(request)
34
30
  URI.parse(request[:url].to_s).path
35
31
  end
@@ -53,8 +49,7 @@ module Faraday
53
49
 
54
50
  # Public
55
51
  def call(env)
56
- env[:request_headers][KEY] ||= hmac_auth_header(env).to_s #if sign_request?
57
- puts env[:request_headers]
52
+ env[:request_headers][KEY] ||= hmac_auth_header(env).to_s if sign_request?
58
53
  @app.call(env)
59
54
  end
60
55
 
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'logger'
4
+ require 'fileutils'
5
+
6
+ RAILS_ENV = "production"
7
+ RAILS_ROOT = FileUtils.pwd
8
+ RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
9
+
10
+ $: << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
11
+ require 'crashlog'
12
+ require File.expand_path('../../rails/init', __FILE__)
13
+
14
+ fail "Please supply an API Key as the first argument" if ARGV.empty?
15
+
16
+ host = ARGV[3]
17
+ host ||= "stdin.crashlog.io"
18
+
19
+ secure = (ARGV[2] == "secure")
20
+
21
+ exception = begin
22
+ raise "Testing crashlog notifier with secure = #{secure}. If you can see this, it works."
23
+ rescue => foo
24
+ foo
25
+ end
26
+
27
+ CrashLog.configure do |config|
28
+ config.api_key = ARGV[0]
29
+ config.secret = ARGV[1]
30
+ config.scheme = secure ? 'https' : 'http'
31
+ config.host = host
32
+ config.service_name = 'Staging'
33
+ end
34
+
35
+ puts "Configuration:"
36
+ CrashLog.configuration.each do |key, value|
37
+ puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55))
38
+ end
39
+ puts "Sending #{secure ? "" : "in"}secure notification to project with key #{ARGV.first}"
40
+ CrashLog.notify(exception)
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe CrashLog::Configuration do
4
+ context 'release stage' do
5
+ it 'includes production' do
6
+ subject.release_stages.should include 'production'
7
+ end
8
+
9
+ it 'includes staging' do
10
+ subject.release_stages.should include 'staging'
11
+ end
12
+
13
+ it 'is true if production' do
14
+ subject.stage = 'production'
15
+ subject.release_stage?.should be_true
16
+ end
17
+
18
+ it 'is true if staging' do
19
+ subject.stage = 'staging'
20
+ subject.release_stage?.should be_true
21
+ end
22
+
23
+ it 'is false in development' do
24
+ subject.stage = 'development'
25
+ subject.release_stage?.should be_false
26
+ end
27
+ end
28
+
29
+ context 'valid?' do
30
+ it 'is valid if api_key and secret are present' do
31
+ subject.should_not be_valid
32
+ subject.api_key = 'API_KEY'
33
+ subject.secret = 'SECRET'
34
+ subject.should be_valid
35
+ end
36
+ end
37
+ end
@@ -5,7 +5,7 @@ describe CrashLog::Reporter do
5
5
 
6
6
  let(:config) {
7
7
  CrashLog::Configuration.new.tap do |config|
8
- config.project_id = 'PROJECT_ID'
8
+ config.secret = 'SECRET'
9
9
  config.api_key = 'API_KEY'
10
10
  # config.adapter = test_adapter
11
11
  config.scheme = 'http'
@@ -44,7 +44,7 @@ describe CrashLog::Reporter do
44
44
  end
45
45
 
46
46
  let(:announce_response) do
47
- {:application => "CrashLog Test"}
47
+ {:application_name=> "CrashLog Test"}
48
48
  end
49
49
 
50
50
  let(:positive_response_json) { positive_response.to_json }
@@ -66,7 +66,7 @@ describe CrashLog::Reporter do
66
66
  before do
67
67
  test_connection = Faraday.new(:url => subject.url) do |builder|
68
68
  builder.adapter :test, stubs
69
- builder.request :hmac_authentication, 'PROJECT_ID', 'SECRET', {:service_id => 'CrashLog'}
69
+ builder.request :hmac_authentication, 'API_KEY', 'SECRET', {:service_id => 'CrashLog'}
70
70
  builder.request :url_encoded
71
71
  end
72
72
 
@@ -84,14 +84,22 @@ describe CrashLog::Reporter do
84
84
  end
85
85
 
86
86
  it 'makes a post request' do
87
- subject.send(:connection).should_receive(:post).once
87
+ response = double("Post", success?: true)
88
+ response.stub(:body).and_return(positive_response_json)
89
+ subject.send(:connection).should_receive(:post).once.and_return(response)
88
90
  subject.notify(payload)
89
91
  end
90
92
 
91
93
  it 'authenticates request with HMAC' do
94
+ time_travel_to "2012-08-01 00:00:00 UTC"
95
+
92
96
  subject.notify(payload).should be_true
97
+
93
98
  subject.response.env[:request_headers]['Authorization'].should ==
94
- CrashLog::AuthHMAC.new({}, {:service_id => 'CrashLog'}).authorization(subject.response.env, 'PROJECT_ID', 'SECRET')
99
+ CrashLog::AuthHMAC.new({}, {
100
+ :service_id => 'CrashLog',
101
+ :signature => Faraday::Request::HMACAuthentication::CanonicalString
102
+ }).authorization(subject.response.env, 'API_KEY', 'SECRET')
95
103
  stubs.verify_stubbed_calls
96
104
  end
97
105
 
@@ -96,7 +96,7 @@ describe CrashLog do
96
96
  CrashLog::Reporter.any_instance.stub(:announce).and_return("Test Application")
97
97
  logger = stub('Logger')
98
98
  logger.should_receive(:info).
99
- with("** [CrashLog] Initialized and ready to handle exceptions for Test Application")
99
+ with("** [CrashLog] Configured correctly and ready to handle exceptions for 'Test Application'")
100
100
 
101
101
  CrashLog.stub(:logger).and_return(logger)
102
102
  CrashLog.report_for_duty!
@@ -2,5 +2,6 @@ require 'crashlog'
2
2
 
3
3
  CrashLog.configure do |config|
4
4
  config.api_key = "API_KEY"
5
+ config.secret = "SECRET"
5
6
  config.dry_run = true
6
7
  end
@@ -5,6 +5,10 @@ describe 'Rescue from within a Rails 3.x controller' do
5
5
  include RSpec::Rails::RequestExampleGroup
6
6
  include Rack::Test::Methods
7
7
 
8
+ it 'is testing tails 3.x' do
9
+ Rails.version.should =~ /^3\./
10
+ end
11
+
8
12
  describe 'dummy app' do
9
13
  it 'should response nicely to index' do
10
14
  get '/'
data/spec/spec_helper.rb CHANGED
@@ -17,7 +17,5 @@ Dir[File.expand_path("../support/*.rb", __FILE__)].each { |file| require file }
17
17
 
18
18
  RSpec.configure do |config|
19
19
  config.mock_with :rspec
20
-
21
- config.before do
22
- end
20
+ config.include Delorean
23
21
  end
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crashlog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
5
- prerelease:
4
+ version: 1.0.0.rc1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - TestPilot CI
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-06 00:00:00.000000000 Z
12
+ date: 2012-09-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &70175970544380 !ruby/object:Gem::Requirement
16
+ requirement: &70309383792940 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70175970544380
24
+ version_requirements: *70309383792940
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: faraday
27
- requirement: &70175970543240 !ruby/object:Gem::Requirement
27
+ requirement: &70309383792280 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70175970543240
35
+ version_requirements: *70309383792280
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: crashlog-auth-hmac
38
- requirement: &70175970541460 !ruby/object:Gem::Requirement
38
+ requirement: &70309383791780 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.1.5
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70175970541460
46
+ version_requirements: *70309383791780
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: yajl-ruby
49
- requirement: &70175970540800 !ruby/object:Gem::Requirement
49
+ requirement: &70309383791260 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70175970540800
57
+ version_requirements: *70309383791260
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rabl
60
- requirement: &70175970540040 !ruby/object:Gem::Requirement
60
+ requirement: &70309383806820 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.6.14
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70175970540040
68
+ version_requirements: *70309383806820
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: uuid
71
- requirement: &70175970539280 !ruby/object:Gem::Requirement
71
+ requirement: &70309383806220 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70175970539280
79
+ version_requirements: *70309383806220
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: hashr
82
- requirement: &70175970538820 !ruby/object:Gem::Requirement
82
+ requirement: &70309383805760 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *70175970538820
90
+ version_requirements: *70309383805760
91
91
  description: CrashLog Exception reporter
92
92
  email:
93
93
  - support@crashlog.io
@@ -129,7 +129,9 @@ files:
129
129
  - lib/faraday/request/hmac_authentication.rb
130
130
  - lib/rails/generators/crashlog/crashlog_generator.rb
131
131
  - rails/init.rb
132
+ - script/integration_test
132
133
  - spec/crash_log/backtrace_spec.rb
134
+ - spec/crash_log/configuration_spec.rb
133
135
  - spec/crash_log/initializer_spec.rb
134
136
  - spec/crash_log/payload_spec.rb
135
137
  - spec/crash_log/reporter_spec.rb
@@ -188,9 +190,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
188
190
  required_rubygems_version: !ruby/object:Gem::Requirement
189
191
  none: false
190
192
  requirements:
191
- - - ! '>='
193
+ - - ! '>'
192
194
  - !ruby/object:Gem::Version
193
- version: '0'
195
+ version: 1.3.1
194
196
  requirements: []
195
197
  rubyforge_project:
196
198
  rubygems_version: 1.8.15
@@ -199,6 +201,7 @@ specification_version: 3
199
201
  summary: CrashLog is an exception handler for production applications
200
202
  test_files:
201
203
  - spec/crash_log/backtrace_spec.rb
204
+ - spec/crash_log/configuration_spec.rb
202
205
  - spec/crash_log/initializer_spec.rb
203
206
  - spec/crash_log/payload_spec.rb
204
207
  - spec/crash_log/reporter_spec.rb