hydraulic_brake 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'rubygems'
4
+ require 'hydraulic_brake/version'
5
+ require 'hydraulic_brake/configuration'
6
+ require 'hydraulic_brake/notice'
7
+ require 'hydraulic_brake/sender'
8
+ require 'hydraulic_brake/backtrace'
9
+
10
+ module HydraulicBrake
11
+ API_VERSION = "2.3"
12
+ LOG_PREFIX = "** [HydraulicBrake] "
13
+
14
+ HEADERS = {
15
+ 'Content-type' => 'text/xml',
16
+ 'Accept' => 'text/xml, application/xml'
17
+ }
18
+
19
+ class << self
20
+ # The sender object is responsible for delivering formatted data to the
21
+ # Airbrake server. Must respond to #send_to_airbrake. See
22
+ # HydraulicBrake::Sender.
23
+ attr_accessor :sender
24
+
25
+ # A HydraulicBrake configuration object. Must act like a hash and return
26
+ # sensible values for all HydraulicBrake configuration options. See
27
+ # HydraulicBrake::Configuration.
28
+ attr_writer :configuration
29
+
30
+ # Tell the log that the Notifier is good to go
31
+ def report_ready
32
+ write_verbose_log("Notifier #{VERSION} ready to catch errors")
33
+ end
34
+
35
+ # Prints out the environment info to the log for debugging help
36
+ def report_environment_info
37
+ write_verbose_log("Environment Info: #{environment_info}")
38
+ end
39
+
40
+ # Prints out the response body from Airbrake for debugging help
41
+ def report_response_body(response)
42
+ write_verbose_log("Response from Airbrake: \n#{response}")
43
+ end
44
+
45
+ # Prints out the details about the notice that wasn't sent to server
46
+ def report_notice(notice)
47
+ write_verbose_log("Notice details: \n#{notice}")
48
+ end
49
+
50
+ # Returns the Ruby version, Rails version, and current Rails environment
51
+ def environment_info
52
+ info = "[Ruby: #{RUBY_VERSION}]"
53
+ info << " [#{configuration.framework}]" if configuration.framework
54
+ info << " [Env: #{configuration.environment_name}]" if configuration.environment_name
55
+ end
56
+
57
+ # Writes out the given message to the #logger
58
+ def write_verbose_log(message)
59
+ logger.debug LOG_PREFIX + message if logger
60
+ end
61
+
62
+ # Look for the Rails logger currently defined
63
+ def logger
64
+ self.configuration.logger
65
+ end
66
+
67
+ # Call this method to modify defaults in your initializers.
68
+ #
69
+ # @example
70
+ # HydraulicBrake.configure do |config|
71
+ # config.api_key = '1234567890abcdef'
72
+ # config.secure = false
73
+ # end
74
+ def configure(silent = false)
75
+ yield(configuration)
76
+ self.sender = Sender.new(configuration)
77
+ report_ready unless silent
78
+ self.sender
79
+ end
80
+
81
+ # The configuration object.
82
+ # @see HydraulicBrake.configure
83
+ def configuration
84
+ @configuration ||= Configuration.new
85
+ end
86
+
87
+ # Sends an exception manually using this method, even when you are not in a
88
+ # controller.
89
+ #
90
+ # @param [Exception] exception The exception you want to notify Airbrake
91
+ # about
92
+ # @param [Hash] opts Data that will be sent to Airbrake
93
+ #
94
+ # @option opts [String] :api_key The API key for this project. The API key
95
+ # is a unique identifier that Airbrake uses for identification
96
+ # @option opts [String] :error_message The error returned by the exception
97
+ # (or the message you want to log)
98
+ # @option opts [String] :backtrace A backtrace, usually obtained with
99
+ # +caller+
100
+ # @option opts [String] :session_data The contents of the user's session
101
+ # @option opts [String] :environment_name The application environment name
102
+ def notify(exception, opts = {})
103
+ send_notice(build_notice_for(exception, opts))
104
+ end
105
+
106
+ def build_lookup_hash_for(exception, options = {})
107
+ notice = build_notice_for(exception, options)
108
+
109
+ result = {}
110
+ result[:action] = notice.action rescue nil
111
+ result[:component] = notice.component rescue nil
112
+ result[:error_class] = notice.error_class if notice.error_class
113
+ result[:environment_name] = 'production'
114
+
115
+ unless notice.backtrace.lines.empty?
116
+ result[:file] = notice.backtrace.lines.first.file
117
+ result[:line_number] = notice.backtrace.lines.first.number
118
+ end
119
+
120
+ result
121
+ end
122
+
123
+ private
124
+
125
+ def send_notice(notice)
126
+ if configuration.public?
127
+ sender.send_to_airbrake(notice)
128
+ end
129
+ end
130
+
131
+ def build_notice_for(exception, opts = {})
132
+ exception = unwrap_exception(exception)
133
+ opts = opts.merge(:exception => exception) if exception.is_a?(Exception)
134
+ opts = opts.merge(exception.to_hash) if exception.respond_to?(:to_hash)
135
+ Notice.new(configuration.merge(opts))
136
+ end
137
+
138
+ def unwrap_exception(exception)
139
+ if exception.respond_to?(:original_exception)
140
+ exception.original_exception
141
+ elsif exception.respond_to?(:continued_exception)
142
+ exception.continued_exception
143
+ else
144
+ exception
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,63 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module HydraulicBrakeTasks
5
+
6
+ # Alerts Airbrake of a deploy.
7
+ #
8
+ # @param [Hash] opts Data about the deploy that is set to Airbrake
9
+ #
10
+ # @option opts [String] :api_key Api key of you Airbrake application
11
+ # @option opts [String] :env Environment of the deploy (production, staging)
12
+ # @option opts [String] :scm_revision The given revision/sha that is being deployed
13
+ # @option opts [String] :scm_repository Address of your repository to help with code lookups
14
+ # @option opts [String] :local_username Who is deploying
15
+ def self.deploy(opts = {})
16
+ api_key = opts.delete(:api_key) || HydraulicBrake.configuration.api_key
17
+ if api_key.empty?
18
+ puts "I don't seem to be configured with an API key. Please check your configuration."
19
+ return false
20
+ end
21
+
22
+ if opts[:env].empty?
23
+ puts "I don't know to which environment you are deploying (use the TO=production option)."
24
+ return false
25
+ end
26
+
27
+ dry_run = opts.delete(:dry_run)
28
+ params = {'api_key' => api_key}
29
+ opts.each {|k,v| params["deploy[#{k}]"] = v }
30
+
31
+ host = HydraulicBrake.configuration.host
32
+ port = HydraulicBrake.configuration.port
33
+
34
+ proxy = Net::HTTP.Proxy(HydraulicBrake.configuration.proxy_host,
35
+ HydraulicBrake.configuration.proxy_port,
36
+ HydraulicBrake.configuration.proxy_user,
37
+ HydraulicBrake.configuration.proxy_pass)
38
+ http = proxy.new(host, port)
39
+
40
+
41
+
42
+ # Handle Security
43
+ if HydraulicBrake.configuration.secure?
44
+ http.use_ssl = true
45
+ http.ca_file = HydraulicBrake.configuration.ca_bundle_path
46
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
47
+ end
48
+
49
+ post = Net::HTTP::Post.new("/deploys.txt")
50
+ post.set_form_data(params)
51
+
52
+ if dry_run
53
+ puts http.inspect, params.inspect
54
+ return true
55
+ else
56
+ response = http.request(post)
57
+
58
+ puts response.body
59
+ return Net::HTTPSuccess === response
60
+ end
61
+ end
62
+ end
63
+
@@ -0,0 +1,34 @@
1
+ Airbrake Resources
2
+ ==================
3
+
4
+ Airbrake has an SSL mode available to paying plans. SSL Certificate Authority (CA) certificates are not kept current by default on many environments. When CA certs are stale, Airbrake cannot verify Airbrake's production SSL cert and error reports fail. To avoid this, we now package local CA certs. The production of these certs is detailed here.
5
+
6
+ Building ca-bundle.crt
7
+ ----------------------
8
+
9
+ From https://gist.github.com/996292.
10
+
11
+ If you want to use curl or net-http/open-uri to access https resources, you will often (always?) get an error, because they don't have the large number of root certificates installed that web browsers have.
12
+
13
+ You can manually install the root certs, but first you have to get them from somewhere. [This article](http://notetoself.vrensk.com/2008/09/verified-https-in-ruby/) gives a nice description of how to do that. The [source of the cert files](http://curl.haxx.se/ca/cacert.pem) it points to is hosted by the curl project, who kindly provide it in the .pem format.
14
+
15
+ **problem:** Sadly, ironically, and comically, it's not possible to access that file via https! Luckily, the awesome curl project does provide us with the script that they use to produce the file, so we can do it securely ourselves. Here's how.
16
+
17
+ 1. `git clone https://github.com/bagder/curl.git`
18
+ 2. `cd curl/lib`
19
+ 3. edit `mk-ca-bundle.pl` and change:
20
+
21
+ ```perl
22
+ my $url = 'http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1';
23
+ ```
24
+
25
+ to
26
+
27
+ ```perl
28
+ my $url = 'https://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1';
29
+ ```
30
+
31
+ (change `http` to `https`)
32
+ 4. `./mk-ca-bundle.pl`
33
+
34
+ Ta da!