request_recorder 0.1.2 → 0.2.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/Appraisals CHANGED
@@ -1,7 +1,9 @@
1
1
  appraise "rails2" do
2
+ gem "rack", "~> 1.1.6"
2
3
  gem "activerecord", "~>2.3.14"
3
4
  end
4
5
 
5
6
  appraise "rails3" do
7
+ gem "rack", ">= 1.5.2"
6
8
  gem "activerecord", "~>3.2.7"
7
9
  end
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
  gemspec
3
3
 
4
4
  gem "appraisal"
@@ -8,3 +8,4 @@ gem "rspec", "~>2"
8
8
  gem "activerecord"
9
9
  gem "sqlite3"
10
10
  gem "fakeredis"
11
+ gem "json"
data/Gemfile.lock CHANGED
@@ -1,35 +1,50 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- request_recorder (0.1.2)
4
+ request_recorder (0.2.0)
5
5
  activerecord
6
+ multi_json
6
7
  rack
7
8
 
8
9
  GEM
9
- remote: http://rubygems.org/
10
+ remote: https://rubygems.org/
10
11
  specs:
11
- activerecord (2.3.14)
12
- activesupport (= 2.3.14)
13
- activesupport (2.3.14)
14
- appraisal (0.4.1)
12
+ activemodel (3.2.13)
13
+ activesupport (= 3.2.13)
14
+ builder (~> 3.0.0)
15
+ activerecord (3.2.13)
16
+ activemodel (= 3.2.13)
17
+ activesupport (= 3.2.13)
18
+ arel (~> 3.0.2)
19
+ tzinfo (~> 0.3.29)
20
+ activesupport (3.2.13)
21
+ i18n (= 0.6.1)
22
+ multi_json (~> 1.0)
23
+ appraisal (0.5.2)
15
24
  bundler
16
25
  rake
17
- bump (0.3.5)
18
- diff-lcs (1.1.3)
19
- fakeredis (0.4.0)
26
+ arel (3.0.2)
27
+ builder (3.0.4)
28
+ bump (0.4.1)
29
+ diff-lcs (1.2.3)
30
+ fakeredis (0.4.2)
20
31
  redis (~> 3.0.0)
21
- rack (1.4.1)
22
- rake (0.9.2)
23
- redis (3.0.1)
24
- rspec (2.6.0)
25
- rspec-core (~> 2.6.0)
26
- rspec-expectations (~> 2.6.0)
27
- rspec-mocks (~> 2.6.0)
28
- rspec-core (2.6.4)
29
- rspec-expectations (2.6.0)
30
- diff-lcs (~> 1.1.2)
31
- rspec-mocks (2.6.0)
32
- sqlite3 (1.3.6)
32
+ i18n (0.6.1)
33
+ json (1.7.7)
34
+ multi_json (1.7.2)
35
+ rack (1.5.2)
36
+ rake (10.0.4)
37
+ redis (3.0.3)
38
+ rspec (2.13.0)
39
+ rspec-core (~> 2.13.0)
40
+ rspec-expectations (~> 2.13.0)
41
+ rspec-mocks (~> 2.13.0)
42
+ rspec-core (2.13.1)
43
+ rspec-expectations (2.13.0)
44
+ diff-lcs (>= 1.1.3, < 2.0)
45
+ rspec-mocks (2.13.1)
46
+ sqlite3 (1.3.7)
47
+ tzinfo (0.3.37)
33
48
 
34
49
  PLATFORMS
35
50
  ruby
@@ -39,6 +54,7 @@ DEPENDENCIES
39
54
  appraisal
40
55
  bump
41
56
  fakeredis
57
+ json
42
58
  rake
43
59
  request_recorder!
44
60
  rspec (~> 2)
data/Readme.md CHANGED
@@ -1,4 +1,4 @@
1
- Record your rack/rails requests and store them for future inspection
1
+ Record your rack/rails requests and store them for future inspection + see them in your chrome console.
2
2
 
3
3
  Install
4
4
  =======
@@ -10,28 +10,30 @@ Add to your middleware stack:
10
10
  require "request_recorder"
11
11
 
12
12
  require "request_recorder/cache_logger"
13
- use RequestRecorder::Middleware, :store => RequestRecorder::CacheLogger.new(Rails.cache)
14
-
15
- -- or --
16
-
17
- require "request_recorder/redis_logger"
18
- use RequestRecorder::Middleware, :store => RequestRecorder::RedisLogger.new(Redis.new)
13
+ use RequestRecorder::Middleware,
14
+ :store => RequestRecorder::CacheLogger.new(Rails.cache),
15
+ :frontend_auth => lambda { |env| Rails.env.development? } # TODO use something like `env.warden.user.is_admin?` in production
19
16
 
20
17
  Usage
21
18
  =====
22
19
 
23
- - request a page with `/something?request_recorder=10|my-session-name` -> record next 10 requests from my browser
20
+ - request a page with `/something?request_recorder=10-my_session_name` -> record next 10 requests from my browser
24
21
  - all the debug-level logging info from rails + activerecord gets stored
25
22
  - get log directly from the store or use the frontend
26
23
 
27
- Frontend
28
- ========
24
+ Chrome console
25
+ ==============
26
+ (needs `:frontend_auth`)
29
27
 
30
- Add :frontend_auth and find out if the current user is authorized
28
+ - Install [Chrome extension](https://chrome.google.com/webstore/detail/chrome-logger/noaneddfkdjfnfdakjjmocngnfkfehhd)
29
+ - Enable it<br/> ![Enable](http://cdn.craig.is/img/chromelogger/toggle.gif)
30
+ - Open console<br/> ![Profit](https://dl.dropboxusercontent.com/u/2670385/Web/request_recorder_output.png)
31
31
 
32
- use RequestRecorder::Middleware, :frontent_auth => lambda{|env| env.warden.user.is_admin? }
33
-
34
- Go to `/request_recorder/<key>` and see the recorded log.
32
+ Frontend
33
+ ========
34
+ (needs `:frontend_auth`)
35
+ See the log of all requests in an entire session: `/request_recorder/my_session_name`.
36
+ This also includes requests that did not get shown in the chrome logger like redirects.
35
37
 
36
38
  Author
37
39
  ======
@@ -1,6 +1,6 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source :rubygems
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
6
  gem "bump"
@@ -8,6 +8,8 @@ gem "rake"
8
8
  gem "rspec", "~>2"
9
9
  gem "sqlite3"
10
10
  gem "fakeredis"
11
+ gem "json"
12
+ gem "rack", "~> 1.1.6"
11
13
  gem "activerecord", "~>2.3.14"
12
14
 
13
15
  gemspec :path=>"../"
@@ -1,35 +1,38 @@
1
1
  PATH
2
2
  remote: /Users/mgrosser/code/tools/request_recorder
3
3
  specs:
4
- request_recorder (0.1.1)
4
+ request_recorder (0.1.2)
5
5
  activerecord
6
+ multi_json
6
7
  rack
7
8
 
8
9
  GEM
9
- remote: http://rubygems.org/
10
+ remote: https://rubygems.org/
10
11
  specs:
11
- activerecord (2.3.14)
12
- activesupport (= 2.3.14)
13
- activesupport (2.3.14)
14
- appraisal (0.4.1)
12
+ activerecord (2.3.18)
13
+ activesupport (= 2.3.18)
14
+ activesupport (2.3.18)
15
+ appraisal (0.5.2)
15
16
  bundler
16
17
  rake
17
- bump (0.3.5)
18
- diff-lcs (1.1.3)
19
- fakeredis (0.4.1)
18
+ bump (0.4.1)
19
+ diff-lcs (1.2.3)
20
+ fakeredis (0.4.2)
20
21
  redis (~> 3.0.0)
21
- rack (1.4.1)
22
- rake (0.9.2.2)
23
- redis (3.0.2)
24
- rspec (2.11.0)
25
- rspec-core (~> 2.11.0)
26
- rspec-expectations (~> 2.11.0)
27
- rspec-mocks (~> 2.11.0)
28
- rspec-core (2.11.1)
29
- rspec-expectations (2.11.3)
30
- diff-lcs (~> 1.1.3)
31
- rspec-mocks (2.11.3)
32
- sqlite3 (1.3.6)
22
+ json (1.7.7)
23
+ multi_json (1.7.2)
24
+ rack (1.1.6)
25
+ rake (10.0.4)
26
+ redis (3.0.3)
27
+ rspec (2.13.0)
28
+ rspec-core (~> 2.13.0)
29
+ rspec-expectations (~> 2.13.0)
30
+ rspec-mocks (~> 2.13.0)
31
+ rspec-core (2.13.1)
32
+ rspec-expectations (2.13.0)
33
+ diff-lcs (>= 1.1.3, < 2.0)
34
+ rspec-mocks (2.13.1)
35
+ sqlite3 (1.3.7)
33
36
 
34
37
  PLATFORMS
35
38
  ruby
@@ -39,6 +42,8 @@ DEPENDENCIES
39
42
  appraisal
40
43
  bump
41
44
  fakeredis
45
+ json
46
+ rack (~> 1.1.6)
42
47
  rake
43
48
  request_recorder!
44
49
  rspec (~> 2)
@@ -1,6 +1,6 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source :rubygems
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
6
  gem "bump"
@@ -8,6 +8,8 @@ gem "rake"
8
8
  gem "rspec", "~>2"
9
9
  gem "sqlite3"
10
10
  gem "fakeredis"
11
+ gem "json"
12
+ gem "rack", ">= 1.5.2"
11
13
  gem "activerecord", "~>3.2.7"
12
14
 
13
15
  gemspec :path=>"../"
@@ -1,48 +1,50 @@
1
1
  PATH
2
2
  remote: /Users/mgrosser/code/tools/request_recorder
3
3
  specs:
4
- request_recorder (0.1.1)
4
+ request_recorder (0.1.2)
5
5
  activerecord
6
+ multi_json
6
7
  rack
7
8
 
8
9
  GEM
9
- remote: http://rubygems.org/
10
+ remote: https://rubygems.org/
10
11
  specs:
11
- activemodel (3.2.8)
12
- activesupport (= 3.2.8)
12
+ activemodel (3.2.13)
13
+ activesupport (= 3.2.13)
13
14
  builder (~> 3.0.0)
14
- activerecord (3.2.8)
15
- activemodel (= 3.2.8)
16
- activesupport (= 3.2.8)
15
+ activerecord (3.2.13)
16
+ activemodel (= 3.2.13)
17
+ activesupport (= 3.2.13)
17
18
  arel (~> 3.0.2)
18
19
  tzinfo (~> 0.3.29)
19
- activesupport (3.2.8)
20
- i18n (~> 0.6)
20
+ activesupport (3.2.13)
21
+ i18n (= 0.6.1)
21
22
  multi_json (~> 1.0)
22
- appraisal (0.4.1)
23
+ appraisal (0.5.2)
23
24
  bundler
24
25
  rake
25
26
  arel (3.0.2)
26
27
  builder (3.0.4)
27
- bump (0.3.5)
28
- diff-lcs (1.1.3)
29
- fakeredis (0.4.1)
28
+ bump (0.4.1)
29
+ diff-lcs (1.2.3)
30
+ fakeredis (0.4.2)
30
31
  redis (~> 3.0.0)
31
32
  i18n (0.6.1)
32
- multi_json (1.3.6)
33
- rack (1.4.1)
34
- rake (0.9.2.2)
35
- redis (3.0.2)
36
- rspec (2.11.0)
37
- rspec-core (~> 2.11.0)
38
- rspec-expectations (~> 2.11.0)
39
- rspec-mocks (~> 2.11.0)
40
- rspec-core (2.11.1)
41
- rspec-expectations (2.11.3)
42
- diff-lcs (~> 1.1.3)
43
- rspec-mocks (2.11.3)
44
- sqlite3 (1.3.6)
45
- tzinfo (0.3.33)
33
+ json (1.7.7)
34
+ multi_json (1.7.2)
35
+ rack (1.5.2)
36
+ rake (10.0.4)
37
+ redis (3.0.3)
38
+ rspec (2.13.0)
39
+ rspec-core (~> 2.13.0)
40
+ rspec-expectations (~> 2.13.0)
41
+ rspec-mocks (~> 2.13.0)
42
+ rspec-core (2.13.1)
43
+ rspec-expectations (2.13.0)
44
+ diff-lcs (>= 1.1.3, < 2.0)
45
+ rspec-mocks (2.13.1)
46
+ sqlite3 (1.3.7)
47
+ tzinfo (0.3.37)
46
48
 
47
49
  PLATFORMS
48
50
  ruby
@@ -52,6 +54,8 @@ DEPENDENCIES
52
54
  appraisal
53
55
  bump
54
56
  fakeredis
57
+ json
58
+ rack (>= 1.5.2)
55
59
  rake
56
60
  request_recorder!
57
61
  rspec (~> 2)
@@ -4,12 +4,16 @@ require "rack/response"
4
4
  require "request_recorder/repeater"
5
5
  require "request_recorder/frontend"
6
6
  require "active_record"
7
+ require "rack"
8
+ require "rack/body_proxy" if defined?(Rack.release) && Rack.release >= "1.5"
9
+ require "base64"
10
+ require "multi_json"
7
11
 
8
12
  module RequestRecorder
9
13
  class Middleware
10
14
  MARKER = "request_recorder"
11
15
  MAX_STEPS = 100
12
- SEPARATOR = "|"
16
+ SEPARATOR = "-"
13
17
  NEED_AUTOFLUSH = (ActiveRecord::VERSION::MAJOR == 2)
14
18
  AUTH = :frontend_auth
15
19
 
@@ -41,9 +45,10 @@ module RequestRecorder
41
45
  id = persist_log(id, log)
42
46
 
43
47
  if result.is_a?(Exception)
44
- raise result
48
+ raise result # Do not mess up the apps normal exception behavior
45
49
  else
46
- response_with_data_in_cookie(result, steps_left, id)
50
+ extra_headers = chrome_logger_headers(log) if @auth && @auth.call(env)
51
+ response_with_data_in_cookie(result, steps_left, id, extra_headers)
47
52
  end
48
53
  end
49
54
  end
@@ -77,9 +82,9 @@ module RequestRecorder
77
82
  [steps.to_i, id]
78
83
  end
79
84
 
80
- def response_with_data_in_cookie(result, to_go, id)
85
+ def response_with_data_in_cookie(result, to_go, id, extra_headers)
81
86
  status, headers, body = result
82
- response = Rack::Response.new(body, status, headers)
87
+ response = Rack::Response.new(body, status, headers.merge(extra_headers || {}))
83
88
  if to_go <= 1
84
89
  response.delete_cookie(MARKER)
85
90
  else
@@ -89,6 +94,24 @@ module RequestRecorder
89
94
  response.finish # finish writes out the response in the expected format.
90
95
  end
91
96
 
97
+ def chrome_logger_headers(log)
98
+ data = {
99
+ 'version' => "0.1.1",
100
+ 'columns' => [ 'log' , 'backtrace' , 'type' ],
101
+ 'rows' =>
102
+ [
103
+ [["Rails log"],"xxx.rb:1","group"],
104
+ *log.split("\n").map{|line| [remove_console_colors(line).split(" "), "xxx.rb:1", ""] },
105
+ [[], "xxx.rb:1", "groupEnd"],
106
+ ]
107
+ }
108
+ {"X-ChromeLogger-Data" => Base64.encode64(MultiJson.dump(data).encode("UTF-8")).gsub("\n", "")}
109
+ end
110
+
111
+ def remove_console_colors(string)
112
+ string.gsub(/\e\[[\d;]+m/, "")
113
+ end
114
+
92
115
  def capture_logging
93
116
  old = [
94
117
  ActiveRecord::Base.logger.instance_variable_get("@log"),
@@ -1,3 +1,3 @@
1
1
  module RequestRecorder
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -10,5 +10,6 @@ Gem::Specification.new name, RequestRecorder::VERSION do |s|
10
10
  s.files = `git ls-files`.split("\n")
11
11
  s.license = "MIT"
12
12
  s.add_runtime_dependency "rack"
13
+ s.add_runtime_dependency "multi_json"
13
14
  s.add_runtime_dependency "activerecord"
14
15
  end
@@ -63,7 +63,7 @@ describe RequestRecorder do
63
63
  end
64
64
 
65
65
  it "starts with a given key" do
66
- middleware.call({"QUERY_STRING" => "request_recorder=10|abcdefg"})
66
+ middleware.call({"QUERY_STRING" => "request_recorder=10-abcdefg"})
67
67
  redis.hget(redis_key, "abcdefg").should include "SELECT"
68
68
  end
69
69
 
@@ -77,12 +77,12 @@ describe RequestRecorder do
77
77
  it "sets cookie in first step" do
78
78
  status, headers, body = middleware.call(activate_logger)
79
79
  generated_id = stored.keys.last
80
- headers["Set-Cookie"].should include "request_recorder=9%7C#{generated_id.gsub(":", "%3A").gsub(" ", "+")}; expires="
80
+ headers["Set-Cookie"].should include "request_recorder=9-#{generated_id.gsub(":", "%3A").gsub(" ", "+")}; expires="
81
81
  headers["Set-Cookie"].should include "; HttpOnly"
82
82
  end
83
83
 
84
84
  it "appends to existing log" do
85
- middleware.call("HTTP_COOKIE" => "request_recorder=8|#{existing_request_id}")
85
+ middleware.call("HTTP_COOKIE" => "request_recorder=8-#{existing_request_id}")
86
86
  existing_request = redis.hget(redis_key, existing_request_id)
87
87
  existing_request.should include "SELECT"
88
88
  existing_request.should include "BEFORE"
@@ -91,20 +91,20 @@ describe RequestRecorder do
91
91
  it "creates a new log if redis dies" do
92
92
  existing_request_id # store key
93
93
  redis.flushall
94
- middleware.call("HTTP_COOKIE" => "request_recorder=8|#{existing_request_id}")
94
+ middleware.call("HTTP_COOKIE" => "request_recorder=8-#{existing_request_id}")
95
95
  existing_request = redis.hget(redis_key, existing_request_id)
96
96
  existing_request.should include "SELECT"
97
97
  existing_request.should_not include "BEFORE"
98
98
  end
99
99
 
100
100
  it "decrements cookie on each step" do
101
- status, headers, body = middleware.call("HTTP_COOKIE" => "request_recorder=2|#{existing_request_id};foo=bar")
102
- headers["Set-Cookie"].should include "request_recorder=1%7C#{existing_request_id}; expires="
101
+ status, headers, body = middleware.call("HTTP_COOKIE" => "request_recorder=2-#{existing_request_id};foo=bar")
102
+ headers["Set-Cookie"].sub(" max-age=0;", "").should include "request_recorder=1-#{existing_request_id}; expires="
103
103
  end
104
104
 
105
105
  it "removes cookie if final step is reached" do
106
- status, headers, body = middleware.call("HTTP_COOKIE" => "request_recorder=1|#{existing_request_id};foo=bar")
107
- headers["Set-Cookie"].should include "request_recorder=; expires="
106
+ status, headers, body = middleware.call("HTTP_COOKIE" => "request_recorder=1-#{existing_request_id};foo=bar")
107
+ headers["Set-Cookie"].sub(" max-age=0;", "").should include "request_recorder=; expires="
108
108
  end
109
109
  end
110
110
 
@@ -168,13 +168,36 @@ describe RequestRecorder do
168
168
  status.should == 500
169
169
  body.should include(":frontend_auth")
170
170
  end
171
+
172
+ context "chrome logger" do
173
+ it "logs into chrome logger" do
174
+ status, headers, body = middleware.call("QUERY_STRING" => "request_recorder=10-xxx", "success" => true)
175
+ headers["X-ChromeLogger-Data"].should_not == nil
176
+ data = MultiJson.load(Base64.decode64(headers["X-ChromeLogger-Data"]))
177
+ data["rows"][1][0][2..-1] = "---" # remove timing information + activerecord 2/3 diff
178
+ data.should == {
179
+ "version"=>"0.1.1",
180
+ "columns"=>["log", "backtrace", "type"],
181
+ "rows"=>[
182
+ [["Rails log"], "xxx.rb:1", "group"],
183
+ [["Car", "Load", "---"], "xxx.rb:1", ""],
184
+ [[], "xxx.rb:1", "groupEnd"]
185
+ ]
186
+ }
187
+ end
188
+
189
+ it "does not log without frontend_auth" do
190
+ status, headers, body = middleware.call("QUERY_STRING" => "request_recorder=10-xxx")
191
+ headers["X-ChromeLogger-Data"].should == nil
192
+ end
193
+ end
171
194
  end
172
195
 
173
196
  it "integrates" do
174
197
  stored.size.should == 0
175
198
 
176
199
  # request 1 - start + decrement + log
177
- status, headers, body = middleware.call({"QUERY_STRING" => "request_recorder=3"})
200
+ status, headers, body = middleware.call({"QUERY_STRING" => "request_recorder=3-foo"})
178
201
  stored.size.should == 1
179
202
  stored.values.last.scan("SELECT").size.should == 1
180
203
  cookie = headers["Set-Cookie"].split(";").first
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: request_recorder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-15 00:00:00.000000000 Z
12
+ date: 2013-04-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -27,6 +27,22 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: multi_json
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: activerecord
32
48
  requirement: !ruby/object:Gem::Requirement
@@ -87,7 +103,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
87
103
  version: '0'
88
104
  segments:
89
105
  - 0
90
- hash: 2574127840943451255
106
+ hash: -617741979871775185
91
107
  required_rubygems_version: !ruby/object:Gem::Requirement
92
108
  none: false
93
109
  requirements:
@@ -96,10 +112,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
112
  version: '0'
97
113
  segments:
98
114
  - 0
99
- hash: 2574127840943451255
115
+ hash: -617741979871775185
100
116
  requirements: []
101
117
  rubyforge_project:
102
- rubygems_version: 1.8.24
118
+ rubygems_version: 1.8.25
103
119
  signing_key:
104
120
  specification_version: 3
105
121
  summary: Record your rack/rails requests and store them for future inspection