ahoy_matey 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ac410ebebcbaf5aad9ccc62e1880017a529122f6
4
- data.tar.gz: 9394bb160b09cc8b28d15c23c0d81443b37547c9
3
+ metadata.gz: 181105196800b983c765eacf7faa0ad9280a1553
4
+ data.tar.gz: 67a7a2cb8dea093d979323b384b18d3b7f4e4ba7
5
5
  SHA512:
6
- metadata.gz: df2fd19329ea584adfc8a6a2f730fe651650f812c9806e75ade1869376fd787ffa7537621cf518ac8ffd42e9e83ee6e21828c826023c957622c8f94b8c544cf4
7
- data.tar.gz: 7ae8ddc2287e8182055cb293558286127c49c594b0fcd3cb5516571d4ff3c1ecd71c1cc4de469f7d4dfccaa5f493b5cdc4037c734bb96a140173f5457d6c397f
6
+ metadata.gz: a3dd6aeb1bd934d5ae71b84b38188c8c991a28c764aeecebf1566e3f675c120953c3a443ad38330e5db68d530e7fd1bce7ad2d5f3e469fe8e6b403f4381a6257
7
+ data.tar.gz: ea652c7992e43801a5f6dc5bfac7284c336a6ab11e544a1298b96bf100807251f4059355f6650932f42a85ade1a6a2eac9e3204f14a32186289feabf26d03165
data/CHANGELOG.md CHANGED
@@ -1,6 +1,12 @@
1
- ## 1.3.1
1
+ ## 1.4.0
2
2
 
3
+ - Use `ActiveRecordTokenStore` by default (integer instead of uuid for id)
4
+ - Detect database for `rails g ahoy:stores:active_record` for easier installation
5
+ - Use `safely` as default exception handler
3
6
  - Fixed issue with log silencer
7
+
8
+ ## 1.3.1
9
+
4
10
  - Raise errors in test environment
5
11
 
6
12
  ## 1.3.0
data/README.md CHANGED
@@ -1,17 +1,11 @@
1
1
  # Ahoy
2
2
 
3
- :fire: Never build an analytics platform from scratch again.
4
-
5
- Ahoy provides a solid foundation to track visits and events in Ruby, JavaScript, and native apps.
6
-
7
- Works with any data store so you can easily scale.
3
+ Ahoy provides a solid foundation to track visits and events in Ruby, JavaScript, and native apps. Works with any data store so you can easily scale.
8
4
 
9
5
  :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
10
6
 
11
7
  :postbox: To track emails, check out [Ahoy Email](https://github.com/ankane/ahoy_email).
12
8
 
13
- See [upgrade instructions](#100) on how to move to 1.0.
14
-
15
9
  ## Installation
16
10
 
17
11
  Add this line to your application’s Gemfile:
@@ -31,56 +25,23 @@ And add the javascript file in `app/assets/javascripts/application.js` after jQu
31
25
 
32
26
  Ahoy supports a number of data stores out of the box. You can start with one of them and customize as needed, or create your own store from scratch.
33
27
 
34
- - [PostgreSQL](#postgresql)
35
- - [MySQL](#mysql-or-sqlite)
36
- - [SQLite](#mysql-or-sqlite)
28
+ - [PostgreSQL, MySQL, or SQLite](#postgresql-mysql-or-sqlite)
37
29
  - [MongoDB](#mongodb)
38
30
  - [Fluentd](#fluentd)
39
- - [RabbitMQ](#rabbitmq-master)
40
- - [Kinesis Firehose](#kinesis-firehose-master)
31
+ - [RabbitMQ](#rabbitmq)
32
+ - [Amazon Kinesis Firehose](#amazon-kinesis-firehose)
41
33
  - [Logs](#logs)
42
34
  - [Custom](#custom)
43
35
 
44
- ### PostgreSQL
45
-
46
- For Rails 4.2 and PostgreSQL 9.4 or greater, use:
47
-
48
- ```sh
49
- rails generate ahoy:stores:active_record -d postgresql-jsonb
50
- rake db:migrate
51
- ```
52
-
53
- For Rails 4 and PostgreSQL 9.2 or greater, use:
54
-
55
- ```sh
56
- rails generate ahoy:stores:active_record -d postgresql
57
- rake db:migrate
58
- ```
59
-
60
- Otherwise, follow the instructions for MySQL.
61
-
62
- ### MySQL or SQLite
63
-
64
- Add [activeuuid](https://github.com/jashmenn/activeuuid) to your Gemfile.
65
-
66
- ```ruby
67
- gem 'activeuuid', '>= 0.5.0'
68
- ```
36
+ ### PostgreSQL, MySQL, or SQLite
69
37
 
70
- And run:
38
+ Run:
71
39
 
72
40
  ```sh
73
41
  rails generate ahoy:stores:active_record
74
42
  rake db:migrate
75
43
  ```
76
44
 
77
- If you just want visits, run:
78
-
79
- ```sh
80
- rails generate ahoy:stores:active_record_visits
81
- rake db:migrate
82
- ```
83
-
84
45
  ### MongoDB
85
46
 
86
47
  ```sh
@@ -119,7 +80,7 @@ rails generate ahoy:stores:bunny
119
80
 
120
81
  Use `ENV["RABBITMQ_URL"]` to configure.
121
82
 
122
- ### Kinesis Firehose
83
+ ### Amazon Kinesis Firehose
123
84
 
124
85
  Add [aws-sdk](https://github.com/aws/aws-sdk-ruby) to your Gemfile.
125
86
 
@@ -223,7 +184,7 @@ ahoy.authenticate(user)
223
184
  Stores are built to be highly customizable.
224
185
 
225
186
  ```ruby
226
- class Ahoy::Store < Ahoy::Stores::ActiveRecordStore
187
+ class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore
227
188
  # add methods here
228
189
  end
229
190
  ```
@@ -233,7 +194,7 @@ end
233
194
  Exclude visits and events from being tracked with:
234
195
 
235
196
  ```ruby
236
- class Ahoy::Store < Ahoy::Stores::ActiveRecordStore
197
+ class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore
237
198
  def exclude?
238
199
  bot? || request.ip == "192.168.1.1"
239
200
  end
@@ -245,7 +206,7 @@ Bots are excluded by default.
245
206
  ### Track Additional Values
246
207
 
247
208
  ```ruby
248
- class Ahoy::Store < Ahoy::Stores::ActiveRecordStore
209
+ class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore
249
210
  def track_visit(options)
250
211
  super do |visit|
251
212
  visit.gclid = visit_properties.landing_params["gclid"]
@@ -265,7 +226,7 @@ end
265
226
  If you use a method other than `current_user`, set it here:
266
227
 
267
228
  ```ruby
268
- class Ahoy::Store < Ahoy::Stores::ActiveRecordStore
229
+ class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore
269
230
  def user
270
231
  controller.true_user
271
232
  end
@@ -274,18 +235,12 @@ end
274
235
 
275
236
  ### Report Exceptions
276
237
 
277
- Exceptions are rescued so analytics do not break your app.
278
-
279
- Ahoy uses [Errbase](https://github.com/ankane/errbase) to try to report them to a service by default.
238
+ Exceptions are rescued so analytics do not break your app. Ahoy uses [Safely](https://github.com/ankane/safely) to try to report them to a service by default.
280
239
 
281
240
  To customize this, use:
282
241
 
283
242
  ```ruby
284
- class Ahoy::Store < Ahoy::Stores::ActiveRecordStore
285
- def report_exception(e)
286
- Rollbar.report_exception(e)
287
- end
288
- end
243
+ Safely.report_exception_method = proc { |e| Rollbar.error(e) }
289
244
  ```
290
245
 
291
246
  ### Use Different Models
@@ -293,7 +248,7 @@ end
293
248
  For ActiveRecord and Mongoid stores
294
249
 
295
250
  ```ruby
296
- class Ahoy::Store < Ahoy::Stores::ActiveRecordStore
251
+ class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore
297
252
  def visit_model
298
253
  CustomVisit
299
254
  end
@@ -361,11 +316,13 @@ First, generate a migration and add a `visit_id` column.
361
316
  ```ruby
362
317
  class AddVisitIdToOrders < ActiveRecord::Migration
363
318
  def change
364
- add_column :orders, :visit_id, :uuid
319
+ add_column :orders, :visit_id, :integer
365
320
  end
366
321
  end
367
322
  ```
368
323
 
324
+ **Note**: Use the `uuid` column type if the `id` column on `visits` is a `uuid`.
325
+
369
326
  Then, add `visitable` to the model.
370
327
 
371
328
  ```ruby
@@ -406,7 +363,13 @@ Ahoy.geocode = :async
406
363
 
407
364
  For Rails 4.0 and 4.1, you’ll need to add [activejob_backport](https://github.com/ankane/activejob_backport).
408
365
 
409
- Or disable it with:
366
+ To change the queue name (`ahoy` by default), use:
367
+
368
+ ```ruby
369
+ Ahoy.job_queue = :low_priority
370
+ ```
371
+
372
+ Or disable geocoding with:
410
373
 
411
374
  ```ruby
412
375
  Ahoy.geocode = false
@@ -505,7 +468,7 @@ added_item_ids = Ahoy::Event.where(user_id: viewed_store_ids, name: "Added item
505
468
  viewed_checkout_ids = Ahoy::Event.where(user_id: added_item_ids, name: "Viewed checkout").uniq.pluck(:user_id)
506
469
  ```
507
470
 
508
- The same approach also works with visitor ids.
471
+ The same approach also works with visitor tokens.
509
472
 
510
473
  ## Native Apps
511
474
 
@@ -513,7 +476,7 @@ The same approach also works with visitor ids.
513
476
 
514
477
  When a user launches the app, create a visit.
515
478
 
516
- Generate a `visit_id` and `visitor_id` as [UUIDs](http://en.wikipedia.org/wiki/Universally_unique_identifier).
479
+ Generate a `visit_token` and `visitor_token` as [UUIDs](http://en.wikipedia.org/wiki/Universally_unique_identifier).
517
480
 
518
481
  Send these values in the `Ahoy-Visit` and `Ahoy-Visitor` headers with all requests.
519
482
 
@@ -540,25 +503,34 @@ Use an array to pass multiple events at once.
540
503
 
541
504
  ## Upgrading
542
505
 
543
- ### PostgreSQL 9.4 + JSONB
506
+ ### 1.4.0
544
507
 
545
- ```sh
546
- rails g migration change_properties_to_jsonb_on_ahoy_events
508
+ There’s nothing to do, but it’s worth noting the default store was changed from `ActiveRecordStore` to `ActiveRecordTokenStore` for new installations.
509
+
510
+ ### json -> jsonb
511
+
512
+ Create a migration to add a new `jsonb` column.
513
+
514
+ ```ruby
515
+ rename_column :ahoy_events, :properties, :properties_json
516
+ add_column :ahoy_events, :properties, :jsonb
547
517
  ```
548
518
 
549
- And add:
519
+ Restart your web server immediately afterwards, as Ahoy will rescue and report errors until then.
550
520
 
551
- ```rb
552
- def up
553
- change_column :ahoy_events, :properties, :jsonb, using: "properties::jsonb"
554
- end
521
+ Sync the new column.
555
522
 
556
- def down
557
- change_column :ahoy_events, :properties, :json
523
+ ```ruby
524
+ Ahoy::Event.where(properties: nil).select(:id).find_in_batches do |events|
525
+ Ahoy::Event.where(id: events.map(&:id)).update_all("properties = properties_json::jsonb")
558
526
  end
559
527
  ```
560
528
 
561
- Note: This will lock the table while the migration is running.
529
+ Then create a migration to drop the old column.
530
+
531
+ ```ruby
532
+ remove_column :ahoy_events, :properties_json
533
+ ```
562
534
 
563
535
  ### 1.0.0
564
536
 
data/ahoy_matey.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "rails"
21
+ spec.add_dependency "railties"
22
22
  spec.add_dependency "addressable"
23
23
  spec.add_dependency "browser", "~> 2.0"
24
24
  spec.add_dependency "geocoder"
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency "user_agent_parser"
27
27
  spec.add_dependency "request_store"
28
28
  spec.add_dependency "uuidtools"
29
- spec.add_dependency "errbase"
29
+ spec.add_dependency "safely_block"
30
30
  spec.add_dependency "rack-attack"
31
31
 
32
32
  spec.add_development_dependency "bundler", "~> 1.5"
data/lib/ahoy.rb CHANGED
@@ -1,4 +1,3 @@
1
- require "rails"
2
1
  require "active_support/core_ext"
3
2
  require "addressable/uri"
4
3
  require "browser"
@@ -7,7 +6,7 @@ require "referer-parser"
7
6
  require "user_agent_parser"
8
7
  require "request_store"
9
8
  require "uuidtools"
10
- require "errbase"
9
+ require "safely_block"
11
10
 
12
11
  require "ahoy/version"
13
12
  require "ahoy/tracker"
@@ -27,7 +26,6 @@ require "ahoy/stores/fluentd_store"
27
26
  require "ahoy/stores/mongoid_store"
28
27
  require "ahoy/stores/kinesis_firehose_store"
29
28
  require "ahoy/stores/bunny_store"
30
- require "ahoy/log_silencer"
31
29
  require "ahoy/engine"
32
30
  require "ahoy/warden" if defined?(Warden)
33
31
 
@@ -77,6 +75,9 @@ module Ahoy
77
75
  mattr_accessor :throttle_period
78
76
  self.throttle_period = 1.minute
79
77
 
78
+ mattr_accessor :job_queue
79
+ self.job_queue = :ahoy
80
+
80
81
  def self.ensure_uuid(id)
81
82
  valid = UUIDTools::UUID.parse(id) rescue nil
82
83
  if valid
data/lib/ahoy/engine.rb CHANGED
@@ -1,12 +1,30 @@
1
1
  module Ahoy
2
2
  class Engine < ::Rails::Engine
3
3
  initializer "ahoy.middleware", after: "sprockets.environment" do |app|
4
- Rails::Rack::Logger.send(:prepend, Ahoy::LogSilencer) if Ahoy.quiet
5
-
6
4
  if Ahoy.throttle
7
5
  require "ahoy/throttle"
8
6
  app.middleware.use Ahoy::Throttle
9
7
  end
8
+
9
+ next unless Ahoy.quiet
10
+
11
+ # Parse PATH_INFO by assets prefix
12
+ AHOY_PREFIX = "/ahoy/".freeze
13
+
14
+ # Just create an alias for call in middleware
15
+ Rails::Rack::Logger.class_eval do
16
+ def call_with_quiet_ahoy(env)
17
+ if env["PATH_INFO"].start_with?(AHOY_PREFIX) && logger.respond_to?(:silence_logger)
18
+ logger.silence_logger do
19
+ call_without_quiet_ahoy(env)
20
+ end
21
+ else
22
+ call_without_quiet_ahoy(env)
23
+ end
24
+ end
25
+ alias_method :call_without_quiet_ahoy, :call
26
+ alias_method :call, :call_with_quiet_ahoy
27
+ end
10
28
  end
11
29
  end
12
30
  end
@@ -7,7 +7,8 @@ module Ahoy
7
7
  v.visit_token = ahoy.visit_token
8
8
  v.visitor_token = ahoy.visitor_token
9
9
  v.user = user if v.respond_to?(:user=)
10
- v.created_at = options[:started_at]
10
+ v.started_at = options[:started_at] if v.respond_to?(:started_at)
11
+ v.created_at = options[:started_at] if v.respond_to?(:created_at)
11
12
  end
12
13
 
13
14
  set_visit_properties(visit)
@@ -27,7 +27,7 @@ module Ahoy
27
27
  end
28
28
 
29
29
  def report_exception(e)
30
- Errbase.report(e)
30
+ raise e
31
31
  end
32
32
 
33
33
  def user
@@ -73,7 +73,7 @@ module Ahoy
73
73
 
74
74
  def geocode(visit)
75
75
  if Ahoy.geocode == :async
76
- Ahoy::GeocodeJob.perform_later(visit)
76
+ Ahoy::GeocodeJob.set(queue: Ahoy.job_queue).perform_later(visit)
77
77
  end
78
78
  end
79
79
 
data/lib/ahoy/tracker.rb CHANGED
@@ -124,15 +124,14 @@ module Ahoy
124
124
  @store.exclude?
125
125
  end
126
126
 
127
+ # odd pattern for backwards compatibility
128
+ # TODO remove this method in next major release
127
129
  def report_exception(e)
128
- begin
130
+ safely do
129
131
  @store.report_exception(e)
130
- rescue
131
- # fail-safe
132
- $stderr.puts "Error reporting exception"
133
- end
134
- if Rails.env.development? || Rails.env.test?
135
- raise e
132
+ if Rails.env.development? || Rails.env.test?
133
+ raise e
134
+ end
136
135
  end
137
136
  end
138
137
 
data/lib/ahoy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ahoy
2
- VERSION = "1.3.1"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -24,7 +24,8 @@ module Ahoy
24
24
  end
25
25
 
26
26
  def copy_migration
27
- unless options["database"].in?([nil, "postgresql", "postgresql-jsonb"])
27
+ @database = options["database"] || detect_database
28
+ unless @database.in?([nil, "postgresql", "postgresql-jsonb", "mysql", "sqlite"])
28
29
  raise Thor::Error, "Unknown database option"
29
30
  end
30
31
  migration_template "active_record_events_migration.rb", "db/migrate/create_ahoy_events.rb"
@@ -37,6 +38,15 @@ module Ahoy
37
38
  def create_initializer
38
39
  template "active_record_initializer.rb", "config/initializers/ahoy.rb"
39
40
  end
41
+
42
+ def detect_database
43
+ postgresql_version = ActiveRecord::Base.connection.send(:postgresql_version) rescue 0
44
+ if postgresql_version >= 90400
45
+ "postgresql-jsonb"
46
+ elsif postgresql_version >= 90200
47
+ "postgresql"
48
+ end
49
+ end
40
50
  end
41
51
  end
42
52
  end
@@ -3,7 +3,7 @@ module Ahoy
3
3
  self.table_name = "ahoy_events"
4
4
 
5
5
  belongs_to :visit
6
- belongs_to :user<% if options["database"].blank? %>
6
+ belongs_to :user<% unless %w(postgresql postgresql-jsonb).include?(@database) %>
7
7
 
8
8
  serialize :properties, JSON<% end %>
9
9
  end
@@ -1,20 +1,19 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration
2
2
  def change
3
- create_table :ahoy_events, id: false do |t|
4
- t.uuid :id, default: nil, primary_key: true
5
- t.uuid :visit_id, default: nil
3
+ create_table :ahoy_events do |t|
4
+ t.integer :visit_id
6
5
 
7
6
  # user
8
7
  t.integer :user_id
9
8
  # add t.string :user_type if polymorphic
10
9
 
11
10
  t.string :name
12
- t.<% case options["database"] when "postgresql" %>json<% when "postgresql-jsonb" %>jsonb<% else %>text<% end %> :properties
11
+ t.<% case @database when "postgresql" %>json<% when "postgresql-jsonb" %>jsonb<% else %>text<% end %> :properties
13
12
  t.timestamp :time
14
13
  end
15
14
 
16
- add_index :ahoy_events, [:visit_id]
17
- add_index :ahoy_events, [:user_id]
18
- add_index :ahoy_events, [:time]
15
+ add_index :ahoy_events, [:visit_id, :name]
16
+ add_index :ahoy_events, [:user_id, :name]
17
+ add_index :ahoy_events, [:name, :time]
19
18
  end
20
19
  end
@@ -1,3 +1,3 @@
1
- class Ahoy::Store < Ahoy::Stores::ActiveRecordStore
1
+ class Ahoy::Store < Ahoy::Stores::ActiveRecordTokenStore
2
2
  # customize here
3
3
  end
@@ -1,8 +1,8 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration
2
2
  def change
3
- create_table :visits, id: false do |t|
4
- t.uuid :id, default: nil, primary_key: true
5
- t.uuid :visitor_id, default: nil
3
+ create_table :visits do |t|
4
+ t.string :visit_token
5
+ t.string :visitor_token
6
6
 
7
7
  # the rest are recommended but optional
8
8
  # simply remove the columns you don't want
@@ -51,6 +51,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration
51
51
  t.timestamp :started_at
52
52
  end
53
53
 
54
+ add_index :visits, [:visit_token], unique: true
54
55
  add_index :visits, [:user_id]
55
56
  end
56
57
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoy_matey
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
@@ -11,7 +11,7 @@ cert_chain: []
11
11
  date: 2016-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: railties
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -123,7 +123,7 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: errbase
126
+ name: safely_block
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
@@ -219,7 +219,6 @@ files:
219
219
  - lib/ahoy/deckhands/utm_parameter_deckhand.rb
220
220
  - lib/ahoy/engine.rb
221
221
  - lib/ahoy/geocode_job.rb
222
- - lib/ahoy/log_silencer.rb
223
222
  - lib/ahoy/logger_silencer.rb
224
223
  - lib/ahoy/model.rb
225
224
  - lib/ahoy/stores/active_record_store.rb
@@ -1,16 +0,0 @@
1
- module Ahoy
2
- module LogSilencer
3
- PATH_INFO = "PATH_INFO".freeze
4
- AHOY_PREFIX = "/ahoy/".freeze
5
-
6
- def call(env)
7
- if env[PATH_INFO].start_with?(AHOY_PREFIX) && logger.respond_to?(:silence_logger)
8
- logger.silence_logger do
9
- super
10
- end
11
- else
12
- super
13
- end
14
- end
15
- end
16
- end