framed_rails 0.1.0
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 +11 -0
- data/.ruby-version +1 -0
- data/CHANGELOG +1 -0
- data/Gemfile +3 -0
- data/LICENSE +1 -0
- data/README.md +107 -0
- data/framed_rails.gemspec +37 -0
- data/lib/framed/client.rb +34 -0
- data/lib/framed/emitters.rb +113 -0
- data/lib/framed/example.rb +17 -0
- data/lib/framed/exceptions.rb +13 -0
- data/lib/framed/okjson.rb +602 -0
- data/lib/framed/rails.rb +43 -0
- data/lib/framed/railtie.rb +9 -0
- data/lib/framed/utils.rb +54 -0
- data/lib/framed/version.rb +4 -0
- data/lib/framed_rails.rb +71 -0
- data/vendor/gems/excon-0.45.3/data/cacert.pem +3860 -0
- data/vendor/gems/excon-0.45.3/lib/excon/connection.rb +469 -0
- data/vendor/gems/excon-0.45.3/lib/excon/constants.rb +142 -0
- data/vendor/gems/excon-0.45.3/lib/excon/errors.rb +155 -0
- data/vendor/gems/excon-0.45.3/lib/excon/extensions/uri.rb +33 -0
- data/vendor/gems/excon-0.45.3/lib/excon/headers.rb +83 -0
- data/vendor/gems/excon-0.45.3/lib/excon/middlewares/base.rb +24 -0
- data/vendor/gems/excon-0.45.3/lib/excon/middlewares/decompress.rb +35 -0
- data/vendor/gems/excon-0.45.3/lib/excon/middlewares/escape_path.rb +11 -0
- data/vendor/gems/excon-0.45.3/lib/excon/middlewares/expects.rb +18 -0
- data/vendor/gems/excon-0.45.3/lib/excon/middlewares/idempotent.rb +33 -0
- data/vendor/gems/excon-0.45.3/lib/excon/middlewares/instrumentor.rb +34 -0
- data/vendor/gems/excon-0.45.3/lib/excon/middlewares/mock.rb +51 -0
- data/vendor/gems/excon-0.45.3/lib/excon/middlewares/redirect_follower.rb +56 -0
- data/vendor/gems/excon-0.45.3/lib/excon/middlewares/response_parser.rb +12 -0
- data/vendor/gems/excon-0.45.3/lib/excon/pretty_printer.rb +45 -0
- data/vendor/gems/excon-0.45.3/lib/excon/response.rb +212 -0
- data/vendor/gems/excon-0.45.3/lib/excon/socket.rb +310 -0
- data/vendor/gems/excon-0.45.3/lib/excon/ssl_socket.rb +151 -0
- data/vendor/gems/excon-0.45.3/lib/excon/standard_instrumentor.rb +27 -0
- data/vendor/gems/excon-0.45.3/lib/excon/unix_socket.rb +40 -0
- data/vendor/gems/excon-0.45.3/lib/excon/utils.rb +87 -0
- data/vendor/gems/excon-0.45.3/lib/excon.rb +234 -0
- metadata +91 -0
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-1.9.3-p551@framed_rails
|
data/CHANGELOG
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
CHANGELOG
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
LICENSE
|
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
`framed_rails`
|
2
|
+
------------
|
3
|
+
|
4
|
+
`framed_rails` is a gem to add Framed instrumentation to your rails4
|
5
|
+
app. For each pageview, it sends an event to Framed.
|
6
|
+
|
7
|
+
To use this with rails:
|
8
|
+
|
9
|
+
|
10
|
+
* Add `framed_rails` to your Gemfile.
|
11
|
+
* Add the following to `config/initializers/framed_rails.rb`:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
require 'framed_rails'
|
15
|
+
|
16
|
+
Framed.configure do |config|
|
17
|
+
config[:write_key] = 'Framed key'
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
Note that the threaded emitter works on a background thread. It is
|
22
|
+
possible that events will be unreported when your containing process
|
23
|
+
ends, unless you drain at process shutdown, i.e.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
Framed.drain
|
27
|
+
```
|
28
|
+
|
29
|
+
If reporting fails, the exception will be logged to STDERR by default,
|
30
|
+
unless Rails is detected. In that case, the `Rails.logger` will be
|
31
|
+
used.
|
32
|
+
|
33
|
+
|
34
|
+
Configuration
|
35
|
+
-------------
|
36
|
+
|
37
|
+
<table>
|
38
|
+
<tr>
|
39
|
+
<th>Key</th>
|
40
|
+
<th>Description</th>
|
41
|
+
<th>Default</th>
|
42
|
+
</tr>
|
43
|
+
|
44
|
+
<tr>
|
45
|
+
<td>:consumer</td>
|
46
|
+
<td>The emitter to be used for reporting. See the Emitters
|
47
|
+
section below.</td>
|
48
|
+
<td>Framed::Emitters::Blocking</td>
|
49
|
+
</tr>
|
50
|
+
|
51
|
+
<tr>
|
52
|
+
<td>:endpoint</td>
|
53
|
+
<td>The URL to POST to, using basic auth with your write key</td>
|
54
|
+
<td>Framed::SEGMENT_API</td>
|
55
|
+
</tr>
|
56
|
+
|
57
|
+
<tr>
|
58
|
+
<td>:user_id_controller_method</td>
|
59
|
+
<td>The name of a controller method which returns the user ID, if
|
60
|
+
any</td>
|
61
|
+
<td>'framed_devise_user_id'</td>
|
62
|
+
</tr>
|
63
|
+
|
64
|
+
<tr>
|
65
|
+
<td>:logger</td>
|
66
|
+
<td>A Logger for reporting errors.</td>
|
67
|
+
<td>STDERR, or Rails.logger if detected.</td>
|
68
|
+
</tr>
|
69
|
+
|
70
|
+
<tr>
|
71
|
+
<td>:anonymous_cookie</td>
|
72
|
+
<td>The name of the in signed cookie for anonymous user IDs.
|
73
|
+
Long-lived anonymous user IDs are issued anonymous users.</td>
|
74
|
+
<td>Framed::COOKIE_NAME</td>
|
75
|
+
</tr>
|
76
|
+
|
77
|
+
<tr>
|
78
|
+
<td>:user_id_controller_method</td>
|
79
|
+
<td>The name of a controller method which can provide the current
|
80
|
+
User ID. Devise just works.</td>
|
81
|
+
<td>'framed_devise_user_id'</td>
|
82
|
+
</tr>
|
83
|
+
</table>
|
84
|
+
|
85
|
+
Emitters
|
86
|
+
--------
|
87
|
+
|
88
|
+
By default, the report is sent with a blocking Emitter. If you would
|
89
|
+
prefer a non-blocking emitter, you can include the following line in
|
90
|
+
your configure block:
|
91
|
+
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
config[:consumer] => Framed::Emitters::Threaded
|
95
|
+
```
|
96
|
+
|
97
|
+
If you'd like to implement your own, see `lib/framed/emitters.rb`,
|
98
|
+
particularly Base and Blocking as examples.
|
99
|
+
|
100
|
+
Emitters included in this gem:
|
101
|
+
|
102
|
+
* `Framed::Emitters::InMemory` - stores reported events in memory,
|
103
|
+
rather than transmitting them. Events are later available as
|
104
|
+
Framed.consumer.reported.
|
105
|
+
* `Framed::Emitters::Logger` - Logs an info message to config[:logger].
|
106
|
+
* `Framed::Emitters::Blocking` - Logs to Framed, using a blocking request.
|
107
|
+
* `Framed::Emitters::Threaded` - Logs to Framed, using a background-threaded request.
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'framed/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "framed_rails"
|
9
|
+
s.version = Framed::VERSION
|
10
|
+
s.required_ruby_version = '>= 1.8.7'
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.authors = [ "Jeremy Dunck" ]
|
13
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
14
|
+
s.licenses = ['MIT']
|
15
|
+
s.description = <<-EOS
|
16
|
+
TK
|
17
|
+
EOS
|
18
|
+
s.email = "support@framed.io"
|
19
|
+
s.executables = [ ]
|
20
|
+
s.extra_rdoc_files = [
|
21
|
+
"CHANGELOG",
|
22
|
+
"LICENSE",
|
23
|
+
"README.md"
|
24
|
+
]
|
25
|
+
|
26
|
+
file_list = `git ls-files`.split
|
27
|
+
s.files = file_list
|
28
|
+
|
29
|
+
s.homepage = "http://www.github.com/framed-data/framed_rails"
|
30
|
+
s.require_paths = ["lib", 'vendor/gems/excon-0.45.3/lib']
|
31
|
+
s.rubygems_version = Gem::VERSION
|
32
|
+
s.summary = "Framed.io data collector"
|
33
|
+
|
34
|
+
# s.add_development_dependency 'rake', '10.1.0'
|
35
|
+
|
36
|
+
# FIXME: RUBY_VERSION, RUBY_PLATFORM, RUBY_ENGINE
|
37
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'excon'
|
2
|
+
require 'base64'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'framed/exceptions'
|
6
|
+
|
7
|
+
module Framed
|
8
|
+
class Client
|
9
|
+
attr_accessor :config
|
10
|
+
|
11
|
+
def initialize(config)
|
12
|
+
raise Error.new('No API endpoint specified') unless config[:endpoint]
|
13
|
+
raise Error.new('No write_key specified') unless config[:write_key]
|
14
|
+
|
15
|
+
@config = config
|
16
|
+
end
|
17
|
+
|
18
|
+
def track(data)
|
19
|
+
write_key = Base64.strict_encode64(@config[:write_key])
|
20
|
+
payload = JSON.generate(data)
|
21
|
+
response = Excon.post(@config[:endpoint],
|
22
|
+
:headers => {
|
23
|
+
'Authorization' => "Basic #{write_key}",
|
24
|
+
'Content-Type' => 'application/json'
|
25
|
+
},
|
26
|
+
:body => payload
|
27
|
+
)
|
28
|
+
|
29
|
+
if response.status != 200
|
30
|
+
raise Framed::RequestError.new("Failed Client.track #{response.status} with data #{payload}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Framed
|
5
|
+
module Emitters
|
6
|
+
class Base
|
7
|
+
def initialize(client)
|
8
|
+
@client = client
|
9
|
+
end
|
10
|
+
|
11
|
+
def stop(drain = false)
|
12
|
+
|
13
|
+
end
|
14
|
+
def start
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def enqueue(event)
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def transmit(event)
|
25
|
+
begin
|
26
|
+
@client.track(event)
|
27
|
+
rescue StandardError => exc
|
28
|
+
Framed.logger.error("framed_rails: transmit failed: #{exc}")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class InMemory < Base
|
34
|
+
attr_reader :reported
|
35
|
+
|
36
|
+
def initialize(client)
|
37
|
+
super
|
38
|
+
@reported = []
|
39
|
+
end
|
40
|
+
|
41
|
+
def enqueue(event)
|
42
|
+
@reported << event
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Logger < Base
|
47
|
+
def enqueue(event)
|
48
|
+
Framed.logger.info(JSON.generate(event))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Threaded < Base
|
53
|
+
def initialize(client)
|
54
|
+
super
|
55
|
+
@queue = Queue.new
|
56
|
+
end
|
57
|
+
|
58
|
+
def enqueue(event)
|
59
|
+
@queue << event
|
60
|
+
start
|
61
|
+
end
|
62
|
+
|
63
|
+
def start
|
64
|
+
return if @thread
|
65
|
+
|
66
|
+
@thread = Thread.new do
|
67
|
+
while true
|
68
|
+
begin
|
69
|
+
process_events
|
70
|
+
rescue StandardError => exc
|
71
|
+
Framed.logger.error("framed_rails: run_thread failed: #{exc}")
|
72
|
+
stop
|
73
|
+
end
|
74
|
+
sleep(0.5)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def stop(drain = false)
|
80
|
+
if @thread
|
81
|
+
@thread.kill
|
82
|
+
end
|
83
|
+
@thread = nil
|
84
|
+
|
85
|
+
if drain && @queue.length
|
86
|
+
process_events
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def dequeue
|
93
|
+
@queue.pop
|
94
|
+
end
|
95
|
+
|
96
|
+
def process_events
|
97
|
+
while @queue.length > 0
|
98
|
+
transmit(dequeue)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class Blocking < Base
|
104
|
+
def start
|
105
|
+
end
|
106
|
+
def stop
|
107
|
+
end
|
108
|
+
def enqueue(event)
|
109
|
+
transmit(event)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'framed_rails'
|
2
|
+
|
3
|
+
Framed.configure do |config|
|
4
|
+
config[:write_key] = 'XWkzILLq5gLUKXQUhAl4DJej1wkxqiBy'
|
5
|
+
# config[:consumer] = Framed::Blocking
|
6
|
+
end
|
7
|
+
|
8
|
+
data = {
|
9
|
+
anonymousId: "anon1",
|
10
|
+
userId: "user1",
|
11
|
+
event: "signup",
|
12
|
+
properties: {
|
13
|
+
name: "value"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
Framed.report(data)
|