Class: Google::Cloud::ErrorReporting::Middleware
- Inherits:
-
Object
- Object
- Google::Cloud::ErrorReporting::Middleware
- Defined in:
- lib/google/cloud/error_reporting/middleware.rb
Overview
Middleware
Google::Cloud::ErrorReporting::Middleware defines a Rack Middleware that can automatically catch upstream exceptions and report them to Stackdriver Error Reporting.
Instance Attribute Summary collapse
-
#error_reporting ⇒ Object
readonly
Returns the value of attribute error_reporting.
-
#ignore_classes ⇒ Object
readonly
Returns the value of attribute ignore_classes.
-
#project_id ⇒ Object
readonly
Returns the value of attribute project_id.
-
#service_name ⇒ Object
readonly
Returns the value of attribute service_name.
-
#service_version ⇒ Object
readonly
Returns the value of attribute service_version.
Instance Method Summary collapse
-
#build_error_event_from_exception(env, exception) ⇒ Google::Devtools::Clouderrorreporting::V1beta1::ReportedErrorEvent
Creates a GRPC ErrorEvent based on the exception.
-
#call(env) ⇒ Object
Implements the mandatory Rack Middleware call method.
-
#full_project_id ⇒ Object
Build full ReportErrorsServiceApi project_path from project_id, which is in "projects/##project_id" format.
-
#initialize(app, error_reporting: nil, project_id: nil, service_name: nil, service_version: nil, ignore_classes: nil) ⇒ Google::Cloud::ErrorReporting::Middleware
constructor
Construct a new instance of Middleware.
-
#report_exception(env, exception) ⇒ Object
Report an given exception to Stackdriver Error Reporting.
Constructor Details
#initialize(app, error_reporting: nil, project_id: nil, service_name: nil, service_version: nil, ignore_classes: nil) ⇒ Google::Cloud::ErrorReporting::Middleware
Construct a new instance of Middleware
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/google/cloud/error_reporting/middleware.rb', line 53 def initialize app, error_reporting: nil, project_id: nil, service_name: nil, service_version: nil, ignore_classes: nil @app = app @error_reporting = error_reporting || Google::Cloud::ErrorReporting::V1beta1::ReportErrorsServiceApi.new @service_name = service_name || ENV["ERROR_REPORTING_SERVICE"] || Google::Cloud::Core::Environment.gae_module_id || "ruby" @service_version = service_version || ENV["ERROR_REPORTING_VERSION"] || Google::Cloud::Core::Environment.gae_module_version @ignore_classes = Array(ignore_classes) @project_id = project_id || ENV["ERROR_REPORTING_PROJECT"] || ENV["GOOGLE_CLOUD_PROJECT"] || Google::Cloud::Core::Environment.project_id raise ArgumentError, "project_id is required" if @project_id.nil? end |
Instance Attribute Details
#error_reporting ⇒ Object (readonly)
Returns the value of attribute error_reporting
29 30 31 |
# File 'lib/google/cloud/error_reporting/middleware.rb', line 29 def error_reporting @error_reporting end |
#ignore_classes ⇒ Object (readonly)
Returns the value of attribute ignore_classes
29 30 31 |
# File 'lib/google/cloud/error_reporting/middleware.rb', line 29 def ignore_classes @ignore_classes end |
#project_id ⇒ Object (readonly)
Returns the value of attribute project_id
29 30 31 |
# File 'lib/google/cloud/error_reporting/middleware.rb', line 29 def project_id @project_id end |
#service_name ⇒ Object (readonly)
Returns the value of attribute service_name
29 30 31 |
# File 'lib/google/cloud/error_reporting/middleware.rb', line 29 def service_name @service_name end |
#service_version ⇒ Object (readonly)
Returns the value of attribute service_version
29 30 31 |
# File 'lib/google/cloud/error_reporting/middleware.rb', line 29 def service_version @service_version end |
Instance Method Details
#build_error_event_from_exception(env, exception) ⇒ Google::Devtools::Clouderrorreporting::V1beta1::ReportedErrorEvent
Creates a GRPC ErrorEvent based on the exception. Fill in the HttpRequestContext section of the ErrorEvent based on the HTTP Request headers.
When used in Rails environment. It replies on ActionDispatch::ExceptionWrapper class to derive a HTTP status code based on the exception's class.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/google/cloud/error_reporting/middleware.rb', line 143 def build_error_event_from_exception env, exception # Build service_context hash service_context = { service: service_name, version: service_version }.delete_if { |k,v| v.nil? } # Build error message and source_location hash if exception.backtrace.nil? || exception.backtrace.empty? = exception. report_location = nil else = "#{exception.backtrace.first}: #{exception.} " \ "(#{exception.class})\n\t" + exception.backtrace.drop(1).join("\n\t") file_path, line_number, function_name = exception.backtrace.first.split(":") function_name = function_name.to_s[/`(.*)'/, 1] report_location = { file_path: file_path, function_name: function_name, line_number: line_number.to_i }.delete_if { |k,v| v.nil? } end # Build http_request_context hash rack_request = Rack::Request.new env http_method = rack_request.request_method http_url = rack_request.url http_user_agent = rack_request.user_agent http_referrer = rack_request.referrer http_status = get_http_status exception http_remote_ip = rack_request.ip http_request_context = { method: http_method, url: http_url, user_agent: http_user_agent, referrer: http_referrer, response_status_code: http_status, remote_ip: http_remote_ip }.delete_if { |k,v| v.nil? } # Build error_context hash error_context = { http_request: http_request_context, user: ENV["USER"], report_location: report_location, }.delete_if { |k,v| v.nil? } # Build error_event hash t = Time.now error_event = { event_time: { seconds: t.to_i, nanos: t.nsec }, service_context: service_context, message: , context: error_context }.delete_if { |k,v| v.nil? } # Finally build and return GRPC ErrorEvent Google::Devtools::Clouderrorreporting::V1beta1::ReportedErrorEvent.decode_json \ error_event.to_json end |
#call(env) ⇒ Object
Implements the mandatory Rack Middleware call method.
Catch all Exceptions from upstream and report them to Stackdriver Error Reporting. Unless the exception's class is defined to be ignored by this Middleware.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/google/cloud/error_reporting/middleware.rb', line 85 def call env response = @app.call env # sinatra doesn't always raise the Exception, but it saves it in # env['sinatra.error'] if env["sinatra.error"].is_a? Exception report_exception env, env["sinatra.error"] end response rescue Exception => exception report_exception env, exception # Always raise exception backup raise exception end |
#full_project_id ⇒ Object
Build full ReportErrorsServiceApi project_path from project_id, which is in "projects/##project_id" format.
212 213 214 |
# File 'lib/google/cloud/error_reporting/middleware.rb', line 212 def full_project_id Google::Cloud::ErrorReporting::V1beta1::ReportErrorsServiceApi.project_path project_id end |
#report_exception(env, exception) ⇒ Object
Report an given exception to Stackdriver Error Reporting.
While it reports most of the exceptions. Certain Rails exceptions that maps to a HTTP status code less than 500 will be treated as not the app fault and ignored.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/google/cloud/error_reporting/middleware.rb', line 112 def report_exception env, exception # Do not any exceptions that's specified by the ignore_classes list. return if ignore_classes.include? exception.class error_event = build_error_event_from_exception env, exception # If this exception maps to a HTTP status code less than 500, do # not report it. status_code = error_event.context.http_request.response_status_code.to_i return if status_code > 0 && status_code < 500 error_reporting.report_error_event full_project_id, error_event end |