custos_notifier 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,175 @@
1
+ require 'rubygems'
2
+ require 'rack'
3
+ require 'rest-client'
4
+
5
+ require 'custos_notifier/configuration'
6
+ require 'custos_notifier/rack'
7
+
8
+ require "custos_notifier/railtie" if defined?(Rails::Railtie)
9
+
10
+ module CustosNotifier
11
+
12
+ class << self
13
+
14
+ attr_accessor :configuration
15
+
16
+ # Notify Custos service about raised exceptions. Exception will be ignored if notifier is
17
+ # configured with "development" stage. Raised exception is passed to this method, additional
18
+ # request attributes can be passed.
19
+ # Very simple example you can find in <tt>CustosNotifier::Rack</tt> middleware.
20
+ # Example:
21
+ # begin
22
+ # raise "My example exception"
23
+ # rescue => ex
24
+ # CustosNotifier.notify ex, :rack_env => env
25
+ # end
26
+ #
27
+ # exception:: Exception ancestors
28
+ # options:: Hash, default empty hash.
29
+ def notify(exception, options = {})
30
+ return if ["development", "test"].include? configuration.stage.downcase
31
+
32
+ options[:exception] = exception
33
+ notice = Notice.new(options)
34
+
35
+ url = URI.parse("#{ configuration.url }/errors")
36
+ RestClient.post(url.to_s, notice.to_param)
37
+ end
38
+
39
+
40
+ # Configure Custos notifier. Sets configuration options based on passed block.
41
+ # Example:
42
+ # CustosNotifier.configure do |config|
43
+ # config.url = "blah.foo.bar'
44
+ # config.project = 'awsome'
45
+ # config.stage = 'production'
46
+ # config.api_key = 'secret'
47
+ # end
48
+ #
49
+ # returns:: Configuration
50
+ def configure
51
+ self.configuration ||= Configuration.new
52
+ yield(configuration)
53
+ self.configuration.stage ||= detect_stage
54
+ configuration
55
+ end
56
+
57
+
58
+ protected
59
+
60
+
61
+ # Try to auto-detect stage. If detection is impossible method returns <tt>nil</tt>.
62
+ def detect_stage
63
+ ENV['RACK_ENV'] || ENV['RAILS_ENV'] || Rails.env
64
+ rescue NameError
65
+ nil
66
+ end
67
+
68
+ end
69
+
70
+
71
+ # Mainly goal of this class is evaulate HTTP request attributes and build a hash object containing
72
+ # all parameters needed to post error to Custos Service.
73
+ class Notice
74
+
75
+ attr_reader :args
76
+ attr_reader :parameters
77
+
78
+ def initialize(args)
79
+ @args = args
80
+ @exception = args[:exception]
81
+
82
+ @exception_class = @exception.class.to_s
83
+ @message = @exception.message
84
+ @backtrace = @exception.backtrace.join("\n")
85
+ @server = `hostname -s`.chomp
86
+ @source = ""
87
+ @process_id = $$
88
+ @parameters = rack_env(:params).inspect || {}.inspect
89
+ @request_uri = rack_env(:url) || ""
90
+ @document_root = rack_env(:env) { |env| env["DOCUMENT_ROOT"] } || ""
91
+ @content_length = rack_env(:env) { |env| env["DOCUMENT_ROOT"] } || ""
92
+ @http_accept = rack_env(:env) { |env| env["HTTP_ACCEPT"] } || ""
93
+ @http_method = rack_env(:request_method)
94
+ @http_cookie = rack_env(:env) { |env| env["HTTP_COOKIE"] } || ""
95
+ @http_host = rack_env(:host) || ""
96
+ @http_referer = rack_env(:referer) || ""
97
+ @user_agent = rack_env(:user_agent) || ""
98
+ @path_info = rack_env(:path_info) || ""
99
+ @query_string = rack_env(:query_string) || ""
100
+ @connection = rack_env(:env) { |env| env["HTTP_CONNECTION"] } || ""
101
+ @server_name = rack_env(:env) { |env| env["SERVER_NAME"] } || ""
102
+ end
103
+
104
+
105
+ # Method builds (based on parameters passed to constructor) a parameter hash which i posted
106
+ # to Custos service.
107
+ #
108
+ # returns:: Hash
109
+ def to_param
110
+ {
111
+ :project => CustosNotifier.configuration.project,
112
+ :api_key => CustosNotifier.configuration.api_key,
113
+ :error => {
114
+ :exception_class => @exception_class,
115
+ :message => @message,
116
+ :stage => CustosNotifier.configuration.stage,
117
+ :backtrace => @backtrace,
118
+ :server => @server,
119
+ :source => @source,
120
+ :process_id => @process_id,
121
+ :request => {
122
+ :uri => @request_uri,
123
+ :parameters => @parameters,
124
+ :document_root => @document_root,
125
+ :content_length => @content_length,
126
+ :http_accept => @http_accept,
127
+ :http_cookie => @http_cookie,
128
+ :http_host => @http_host,
129
+ :http_referer => @http_referer,
130
+ :user_agent => @user_agent,
131
+ :path_info => @path_info,
132
+ :query_string => @query_string,
133
+ :connection => @connection,
134
+ :server_name => @server_name,
135
+ :http_method => @http_method
136
+ }
137
+ }
138
+ }
139
+ end
140
+
141
+
142
+ protected
143
+
144
+
145
+ def request
146
+ @args[:request] || rack_request
147
+ end
148
+
149
+
150
+ # Get a value from <tt>Rack</tt> request object. Block can be passed to method and it will be
151
+ # evaluated on <tt>method's</tt> return.
152
+ def rack_env(method)
153
+ return unless request
154
+ value = request.send(method)
155
+ if block_given?
156
+ yield(value) if block_given?
157
+ else
158
+ value
159
+ end
160
+ end
161
+
162
+
163
+ # Method returns <tt>Rack</tt> request object based on <tt>self.args[:rack_env]</tt> values.
164
+ # If there aren't values <tt>nil</tt> will be returned.
165
+ #
166
+ # returns:: Rack::Request || NilClass
167
+ def rack_request
168
+ @rack_request ||= if args[:rack_env]
169
+ ::Rack::Request.new(args[:rack_env])
170
+ end
171
+ end
172
+
173
+ end
174
+
175
+ end
@@ -0,0 +1,11 @@
1
+ module CustosNotifier
2
+
3
+ # Class holds configuration (url, api_key, project, stage) access for Custos notifier.
4
+ class Configuration
5
+ attr_accessor :url
6
+ attr_accessor :api_key
7
+ attr_accessor :project
8
+ attr_accessor :stage
9
+ end
10
+
11
+ end
@@ -0,0 +1,38 @@
1
+ module CustosNotifier
2
+
3
+ # Simple middleware for handling raised exceptions in Rack applications
4
+ # Example:
5
+ # class MyApp
6
+ # def call(env)
7
+ # raise "my exception"
8
+ # end
9
+ # end
10
+ #
11
+ # CustosNotifier.configure do |config|
12
+ # config.url = "foo.blah.bar"
13
+ # config.project = "awsomeSite"
14
+ # config.stage = "production"
15
+ # config.api_key = "secret"
16
+ # end
17
+ #
18
+ # use CustosNotifier::Rack
19
+ # run MyApp
20
+ class Rack
21
+
22
+ def initialize(app)
23
+ @app = app
24
+ end
25
+
26
+
27
+ def call(env)
28
+ begin
29
+ @app.call(env)
30
+ rescue Exception => raised
31
+ CustosNotifier.notify(raised, :rack_env => env)
32
+ [500, {"Content-Type" => "text/html"},"Something went wrong"]
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,6 @@
1
+ require 'custos_notifier'
2
+ require 'custos_notifier/rails/action_controller_catcher'
3
+
4
+ if defined?(ActionController::Base)
5
+ ActionController::Base.send(:include, CustosNotifier::Rails::ActionControllerCatcher)
6
+ end
@@ -0,0 +1,16 @@
1
+ module CustosNotifier
2
+ module Rails
3
+ module ActionControllerCatcher
4
+
5
+ private
6
+
7
+
8
+ # Override standard exception handling behaviour.
9
+ def rescue_action_in_public(exception)
10
+ CustosNotifier.notify(exception, :request => request)
11
+ super
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module CustosNotifier
2
+
3
+ class Railtie < Rails::Railtie
4
+
5
+ # Use CustosNotifier::Rack as one of used middlewares.
6
+ initializer "custos_notifier.user_middleware" do |app|
7
+ app.config.middleware.use CustosNotifier::Rack
8
+ end
9
+ end
10
+
11
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: custos_notifier
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - Sebastian Nowak
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-06-08 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rest-client
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 1
31
+ - 6
32
+ version: "1.6"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: With this gem you can submit error messages to Custos service.
36
+ email: sebastian.nowak@implix.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - lib/custos_notifier/configuration.rb
45
+ - lib/custos_notifier/rack.rb
46
+ - lib/custos_notifier/rails/action_controller_catcher.rb
47
+ - lib/custos_notifier/rails.rb
48
+ - lib/custos_notifier/railtie.rb
49
+ - lib/custos_notifier.rb
50
+ has_rdoc: true
51
+ homepage:
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options: []
56
+
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 3
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.6.1
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Notifier for Custos service.
84
+ test_files: []
85
+