sojourn 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a5bcd732bdfc1df4fdd68744f4c807f894104848
4
- data.tar.gz: 927a8ba15bd0948cb8c390c15b7c900785051a1f
3
+ metadata.gz: 9f2ae69a242be094ed09f87d8721b0b12c7369a4
4
+ data.tar.gz: 16deb25d1a1598c08cd96162a59ec25a344fde88
5
5
  SHA512:
6
- metadata.gz: 469867e717db9bc51b25e1b414a711db552631225524e781a2c9a5d62e3faefdf2d8e0f77acd426aaa7ac094b62e35b7361ec5c761ed4dadaddf7ce8bba2d32b
7
- data.tar.gz: 44d5346a2ccabc605e220af036077b2f9969213580bc04188852f5d6ee6ff4a2b3a6ea1bf566cefdaa0cde87177092d3892247448bafdc19703cf8f9c96dc3f4
6
+ metadata.gz: 99a18bf20addc6f178c68b9fc96a990c512ef6c1839c54755dc523327c77984dafedff591a122da996e536e030de6e247800f3643f00b9425c937c22770d7788
7
+ data.tar.gz: dc459a98a2a177b53aacebfd400b37853ad61c6da727ed48713884d1f7960c90146e7c362211391a551472aed00389038204920da5724ce5f9f2cc7d0ad7618b
data/README.md CHANGED
@@ -11,16 +11,22 @@ Simple source & event tracking for Rails. This gem automatically tracks *sojourn
11
11
 
12
12
  ## How It Works
13
13
 
14
- **Everything is tracked in the form of events.** Yep, events all the way down.
15
- (See 'Why Events?' below for the reasoning behind this.)
14
+ Whenever a new visitor ("sojourner") arrives to the site, an event is tracked containing
15
+ basic data about their browser and where they came from. Similar events are also tracked
16
+ whenever a user logs in, logs out, or visits again from an external site. In addition,
17
+ you can track a custom event anytime a visitor does something of interest to you.
16
18
 
17
- Sojourn assigns each *sojourner* a UUID, which is tracked across requests. All events are
18
- associated with this UUID and with the current user's ID (if logged-in).
19
+ Ultimately, rather than storing parts of the data in separate tables, **all data is
20
+ tracked in the form of events.** Yep, events all the way down. (See 'Why Events?' below
21
+ for the reasoning behind this.)
19
22
 
20
- Events (`Sojourn::Event`) consist of a name, a set of properties (key-value hash) and information
21
- about the request. In the current ActiveRecord implementation, requests (`Sojourn::Request`) can
22
- be queried separately and may have many events. See 'Usage' below for the details of these models.
23
+ Sojourn assigns each "sojourner" a UUID, which is tracked across requests. All events are
24
+ associated with this UUID and with the current user's ID (if logged-in). The current
25
+ request is also assigned a UUID (which defaults to the `X-Request-ID` header).
23
26
 
27
+ Events consist of an event name (defining a collection of events), a session UUID,
28
+ and a set of properties (key-value data) which includes information about the request.
29
+ In the PostgreSQL implementation, we use a `JSONB` column to store the key-value data.
24
30
 
25
31
  ## Usage
26
32
 
@@ -28,17 +34,16 @@ be queried separately and may have many events. See 'Usage' below for the detail
28
34
  # Track a custom event (highly encouraged!):
29
35
  sojourn.track! 'clicked call-to-action', plan_choice: 'enterprise'
30
36
 
31
- # If you don't have access to a controller context (i.e. the event is not occurring during a web
32
- # request), you can still track a raw event like this:
33
-
34
- Sojourn.track_raw_event! 'subscription expired', plan: 'enterprise', customer_id: 'xyb123'
35
-
36
37
  # Read events using ActiveRecord
37
38
  e = Sojourn::Event.last
38
39
  e.name # event name (e.g. 'clicked call-to-action')
39
40
  e.sojourner_uuid # uuid tracked across requests, stored in cookie
40
41
  e.user # User or nil
41
42
  e.properties # key-value hash (e.g. "{ plan_choice: 'enterprise' }")
43
+
44
+ # If you don't have access to a controller context (i.e. the event is not occurring during a web
45
+ # request), you can still track a raw event like this:
46
+ Sojourn.track_raw_event! 'subscription expired', plan: 'enterprise', customer_id: 'xyb123'
42
47
  ```
43
48
 
44
49
  ## Default Events
@@ -51,7 +56,7 @@ The three built-in events are as follows:
51
56
  '!logged_out' # The sojourner has logged-out.
52
57
  ```
53
58
 
54
- A `'!sojourning'` event takes place whenever any of the following is true:
59
+ A `'!sojourning'` event takes place whenever any of the following conditions is met:
55
60
 
56
61
  * The sojourner has never been seen before (i.e. direct traffic of some kind)
57
62
  * The referer is from an external source (i.e. not the current `request.host`)
@@ -116,10 +121,17 @@ To install migrations and the `sojourn.rb` initializer, execute:
116
121
  The idea is that, at a certain scale, this kind of tracking should be dumped directly into
117
122
  append-only logs (or an event bus / messaging queue) for asynchronous processing.
118
123
 
119
- This is made easier when everything can be represented, at a basic level, as discrete events.
120
- In theory, it works with just about any data store, and makes for easy time series and funnel
121
- analysis. I'd like to move away from ActiveRecord at some point and open up the door for other,
122
- highly scalable data backends.
124
+ This is made easier when everything can be represented, at a basic level, as a set of discrete
125
+ events. In theory, it works with just about any data store, and makes for easy time series and
126
+ funnel analysis. I'd like to move away from ActiveRecord at some point and open up the door for
127
+ other, more horizontally scalable data backends, ideally with a focus on streaming data (e.g.
128
+ Kafka combined with Samza or Storm).
129
+
130
+ An added benfit of storing the start of each visit as its own event in the series (i.e. the
131
+ built-in `!sojourning` event) is that you can change the length of your visit window after
132
+ the fact and re-run your analysis. The more traditional approach is to tag each event with
133
+ some kind of incrementing visit ID, which forces you into defining what a "unique visit"
134
+ means for your product before you've even collected any data.
123
135
 
124
136
  ## Current Limitations (i.e. the 'todo' list)
125
137
 
@@ -31,7 +31,8 @@ module Sojourn
31
31
 
32
32
  def browser_data
33
33
  return @browser_data if @browser_data
34
- @browser_data = {
34
+ @browser_data = { known: false } unless browser
35
+ @browser_data ||= {
35
36
  name: browser.name,
36
37
  version: browser.version,
37
38
  platform: browser.platform,
@@ -1,3 +1,3 @@
1
1
  module Sojourn
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -50,7 +50,7 @@ module Mocks
50
50
  end
51
51
 
52
52
  def user_agent
53
- opts[:user_agent] || CHROME_UA
53
+ opts.key?(:user_agent) ? opts[:user_agent] : CHROME_UA
54
54
  end
55
55
  end
56
56
  end
@@ -21,17 +21,12 @@ module Sojourn
21
21
  its(:user_id) { is_expected.to eq(user.id) }
22
22
  its(:name) { is_expected.to eq(event_name) }
23
23
 
24
- describe 'request' do
25
- subject { Event.last.properties[:request] }
26
-
27
- its([:params]) { is_expected.to eq('filtered' => true) }
28
- its([:method]) { is_expected.to eq('get') }
29
- end
30
-
31
24
  describe 'properties' do
32
25
  subject { Event.last.properties }
33
26
 
34
27
  its(:keys) { is_expected.to eq(%w(request browser bar)) }
28
+ its([:request, :params]) { is_expected.to eq('filtered' => true) }
29
+ its([:request, :method]) { is_expected.to eq('get') }
35
30
  its([:browser, :name]) { is_expected.to eq('Chrome') }
36
31
  end
37
32
  end
@@ -73,6 +68,19 @@ module Sojourn
73
68
 
74
69
  its(:name) { is_expected.to eq('!logged_out') }
75
70
  end
71
+
72
+ context 'when user agent not present' do
73
+ let(:request) { Mocks::Request.new(user_agent: nil) }
74
+
75
+ its(:name) { is_expected.to eq('!sojourning') }
76
+
77
+ describe 'properties' do
78
+ subject { Event.last.properties }
79
+
80
+ its([:browser, :known]) { is_expected.to be(false) }
81
+ its([:browser, :name]) { is_expected.to be_nil }
82
+ end
83
+ end
76
84
  end
77
85
 
78
86
  describe 'update_session!' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sojourn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Smudge
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-04 00:00:00.000000000 Z
11
+ date: 2016-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler