validation_tracker_client 2.4.11

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/.gitignore ADDED
@@ -0,0 +1,41 @@
1
+ /.idea/*
2
+ .rvmrc
3
+ app/views/**/.tmp_*
4
+ public/images/Thumbs.db
5
+ public/system
6
+ tmp
7
+ public/blank.html
8
+ /.project
9
+ /.loadpath
10
+ /db/sphinx/test
11
+ /db/sphinx/test2
12
+ /db/sphinx/test3
13
+ /db/sphinx/test4
14
+ /db/sphinx/cucumber
15
+ /db/sphinx/development
16
+ /tmp
17
+ /log
18
+ /config/development.sphinx.conf
19
+ /config/test.sphinx.conf
20
+ /config/test2.sphinx.conf
21
+ /config/test3.sphinx.conf
22
+ /config/test4.sphinx.conf
23
+ /config/cucumber.sphinx.conf
24
+ nbproject
25
+ db/development_structure.sql
26
+ db/test_structure.sql
27
+ /results
28
+ cities.txt
29
+ states.txt
30
+ countries.txt
31
+ GPATH
32
+ GRTAGS
33
+ GSYMS
34
+ GTAGS
35
+ webrat.log
36
+ test/fixtures
37
+ .rvmrc
38
+ .gemtags
39
+ .tags
40
+ .tags_sorted_by_file
41
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in validation_tracker_client.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 arun.kumar.arjunan
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # ValidationTrackerClient
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'validation_tracker_client'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install validation_tracker_client
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,136 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'rubygems'
4
+ begin
5
+ require 'active_support'
6
+ rescue LoadError
7
+ require 'activesupport'
8
+ end
9
+ require 'validation_tracker_client/version'
10
+ require 'validation_tracker_client/configuration'
11
+ require 'validation_tracker_client/notice'
12
+ require 'validation_tracker_client/sender'
13
+
14
+ require 'validation_tracker_client/railtie' if defined?(Rails::Railtie)
15
+
16
+ # Gem for applications to automatically post errors to the Validation Tracker of their choice.
17
+ module ValidationTrackerClient
18
+
19
+ API_VERSION = "2.0"
20
+ LOG_PREFIX = "** [Validation Tracker] "
21
+
22
+ HEADERS = {
23
+ 'Content-type' => 'text/xml',
24
+ 'Accept' => 'text/xml, application/xml'
25
+ }
26
+
27
+ class << self
28
+ # The sender object is responsible for delivering formatted data to the Validation Tracker server.
29
+ # Must respond to #send_to_validation_tracker. See ValidationTrackerClient::Sender.
30
+ attr_accessor :sender
31
+
32
+ # A Validation Tracker configuration object. Must act like a hash and return sensible
33
+ # values for all Validation Tracker configuration options. See ValidationTrackerClient::Configuration.
34
+ attr_accessor :configuration
35
+
36
+ # Tell the log that the Notifier is good to go
37
+ def report_ready
38
+ write_verbose_log("Notifier #{VERSION} ready to catch errors")
39
+ end
40
+
41
+ # Prints out the environment info to the log for debugging help
42
+ def report_environment_info
43
+ write_verbose_log("Environment Info: #{environment_info}")
44
+ end
45
+
46
+ # Prints out the response body from Validation Tracker for debugging help
47
+ def report_response_body(response)
48
+ write_verbose_log("Response from Validation Tracker: \n#{response}")
49
+ end
50
+
51
+ # Returns the Ruby version, Rails version, and current Rails environment
52
+ def environment_info
53
+ info = "[Ruby: #{RUBY_VERSION}]"
54
+ info << " [#{configuration.framework}]"
55
+ info << " [Env: #{configuration.environment_name}]"
56
+ end
57
+
58
+ # Writes out the given message to the #logger
59
+ def write_verbose_log(message)
60
+ logger.info LOG_PREFIX + message if logger
61
+ end
62
+
63
+ # Look for the Rails logger currently defined
64
+ def logger
65
+ self.configuration.logger
66
+ end
67
+
68
+ # Call this method to modify defaults in your initializers.
69
+ #
70
+ # @example
71
+ # ValidationTrackerClient.configure do |config|
72
+ # config.api_key = '1234567890abcdef'
73
+ # config.secure = false
74
+ # end
75
+ def configure(silent = false)
76
+ self.configuration ||= Configuration.new
77
+ yield(configuration)
78
+ self.sender = Sender.new(configuration)
79
+ report_ready unless silent
80
+ end
81
+
82
+ # Sends an exception manually using this method, even when you are not in a controller.
83
+ #
84
+ # @param [Exception] exception The exception you want to notify Validation Tracker about.
85
+ # @param [Hash] opts Data that will be sent to Validation Tracker.
86
+ #
87
+ # @option opts [String] :api_key The API key for this project. The API key is a unique identifier that Validation Tracker uses for identification.
88
+ # @option opts [String] :error_message The error returned by the exception (or the message you want to log).
89
+ # @option opts [String] :backtrace A backtrace, usually obtained with +caller+.
90
+ # @option opts [String] :request The controller's request object.
91
+ # @option opts [String] :session The contents of the user's session.
92
+ # @option opts [String] :environment ENV merged with the contents of the request's environment.
93
+ def notify(error_message, opts = {})
94
+ send_notice(build_notice_for(error_message, opts))
95
+ end
96
+
97
+ # Sends the notice unless it is one of the default ignored exceptions
98
+ # @see ValidationTrackerClient.notify
99
+ def notify_or_ignore(exception, opts = {})
100
+ notice = build_notice_for(exception, opts)
101
+ send_notice(notice) unless notice.ignore?
102
+ end
103
+
104
+ def build_lookup_hash_for(exception, options = {})
105
+ notice = build_notice_for(exception, options)
106
+
107
+ result = {}
108
+ result[:action] = notice.action rescue nil
109
+ result[:component] = notice.component rescue nil
110
+ result[:error_class] = notice.error_class if notice.error_class
111
+ result[:environment_name] = 'production'
112
+
113
+ unless notice.backtrace.lines.empty?
114
+ result[:file] = notice.backtrace.lines.first.file
115
+ result[:line_number] = notice.backtrace.lines.first.number
116
+ end
117
+
118
+ result
119
+ end
120
+
121
+ private
122
+
123
+ def send_notice(notice)
124
+ if configuration.public?
125
+ sender.send_to_validation_tracker(notice.to_xml)
126
+ end
127
+ end
128
+
129
+ def build_notice_for(error_message, opts = {})
130
+ opts = opts.merge(:error_message => error_message)
131
+ Notice.new(configuration.merge(opts))
132
+ end
133
+
134
+ end
135
+ end
136
+
@@ -0,0 +1,175 @@
1
+ module ValidationTrackerClient
2
+ # Used to set up and modify settings for the notifier.
3
+ class Configuration
4
+
5
+ OPTIONS = [:api_key, :development_environments,
6
+ :development_lookup, :environment_name, :host,
7
+ :http_open_timeout, :http_read_timeout,
8
+ :notifier_name, :notifier_url, :notifier_version,
9
+ :params_filters, :project_root, :port, :protocol, :proxy_host,
10
+ :proxy_pass, :proxy_port, :proxy_user, :secure, :framework,
11
+ :user_information].freeze
12
+
13
+ # The API key for your project, found on the project edit form.
14
+ attr_accessor :api_key
15
+
16
+ # The host to connect to (defaults to validation-tracker.heroku.com).
17
+ attr_accessor :host
18
+
19
+ # The port on which your Validation Tracker server runs (defaults to 443 for secure
20
+ # connections, 80 for insecure connections).
21
+ attr_accessor :port
22
+
23
+ # +true+ for https connections, +false+ for http connections.
24
+ attr_accessor :secure
25
+
26
+ # The HTTP open timeout in seconds (defaults to 2).
27
+ attr_accessor :http_open_timeout
28
+
29
+ # The HTTP read timeout in seconds (defaults to 5).
30
+ attr_accessor :http_read_timeout
31
+
32
+ # The hostname of your proxy server (if using a proxy)
33
+ attr_accessor :proxy_host
34
+
35
+ # The port of your proxy server (if using a proxy)
36
+ attr_accessor :proxy_port
37
+
38
+ # The username to use when logging into your proxy server (if using a proxy)
39
+ attr_accessor :proxy_user
40
+
41
+ # The password to use when logging into your proxy server (if using a proxy)
42
+ attr_accessor :proxy_pass
43
+
44
+ # A list of parameters that should be filtered out of what is sent to Validation Tracker.
45
+ # By default, all "password" attributes will have their contents replaced.
46
+ attr_reader :params_filters
47
+
48
+ # A list of environments in which notifications should not be sent.
49
+ attr_accessor :development_environments
50
+
51
+ # +true+ if you want to check for production errors matching development errors, +false+ otherwise.
52
+ attr_accessor :development_lookup
53
+
54
+ # The name of the environment the application is running in
55
+ attr_accessor :environment_name
56
+
57
+ # The path to the project in which the error occurred, such as the RAILS_ROOT
58
+ attr_accessor :project_root
59
+
60
+ # The name of the notifier library being used to send notifications (such as "Validation Tracker Notifier")
61
+ attr_accessor :notifier_name
62
+
63
+ # The version of the notifier library being used to send notifications (such as "1.0.2")
64
+ attr_accessor :notifier_version
65
+
66
+ # The url of the notifier library being used to send notifications
67
+ attr_accessor :notifier_url
68
+
69
+ # The logger used by ValidationTrackerClient
70
+ attr_accessor :logger
71
+
72
+ # The text that the placeholder is replaced with. {{error_id}} is the actual error number.
73
+ attr_accessor :user_information
74
+
75
+ # The framework ValidationTrackerClient is configured to use
76
+ attr_accessor :framework
77
+
78
+ DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze
79
+
80
+ DEFAULT_BACKTRACE_FILTERS = [
81
+ lambda { |line|
82
+ if defined?(ValidationTrackerClient.configuration.project_root) && ValidationTrackerClient.configuration.project_root.to_s != ''
83
+ line.gsub(/#{ValidationTrackerClient.configuration.project_root}/, "[PROJECT_ROOT]")
84
+ else
85
+ line
86
+ end
87
+ },
88
+ lambda { |line| line.gsub(/^\.\//, "") },
89
+ lambda { |line|
90
+ if defined?(Gem)
91
+ Gem.path.inject(line) do |line, path|
92
+ line.gsub(/#{path}/, "[GEM_ROOT]")
93
+ end
94
+ end
95
+ },
96
+ lambda { |line| line if line !~ %r{lib/validation_tracker_client} }
97
+ ].freeze
98
+
99
+
100
+ alias_method :secure?, :secure
101
+
102
+ def initialize
103
+ @secure = false
104
+ @host = 'validation-tracker.heroku.com'
105
+ @http_open_timeout = 2
106
+ @http_read_timeout = 5
107
+ @params_filters = DEFAULT_PARAMS_FILTERS.dup
108
+ @ignore_user_agent = []
109
+ @development_environments = %w(development test cucumber)
110
+ @development_lookup = true
111
+ @notifier_name = 'Validation Tracker Notifier'
112
+ @notifier_version = VERSION
113
+ @notifier_url = 'http://validation-tracker.heroku.com'
114
+ @framework = 'Standalone'
115
+ @user_information = 'Validation Tracker Error {{error_id}}'
116
+ end
117
+
118
+
119
+ # Allows config options to be read like a hash
120
+ #
121
+ # @param [Symbol] option Key for a given attribute
122
+ def [](option)
123
+ send(option)
124
+ end
125
+
126
+ # Returns a hash of all configurable options
127
+ def to_hash
128
+ OPTIONS.inject({}) do |hash, option|
129
+ hash.merge(option.to_sym => send(option))
130
+ end
131
+ end
132
+
133
+ # Returns a hash of all configurable options merged with +hash+
134
+ #
135
+ # @param [Hash] hash A set of configuration options that will take precedence over the defaults
136
+ def merge(hash)
137
+ to_hash.merge(hash)
138
+ end
139
+
140
+ # Determines if the notifier will send notices.
141
+ # @return [Boolean] Returns +false+ if in a development environment, +true+ otherwise.
142
+ def public?
143
+ !development_environments.include?(environment_name)
144
+ end
145
+
146
+ def port
147
+ @port || default_port
148
+ end
149
+
150
+ def protocol
151
+ if secure?
152
+ 'https'
153
+ else
154
+ 'http'
155
+ end
156
+ end
157
+
158
+ def environment_filters
159
+ warn 'config.environment_filters has been deprecated and has no effect.'
160
+ []
161
+ end
162
+
163
+ private
164
+
165
+ def default_port
166
+ if secure?
167
+ 443
168
+ else
169
+ 80
170
+ end
171
+ end
172
+
173
+ end
174
+
175
+ end
@@ -0,0 +1,329 @@
1
+ require 'builder'
2
+ require 'socket'
3
+
4
+ module ValidationTrackerClient
5
+ class Notice
6
+
7
+ # The API key for the project to which this notice should be sent
8
+ attr_reader :api_key
9
+
10
+
11
+ # The name of the server environment (such as "production")
12
+ attr_reader :environment_name
13
+
14
+ # CGI variables such as HTTP_METHOD
15
+ attr_reader :cgi_data
16
+
17
+ # The message from the exception, or a general description of the error
18
+ attr_reader :error_message
19
+
20
+ # See Configuration#backtrace_filters
21
+ attr_reader :backtrace_filters
22
+
23
+ # See Configuration#params_filters
24
+ attr_reader :params_filters
25
+
26
+ # A hash of parameters from the query string or post body.
27
+ attr_reader :parameters
28
+ alias_method :params, :parameters
29
+
30
+ # The component (if any) which was used in this request (usually the controller)
31
+ attr_reader :component
32
+ alias_method :controller, :component
33
+
34
+ # The action (if any) that was called in this request
35
+ attr_reader :action
36
+
37
+ # A hash of session data from the request
38
+ attr_reader :session_data
39
+
40
+ # The path to the project that caused the error (usually RAILS_ROOT)
41
+ attr_reader :project_root
42
+
43
+ # The URL at which the error occurred (if any)
44
+ attr_reader :url
45
+
46
+ # The name of the notifier library sending this notice, such as "Validation Tracker Notifier"
47
+ attr_reader :notifier_name
48
+
49
+ # The version number of the notifier library sending this notice, such as "2.1.3"
50
+ attr_reader :notifier_version
51
+
52
+ # A URL for more information about the notifier library sending this notice
53
+ attr_reader :notifier_url
54
+
55
+ # The host name where this error occurred (if any)
56
+ attr_reader :hostname
57
+
58
+ def initialize(args)
59
+ self.args = args
60
+ self.exception = args[:exception]
61
+ self.api_key = args[:api_key]
62
+ self.project_root = args[:project_root]
63
+ self.url = args[:url] || rack_env(:url)
64
+
65
+ self.notifier_name = args[:notifier_name]
66
+ self.notifier_version = args[:notifier_version]
67
+ self.notifier_url = args[:notifier_url]
68
+
69
+ self.params_filters = args[:params_filters] || []
70
+ self.parameters = args[:parameters] ||
71
+ action_dispatch_params ||
72
+ rack_env(:params) ||
73
+ {}
74
+ self.component = args[:component] || args[:controller] || parameters['controller']
75
+ self.action = args[:action] || parameters['action']
76
+
77
+ self.environment_name = args[:environment_name]
78
+ self.cgi_data = args[:cgi_data] || args[:rack_env]
79
+ self.error_message = exception_attribute(:error_message, 'Notification') do |exception|
80
+ "#{exception.class.name}: #{exception.message}"
81
+ end
82
+
83
+ self.hostname = local_hostname
84
+
85
+ also_use_rack_params_filters
86
+ find_session_data
87
+ clean_params
88
+ clean_rack_request_data
89
+ end
90
+
91
+ # Converts the given notice to XML
92
+ def to_xml
93
+ builder = Builder::XmlMarkup.new
94
+ builder.instruct!
95
+ xml = builder.notice(:version => ValidationTrackerClient::API_VERSION) do |notice|
96
+ notice.tag!("api-key", api_key)
97
+ notice.notifier do |notifier|
98
+ notifier.name(notifier_name)
99
+ notifier.version(notifier_version)
100
+ notifier.url(notifier_url)
101
+ end
102
+ notice.error do |error|
103
+ error.tag!('class', error_class)
104
+ error.message(error_message)
105
+ error.backtrace do |backtrace|
106
+ self.backtrace.lines.each do |line|
107
+ backtrace.line(:number => line.number,
108
+ :file => line.file,
109
+ :method => line.method)
110
+ end
111
+ end
112
+ end
113
+ if url ||
114
+ controller ||
115
+ action ||
116
+ !parameters.blank? ||
117
+ !cgi_data.blank? ||
118
+ !session_data.blank?
119
+ notice.request do |request|
120
+ request.url(url)
121
+ request.component(controller)
122
+ request.action(action)
123
+ unless parameters.nil? || parameters.empty?
124
+ request.params do |params|
125
+ xml_vars_for(params, parameters)
126
+ end
127
+ end
128
+ unless session_data.nil? || session_data.empty?
129
+ request.session do |session|
130
+ xml_vars_for(session, session_data)
131
+ end
132
+ end
133
+ unless cgi_data.nil? || cgi_data.empty?
134
+ request.tag!("cgi-data") do |cgi_datum|
135
+ xml_vars_for(cgi_datum, cgi_data)
136
+ end
137
+ end
138
+ end
139
+ end
140
+ notice.tag!("server-environment") do |env|
141
+ env.tag!("project-root", project_root)
142
+ env.tag!("environment-name", environment_name)
143
+ env.tag!("hostname", hostname)
144
+ end
145
+ end
146
+ xml.to_s
147
+ end
148
+
149
+ # Determines if this notice should be ignored
150
+ def ignore?
151
+ ignored_class_names.include?(error_class) ||
152
+ ignore_by_filters.any? {|filter| filter.call(self) }
153
+ end
154
+
155
+ # Allows properties to be accessed using a hash-like syntax
156
+ #
157
+ # @example
158
+ # notice[:error_message]
159
+ # @param [String] method The given key for an attribute
160
+ # @return The attribute value, or self if given +:request+
161
+ def [](method)
162
+ case method
163
+ when :request
164
+ self
165
+ else
166
+ send(method)
167
+ end
168
+ end
169
+
170
+ private
171
+
172
+ attr_writer :exception, :api_key, :backtrace, :error_class, :error_message,
173
+ :backtrace_filters, :parameters, :params_filters,
174
+ :environment_filters, :session_data, :project_root, :url, :ignore,
175
+ :ignore_by_filters, :notifier_name, :notifier_url, :notifier_version,
176
+ :component, :action, :cgi_data, :environment_name, :hostname
177
+
178
+ # Arguments given in the initializer
179
+ attr_accessor :args
180
+
181
+ # Gets a property named +attribute+ of an exception, either from an actual
182
+ # exception or a hash.
183
+ #
184
+ # If an exception is available, #from_exception will be used. Otherwise,
185
+ # a key named +attribute+ will be used from the #args.
186
+ #
187
+ # If no exception or hash key is available, +default+ will be used.
188
+ def exception_attribute(attribute, default = nil, &block)
189
+ (exception && from_exception(attribute, &block)) || args[attribute] || default
190
+ end
191
+
192
+ # Gets a property named +attribute+ from an exception.
193
+ #
194
+ # If a block is given, it will be used when getting the property from an
195
+ # exception. The block should accept and exception and return the value for
196
+ # the property.
197
+ #
198
+ # If no block is given, a method with the same name as +attribute+ will be
199
+ # invoked for the value.
200
+ def from_exception(attribute)
201
+ if block_given?
202
+ yield(exception)
203
+ else
204
+ exception.send(attribute)
205
+ end
206
+ end
207
+
208
+ # Removes non-serializable data from the given attribute.
209
+ # See #clean_unserializable_data
210
+ def clean_unserializable_data_from(attribute)
211
+ self.send(:"#{attribute}=", clean_unserializable_data(send(attribute)))
212
+ end
213
+
214
+ # Removes non-serializable data. Allowed data types are strings, arrays,
215
+ # and hashes. All other types are converted to strings.
216
+ # TODO: move this onto Hash
217
+ def clean_unserializable_data(data, stack = [])
218
+ return "[possible infinite recursion halted]" if stack.any?{|item| item == data.object_id }
219
+
220
+ if data.respond_to?(:to_hash)
221
+ data.to_hash.inject({}) do |result, (key, value)|
222
+ result.merge(key => clean_unserializable_data(value, stack + [data.object_id]))
223
+ end
224
+ elsif data.respond_to?(:to_ary)
225
+ data.collect do |value|
226
+ clean_unserializable_data(value, stack + [data.object_id])
227
+ end
228
+ else
229
+ data.to_s
230
+ end
231
+ end
232
+
233
+ # Replaces the contents of params that match params_filters.
234
+ # TODO: extract this to a different class
235
+ def clean_params
236
+ clean_unserializable_data_from(:parameters)
237
+ filter(parameters)
238
+ if cgi_data
239
+ clean_unserializable_data_from(:cgi_data)
240
+ filter(cgi_data)
241
+ end
242
+ if session_data
243
+ clean_unserializable_data_from(:session_data)
244
+ filter(session_data)
245
+ end
246
+ end
247
+
248
+ def clean_rack_request_data
249
+ if cgi_data
250
+ cgi_data.delete("rack.request.form_vars")
251
+ end
252
+ end
253
+
254
+ def filter(hash)
255
+ if params_filters
256
+ hash.each do |key, value|
257
+ if filter_key?(key)
258
+ hash[key] = "[FILTERED]"
259
+ elsif value.respond_to?(:to_hash)
260
+ filter(hash[key])
261
+ end
262
+ end
263
+ end
264
+ end
265
+
266
+ def filter_key?(key)
267
+ params_filters.any? do |filter|
268
+ key.to_s.include?(filter.to_s)
269
+ end
270
+ end
271
+
272
+ def find_session_data
273
+ self.session_data = args[:session_data] || args[:session] || rack_session || {}
274
+ self.session_data = session_data[:data] if session_data[:data]
275
+ end
276
+
277
+ # Converts the mixed class instances and class names into just names
278
+ # TODO: move this into Configuration or another class
279
+ def ignored_class_names
280
+ ignore.collect do |string_or_class|
281
+ if string_or_class.respond_to?(:name)
282
+ string_or_class.name
283
+ else
284
+ string_or_class
285
+ end
286
+ end
287
+ end
288
+
289
+ def xml_vars_for(builder, hash)
290
+ hash.each do |key, value|
291
+ if value.respond_to?(:to_hash)
292
+ builder.var(:key => key){|b| xml_vars_for(b, value.to_hash) }
293
+ else
294
+ builder.var(value.to_s, :key => key)
295
+ end
296
+ end
297
+ end
298
+
299
+ def rack_env(method)
300
+ rack_request.send(method) if rack_request
301
+ end
302
+
303
+ def rack_request
304
+ @rack_request ||= if args[:rack_env]
305
+ ::Rack::Request.new(args[:rack_env])
306
+ end
307
+ end
308
+
309
+ def action_dispatch_params
310
+ args[:rack_env]['action_dispatch.request.parameters'] if args[:rack_env]
311
+ end
312
+
313
+ def rack_session
314
+ args[:rack_env]['rack.session'] if args[:rack_env]
315
+ end
316
+
317
+ def also_use_rack_params_filters
318
+ if args[:rack_env]
319
+ @params_filters ||= []
320
+ @params_filters += rack_request.env["action_dispatch.parameter_filter"] || []
321
+ end
322
+ end
323
+
324
+ def local_hostname
325
+ Socket.gethostname
326
+ end
327
+
328
+ end
329
+ end
@@ -0,0 +1,34 @@
1
+ require 'validation_tracker_client'
2
+ require 'validation_tracker_client/rails/controller_methods'
3
+ require 'validation_tracker_client/rails/action_controller_catcher'
4
+ require 'validation_tracker_client/rails/error_lookup'
5
+ require 'validation_tracker_client/rails/javascript_notifier'
6
+
7
+ module ValidationTrackerClient
8
+ module Rails
9
+ def self.initialize
10
+ if defined?(ActionController::Base)
11
+ ActionController::Base.send(:include, ValidationTrackerClient::Rails::ActionControllerCatcher)
12
+ ActionController::Base.send(:include, ValidationTrackerClient::Rails::ErrorLookup)
13
+ ActionController::Base.send(:include, ValidationTrackerClient::Rails::ControllerMethods)
14
+ ActionController::Base.send(:include, ValidationTrackerClient::Rails::JavascriptNotifier)
15
+ end
16
+
17
+ rails_logger = if defined?(::Rails.logger)
18
+ ::Rails.logger
19
+ elsif defined?(RAILS_DEFAULT_LOGGER)
20
+ RAILS_DEFAULT_LOGGER
21
+ end
22
+
23
+ ValidationTrackerClient.configure(true) do |config|
24
+ config.logger = rails_logger
25
+ config.environment_name = RAILS_ENV if defined?(RAILS_ENV)
26
+ config.project_root = RAILS_ROOT if defined?(RAILS_ROOT)
27
+ config.framework = "Rails: #{::Rails::VERSION::STRING}" if defined?(::Rails::VERSION)
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ ValidationTrackerClient::Rails.initialize
34
+
@@ -0,0 +1,62 @@
1
+ module ValidationTrackerClient
2
+ module Rails
3
+ module ControllerMethods
4
+ private
5
+
6
+ # This method should be used for sending manual notifications while you are still
7
+ # inside the controller. Otherwise it works like ValidationTrackerClient.notify.
8
+ def notify_validation_message(hash_or_exception)
9
+ unless validation_tracker_local_request?
10
+ ValidationTrackerClient.notify(hash_or_exception, validation_tracker_request_data)
11
+ end
12
+ end
13
+
14
+ def validation_tracker_local_request?
15
+ if defined?(::Rails.application.config)
16
+ ::Rails.application.config.consider_all_requests_local || request.local?
17
+ else
18
+ consider_all_requests_local || local_request?
19
+ end
20
+ end
21
+
22
+ def validation_tracker_request_data
23
+ { :parameters => validation_tracker_filter_if_filtering(params.to_hash),
24
+ :session_data => validation_tracker_filter_if_filtering(validation_tracker_session_data),
25
+ :controller => params[:controller],
26
+ :action => params[:action],
27
+ :url => validation_tracker_request_url,
28
+ :cgi_data => validation_tracker_filter_if_filtering(request.env) }
29
+ end
30
+
31
+ def validation_tracker_filter_if_filtering(hash)
32
+ return hash if ! hash.is_a?(Hash)
33
+
34
+ if respond_to?(:filter_parameters)
35
+ filter_parameters(hash) rescue hash
36
+ else
37
+ hash
38
+ end
39
+ end
40
+
41
+ def validation_tracker_session_data
42
+ if session.respond_to?(:to_hash)
43
+ session.to_hash
44
+ else
45
+ session.data
46
+ end
47
+ end
48
+
49
+ def validation_tracker_request_url
50
+ url = "#{request.protocol}#{request.host}"
51
+
52
+ unless [80, 443].include?(request.port)
53
+ url << ":#{request.port}"
54
+ end
55
+
56
+ url << request.fullpath
57
+ url
58
+ end
59
+ end
60
+ end
61
+ end
62
+
@@ -0,0 +1,22 @@
1
+ require 'validation_tracker_client'
2
+ require 'rails'
3
+
4
+ module ValidationTrackerClient
5
+ class Railtie < Rails::Railtie
6
+
7
+ config.after_initialize do
8
+ ValidationTrackerClient.configure(true) do |config|
9
+ config.logger ||= Rails.logger
10
+ config.environment_name ||= Rails.env
11
+ config.project_root ||= Rails.root
12
+ config.framework = "Rails: #{::Rails::VERSION::STRING}"
13
+ end
14
+
15
+ if defined?(::ActionController::Base)
16
+ require 'validation_tracker_client/rails/controller_methods'
17
+
18
+ ::ActionController::Base.send(:include, ValidationTrackerClient::Rails::ControllerMethods)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,76 @@
1
+ module ValidationTrackerClient
2
+ # Sends out the notice to Validation Tracker
3
+ class Sender
4
+
5
+ NOTICES_URI = '/notifier_api/v2/notices/'.freeze
6
+ HTTP_ERRORS = [Timeout::Error,
7
+ Errno::EINVAL,
8
+ Errno::ECONNRESET,
9
+ EOFError,
10
+ Net::HTTPBadResponse,
11
+ Net::HTTPHeaderSyntaxError,
12
+ Net::ProtocolError,
13
+ Errno::ECONNREFUSED].freeze
14
+
15
+ def initialize(options = {})
16
+ [:proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
17
+ :host, :port, :secure, :http_open_timeout, :http_read_timeout].each do |option|
18
+ instance_variable_set("@#{option}", options[option])
19
+ end
20
+ end
21
+
22
+ # Sends the notice data off to Validation Tracker for processing.
23
+ #
24
+ # @param [String] data The XML notice to be sent off
25
+ def send_to_hoptoad(data)
26
+ logger.debug { "Sending request to #{url.to_s}:\n#{data}" } if logger
27
+
28
+ http =
29
+ Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass).
30
+ new(url.host, url.port)
31
+
32
+ http.read_timeout = http_read_timeout
33
+ http.open_timeout = http_open_timeout
34
+ http.use_ssl = secure
35
+
36
+ response = begin
37
+ http.post(url.path, data, HEADERS)
38
+ rescue *HTTP_ERRORS => e
39
+ log :error, "Timeout while contacting the Validation Tracker server."
40
+ nil
41
+ end
42
+
43
+ case response
44
+ when Net::HTTPSuccess then
45
+ log :info, "Success: #{response.class}", response
46
+ else
47
+ log :error, "Failure: #{response.class}", response
48
+ end
49
+
50
+ if response && response.respond_to?(:body)
51
+ error_id = response.body.match(%r{<error-id[^>]*>(.*?)</error-id>})
52
+ error_id[1] if error_id
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ attr_reader :proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
59
+ :host, :port, :secure, :http_open_timeout, :http_read_timeout
60
+
61
+ def url
62
+ URI.parse("#{protocol}://#{host}:#{port}").merge(NOTICES_URI)
63
+ end
64
+
65
+ def log(level, message, response = nil)
66
+ logger.send level, LOG_PREFIX + message if logger
67
+ ValidationTrackerClient.report_environment_info
68
+ ValidationTrackerClient.report_response_body(response.body) if response && response.respond_to?(:body)
69
+ end
70
+
71
+ def logger
72
+ ValidationTrackerClient.logger
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,3 @@
1
+ module ValidationTrackerClient
2
+ VERSION = "2.4.11"
3
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'validation_tracker_client/rails'
data/test.rb ADDED
@@ -0,0 +1,7 @@
1
+ system 'rake build --trace'
2
+ system 'rake install'
3
+ require 'rubygems'
4
+ require 'debugger'
5
+ gem 'validation_tracker_client'
6
+
7
+ ValidationTrackerClient.notify('COOL')
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/validation_tracker_client/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["arun.kumar.arjunan"]
6
+ gem.email = ["arun@chronus.com"]
7
+ gem.description = %q{Validation Tracker Client}
8
+ gem.summary = %q{Validation Tracker Summary}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "validation_tracker_client"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = ValidationTrackerClient::VERSION
17
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: validation_tracker_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.4.11
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - arun.kumar.arjunan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-08 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Validation Tracker Client
15
+ email:
16
+ - arun@chronus.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - LICENSE
24
+ - README.md
25
+ - Rakefile
26
+ - lib/validation_tracker_client.rb
27
+ - lib/validation_tracker_client/configuration.rb
28
+ - lib/validation_tracker_client/notice.rb
29
+ - lib/validation_tracker_client/rails.rb
30
+ - lib/validation_tracker_client/rails/controller_methods.rb
31
+ - lib/validation_tracker_client/railtie.rb
32
+ - lib/validation_tracker_client/sender.rb
33
+ - lib/validation_tracker_client/version.rb
34
+ - rails/init.rb
35
+ - test.rb
36
+ - validation_tracker_client.gemspec
37
+ homepage: ''
38
+ licenses: []
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.10
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Validation Tracker Summary
61
+ test_files: []