informant-rails 1.1.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.markdown +7 -4
- data/Rakefile +12 -9
- data/lib/informant-rails/config.rb +11 -22
- data/lib/informant-rails/{connection_tester.rb → diagnostic.rb} +30 -16
- data/lib/informant-rails/middleware.rb +8 -4
- data/lib/informant-rails/railtie.rb +10 -4
- data/lib/informant-rails/request_tracking.rb +2 -2
- data/lib/informant-rails/validation_tracking.rb +1 -3
- data/lib/informant-rails/version.rb +1 -1
- data/lib/informant-rails.rb +3 -6
- data/lib/tasks/diagnostic.rake +7 -0
- metadata +47 -18
- data/lib/informant-rails/client.rb +0 -66
- data/lib/informant-rails/field_error.rb +0 -19
- data/lib/informant-rails/model.rb +0 -17
- data/lib/informant-rails/parameter_filter.rb +0 -13
- data/lib/informant-rails/request.rb +0 -36
- data/lib/tasks/test_connection.rake +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 854e3ae4ab00261622e7c1a2f6fbd95e9ecc89057d1e3027fd6d8ae9187f7591
|
4
|
+
data.tar.gz: 5ac12d8002cc25e135c7f6f0d29e2553dade24b21b6fd1cab6511517cb0d8641
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 811722c69c8a0855460077e19d07a3bfe2a42738115e127e98b556255d83aa69c099d75d51b904e5224aa06a3a441dde71372f49bd14143d20057717c7c35015
|
7
|
+
data.tar.gz: 923c1ee5338b25d9c97bfd84f368c6ce3efe5719c57973b324a73f2ba631c949a5795a37cf5b60f3a62c0606918c4f835d45298b9cb37bce4c100b287709f0f8
|
data/README.markdown
CHANGED
@@ -8,12 +8,11 @@ The informant-rails gem provides Rails and ActiveRecord hooks for The Informant.
|
|
8
8
|
|
9
9
|
## Compatibility
|
10
10
|
|
11
|
-
The informant-rails gem officially supports Ruby 2.
|
11
|
+
The informant-rails gem officially supports Ruby 2.5+.
|
12
12
|
|
13
|
-
It will work automatically with Rails
|
13
|
+
It will work automatically with Rails 5.2+ as well as Mongoid 6.2 and up.
|
14
14
|
|
15
|
-
[![
|
16
|
-
[![Code Climate](https://codeclimate.com/github/informantapp/informant-rails.png)](https://codeclimate.com/github/informantapp/informant-rails)
|
15
|
+
[![pipeline status](https://gitlab.com/informantapp/informant-rails/badges/master/pipeline.svg)](https://gitlab.com/informantapp/informant-rails/-/commits/master)
|
17
16
|
|
18
17
|
## Installation
|
19
18
|
|
@@ -28,6 +27,10 @@ It will work automatically with Rails 3 and up as well as Mongoid 3 and up.
|
|
28
27
|
4. Deploy with the gem installed
|
29
28
|
5. Submit a form and you'll see it appear in our web interface
|
30
29
|
|
30
|
+
We've set up
|
31
|
+
[informant-rails-example](https://gitlab.com/informantapp/informant-rails-example)
|
32
|
+
as a demonstrate of installation and operation.
|
33
|
+
|
31
34
|
## Usage
|
32
35
|
|
33
36
|
By default, any request that causes an ActiveRecord or Mongoid model to be validated will be tracked by the Informant once the gem is added to your project.
|
data/Rakefile
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'bundler/gem_tasks'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
else
|
9
|
-
require "rspec/core/rake_task"
|
4
|
+
default_task = :spec
|
5
|
+
|
6
|
+
if ENV['APPRAISAL_INITIALIZED']
|
7
|
+
require 'rspec/core/rake_task'
|
10
8
|
RSpec::Core::RakeTask.new
|
11
|
-
|
9
|
+
else
|
10
|
+
require 'appraisal/task'
|
11
|
+
Appraisal::Task.new
|
12
|
+
default_task = :appraisal
|
12
13
|
end
|
14
|
+
|
15
|
+
task default: default_task
|
@@ -1,24 +1,13 @@
|
|
1
|
-
module InformantRails
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def self.client_identifier
|
14
|
-
@client_identifier ||= "informant-rails-#{InformantRails::VERSION}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.enabled?
|
18
|
-
api_token.present?
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.collector_host
|
22
|
-
@collector_host ||= ENV['INFORMANT_COLLECTOR_HOST'] || 'https://collector-api.informantapp.com'
|
1
|
+
module InformantRails
|
2
|
+
module Config
|
3
|
+
extend self
|
4
|
+
|
5
|
+
delegate :api_token, :api_token=,
|
6
|
+
:collector_host,
|
7
|
+
:enabled?,
|
8
|
+
:exclude_models, :exclude_models=,
|
9
|
+
:filter_parameters, :filter_parameters=,
|
10
|
+
:value_tracking?, :value_tracking=,
|
11
|
+
to: InformantCommon::Config
|
23
12
|
end
|
24
13
|
end
|
@@ -1,24 +1,23 @@
|
|
1
|
+
class TestClass
|
2
|
+
include ActiveModel::Model
|
3
|
+
|
4
|
+
attr_accessor :field_name
|
5
|
+
|
6
|
+
validates_presence_of :field_name
|
7
|
+
end
|
8
|
+
|
1
9
|
module InformantRails
|
2
|
-
class
|
3
|
-
def self.run
|
10
|
+
class Diagnostic
|
11
|
+
def self.run
|
12
|
+
new.run
|
13
|
+
end
|
4
14
|
|
5
15
|
def run
|
6
16
|
if Config.api_token.blank?
|
7
17
|
Rails.logger.info missing_api_token_message
|
8
18
|
else
|
9
|
-
Client.
|
10
|
-
|
11
|
-
Client.request.instance_variable_set('@models', [{
|
12
|
-
name: 'TestClass',
|
13
|
-
errors: [name: 'field_name', value: 'field_value', message: 'must be unique']
|
14
|
-
}])
|
15
|
-
response = Client.transmit(Client.request)
|
16
|
-
|
17
|
-
if response.success?
|
18
|
-
Rails.logger.info success_message
|
19
|
-
else
|
20
|
-
Rails.logger.info bad_response_message(response.body)
|
21
|
-
end
|
19
|
+
response = InformantCommon::Client.transmit(test_form_submission).join.value
|
20
|
+
display_response_message(response)
|
22
21
|
end
|
23
22
|
|
24
23
|
Rails.logger.info assistance_message
|
@@ -44,11 +43,26 @@ module InformantRails
|
|
44
43
|
end
|
45
44
|
|
46
45
|
def success_message
|
47
|
-
|
46
|
+
'Everything looks good. You should see a test request on your dashboard.'
|
48
47
|
end
|
49
48
|
|
50
49
|
def assistance_message
|
51
50
|
"If you need assistance or have any questions, send an email to support@informantapp.com or tweet @informantapp and we'll help you out!"
|
52
51
|
end
|
52
|
+
|
53
|
+
def test_form_submission
|
54
|
+
InformantCommon::Event::FormSubmission.new.tap do |form_submission|
|
55
|
+
form_submission.handler = 'Connectivity#test'
|
56
|
+
form_submission.process_model(InformantCommon::Model::ActiveModel.new(TestClass.new.tap(&:valid?)))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def display_response_message(response)
|
61
|
+
if response.code == '204'
|
62
|
+
Rails.logger.info success_message
|
63
|
+
else
|
64
|
+
Rails.logger.info bad_response_message(response.body)
|
65
|
+
end
|
66
|
+
end
|
53
67
|
end
|
54
68
|
end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
module InformantRails
|
2
|
-
class Middleware
|
2
|
+
class Middleware
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
6
|
+
|
3
7
|
def call(env)
|
4
|
-
Client.
|
5
|
-
response = app.call(env)
|
6
|
-
Client.process
|
8
|
+
InformantCommon::Client.start_transaction!(env['REQUEST_METHOD'])
|
9
|
+
response = @app.call(env)
|
10
|
+
InformantCommon::Client.process
|
7
11
|
response
|
8
12
|
end
|
9
13
|
end
|
@@ -1,13 +1,17 @@
|
|
1
1
|
module InformantRails
|
2
2
|
class Railtie < ::Rails::Railtie
|
3
3
|
initializer 'informant' do |config|
|
4
|
-
Config.api_token ||= ENV['INFORMANT_API_KEY']
|
5
|
-
|
6
4
|
if Config.enabled?
|
7
|
-
|
8
|
-
|
5
|
+
InformantCommon::Client.transmit(
|
6
|
+
InformantCommon::Event::AgentInfo.new(
|
7
|
+
agent_identifier: "informant-rails-#{InformantRails::VERSION}",
|
8
|
+
framework_version: "rails-#{Rails.version}"
|
9
|
+
)
|
10
|
+
)
|
9
11
|
InformantRails::Config.filter_parameters = Rails.configuration.filter_parameters
|
10
12
|
|
13
|
+
config.middleware.use InformantRails::Middleware
|
14
|
+
|
11
15
|
ActiveSupport.on_load(:action_controller) do
|
12
16
|
include InformantRails::RequestTracking
|
13
17
|
end
|
@@ -20,6 +24,8 @@ module InformantRails
|
|
20
24
|
include InformantRails::ValidationTracking
|
21
25
|
end
|
22
26
|
end
|
27
|
+
rescue StandardError => e
|
28
|
+
puts "Unable to bootstrap informant: #{e.message}"
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
@@ -5,11 +5,11 @@ module InformantRails
|
|
5
5
|
included do
|
6
6
|
if defined? before_action
|
7
7
|
before_action do
|
8
|
-
|
8
|
+
InformantCommon::Client.current_transaction&.handler = [controller_name, action_name].join('#')
|
9
9
|
end
|
10
10
|
else
|
11
11
|
before_filter do
|
12
|
-
|
12
|
+
InformantCommon::Client.current_transaction&.handler = [controller_name, action_name].join('#')
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
data/lib/informant-rails.rb
CHANGED
@@ -3,15 +3,12 @@ if defined?(Rake)
|
|
3
3
|
Dir[File.join(File.dirname(__FILE__), 'tasks', '**/*.rake')].each { |rake| load rake }
|
4
4
|
end
|
5
5
|
|
6
|
+
require 'informant-common'
|
7
|
+
|
6
8
|
module InformantRails
|
7
9
|
autoload :Config, 'informant-rails/config'
|
8
|
-
autoload :
|
9
|
-
autoload :Client, 'informant-rails/client'
|
10
|
-
autoload :FieldError, 'informant-rails/field_error'
|
10
|
+
autoload :Diagnostic, 'informant-rails/diagnostic'
|
11
11
|
autoload :Middleware, 'informant-rails/middleware'
|
12
|
-
autoload :Model, 'informant-rails/model'
|
13
|
-
autoload :Request, 'informant-rails/request'
|
14
|
-
autoload :ParameterFilter, 'informant-rails/parameter_filter'
|
15
12
|
autoload :RequestTracking, 'informant-rails/request_tracking'
|
16
13
|
autoload :ValidationTracking, 'informant-rails/validation_tracking'
|
17
14
|
autoload :VERSION, 'informant-rails/version'
|
metadata
CHANGED
@@ -1,29 +1,63 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: informant-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Informant, LLC
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: informant-common
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.2.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.2.0
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rails
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - ">="
|
18
32
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
33
|
+
version: 5.2.0
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 7.0.0
|
20
37
|
type: :runtime
|
21
38
|
prerelease: false
|
22
39
|
version_requirements: !ruby/object:Gem::Requirement
|
23
40
|
requirements:
|
24
41
|
- - ">="
|
25
42
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
43
|
+
version: 5.2.0
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 7.0.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: appraisal
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
27
61
|
description: The Informant tracks what users do wrong in your forms so you can make
|
28
62
|
them better.
|
29
63
|
email:
|
@@ -36,24 +70,20 @@ files:
|
|
36
70
|
- README.markdown
|
37
71
|
- Rakefile
|
38
72
|
- lib/informant-rails.rb
|
39
|
-
- lib/informant-rails/client.rb
|
40
73
|
- lib/informant-rails/config.rb
|
41
|
-
- lib/informant-rails/
|
42
|
-
- lib/informant-rails/field_error.rb
|
74
|
+
- lib/informant-rails/diagnostic.rb
|
43
75
|
- lib/informant-rails/middleware.rb
|
44
|
-
- lib/informant-rails/model.rb
|
45
|
-
- lib/informant-rails/parameter_filter.rb
|
46
76
|
- lib/informant-rails/railtie.rb
|
47
|
-
- lib/informant-rails/request.rb
|
48
77
|
- lib/informant-rails/request_tracking.rb
|
49
78
|
- lib/informant-rails/validation_tracking.rb
|
50
79
|
- lib/informant-rails/version.rb
|
51
|
-
- lib/tasks/
|
80
|
+
- lib/tasks/diagnostic.rake
|
52
81
|
homepage: https://www.informantapp.com
|
53
82
|
licenses:
|
54
83
|
- MIT
|
55
|
-
metadata:
|
56
|
-
|
84
|
+
metadata:
|
85
|
+
rubygems_mfa_required: 'true'
|
86
|
+
post_install_message:
|
57
87
|
rdoc_options: []
|
58
88
|
require_paths:
|
59
89
|
- lib
|
@@ -61,16 +91,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
91
|
requirements:
|
62
92
|
- - ">="
|
63
93
|
- !ruby/object:Gem::Version
|
64
|
-
version:
|
94
|
+
version: 2.6.0
|
65
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
96
|
requirements:
|
67
97
|
- - ">="
|
68
98
|
- !ruby/object:Gem::Version
|
69
99
|
version: '0'
|
70
100
|
requirements: []
|
71
|
-
|
72
|
-
|
73
|
-
signing_key:
|
101
|
+
rubygems_version: 3.2.32
|
102
|
+
signing_key:
|
74
103
|
specification_version: 4
|
75
104
|
summary: The Informant tracks server-side validation errors and gives you metrics
|
76
105
|
you never dreamed of.
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
|
3
|
-
module InformantRails
|
4
|
-
class Client
|
5
|
-
|
6
|
-
def self.record(env)
|
7
|
-
new_request.request_url = env['HTTP_REFERER'] unless env['REQUEST_METHOD'] == 'GET'
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.record_action(controller_name, action)
|
11
|
-
if request
|
12
|
-
request.filename = controller_name
|
13
|
-
request.action = action
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.record_validated_model(model)
|
18
|
-
request.process_model(model) if request && include_model?(model)
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.process
|
22
|
-
if request && request.models.any?
|
23
|
-
this_request = request
|
24
|
-
Thread.new { transmit(this_request) }
|
25
|
-
end
|
26
|
-
ensure
|
27
|
-
cleanup
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.request
|
31
|
-
Thread.current[:informant_request]
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.cleanup
|
35
|
-
Thread.current[:informant_request] = nil
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.transmit(completed_request)
|
39
|
-
Net::HTTP.start(api_endpoint.host, api_endpoint.port, use_ssl: api_endpoint.scheme == 'https') do |http|
|
40
|
-
http.request(net_http_post_request(completed_request))
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def self.net_http_post_request(completed_request)
|
47
|
-
Net::HTTP::Post.new(api_endpoint, {
|
48
|
-
"Authorization" => ActionController::HttpAuthentication::Token.encode_credentials(Config.api_token),
|
49
|
-
"Content-Type" => "application/json"
|
50
|
-
}).tap { |r| r.body = { payload: completed_request }.to_json }
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.include_model?(model)
|
54
|
-
!Config.exclude_models.include?(model.class.to_s)
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.new_request
|
58
|
-
Thread.current[:informant_request] = Request.new
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.api_endpoint
|
62
|
-
@api_endpoint ||= URI("#{Config.collector_host}/api/v1/form_submissions")
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module InformantRails
|
2
|
-
class FieldError
|
3
|
-
attr_accessor :name, :value, :message
|
4
|
-
|
5
|
-
def initialize(name, value, message=nil)
|
6
|
-
self.name = name
|
7
|
-
self.value = value
|
8
|
-
self.message = message
|
9
|
-
end
|
10
|
-
|
11
|
-
def value=(value)
|
12
|
-
@value = InformantRails::ParameterFilter.filter(name, value)
|
13
|
-
end
|
14
|
-
|
15
|
-
def as_json(*args)
|
16
|
-
{ name: name, value: value, message: message }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module InformantRails
|
2
|
-
class Model < Struct.new(:model)
|
3
|
-
def name
|
4
|
-
model.class.name
|
5
|
-
end
|
6
|
-
|
7
|
-
def errors
|
8
|
-
model.errors.map do |field, error|
|
9
|
-
InformantRails::FieldError.new(field.to_s, model[field], error)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def as_json(*args)
|
14
|
-
{ name: name, errors: errors.map(&:as_json) }
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module InformantRails
|
2
|
-
class ParameterFilter
|
3
|
-
def self.filter(name, value)
|
4
|
-
Config.value_tracking && !matcher.match(name) ? value : '[FILTERED]'
|
5
|
-
end
|
6
|
-
|
7
|
-
protected
|
8
|
-
|
9
|
-
def self.matcher
|
10
|
-
@matcher ||= Regexp.new(/#{Config.filter_parameters.join('|').presence || '$^'}/)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module InformantRails
|
2
|
-
class Request
|
3
|
-
attr_accessor :request_url, :filename, :action
|
4
|
-
|
5
|
-
def process_model(model)
|
6
|
-
if model && untracked?(model)
|
7
|
-
models << InformantRails::Model.new(model)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def models
|
12
|
-
@models ||= []
|
13
|
-
end
|
14
|
-
|
15
|
-
def as_json(*args)
|
16
|
-
{
|
17
|
-
models: models.map(&:as_json),
|
18
|
-
request_url: request_url,
|
19
|
-
filename: filename,
|
20
|
-
action: action,
|
21
|
-
client: InformantRails::Config.client_identifier,
|
22
|
-
rails_version: rails_version
|
23
|
-
}
|
24
|
-
end
|
25
|
-
|
26
|
-
protected
|
27
|
-
|
28
|
-
def rails_version
|
29
|
-
@rails_version ||= Rails.version
|
30
|
-
end
|
31
|
-
|
32
|
-
def untracked?(model)
|
33
|
-
!models.detect { |container| container.model == model }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|