log_spy 0.0.4 → 1.0.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: f2dc87b4c4a64a5e9cca30f4274c31b5410b7658
4
- data.tar.gz: dd24f18962e75a3efc5c029a9445593e3d7b693e
3
+ metadata.gz: 327b18418456c929af2ee0f996f04c6477d04ddf
4
+ data.tar.gz: 54d57335489f6098d68f06538f262e1bc62591b3
5
5
  SHA512:
6
- metadata.gz: 4fffa272cda3094c4c41763040ca61adf3b117628b4cb7be8f399046771a8869bc7e7de0ad8732c6a2f57a52a84d09e64210fec7dce8d9fa02fd163705deb83d
7
- data.tar.gz: fc708c4642da96e831e8bf4f09ea661e5b5b4d20b25d8c896144aab8031a99e0bb6ddaf4a674760b280b0bd8b84ba886312b92d7051bd787cd8375bb1a6ea2fa
6
+ metadata.gz: 8d4589ceef28e7659e8901004c532e9c3a2272305799c305c473904a20a022ada571a96c93c0d517df0027372b85ad3416455427c2fd81756e880506530bc5f9
7
+ data.tar.gz: f697729d31e5bcba32c221a3fa07a18fe212129330b1cd95f293cbfdb565ae69c2b84f055c2ee58b3b79f9b732e3450a0e4253bb296991207070d5e21c063d15
@@ -1,5 +1,18 @@
1
1
 
2
- 0.0.4 / 2014-09-23
2
+ 1.0.0 / 2016-02-09
3
+ ==================
4
+
5
+ [Changed]
6
+ * upgrade `aws-sdk` to 2.x.x and restrict its dependency version
7
+
8
+ [Added]
9
+ * add `cookies` to payload
10
+
11
+ [Fixed]
12
+ * `rewind` body before read in payload
13
+
14
+
15
+ 0.0.4 / 2014-09-23
3
16
  ==================
4
17
  * add `controller_action` to payload, if `env['action_dispatch.request.parameter']` exists
5
18
 
data/README.md CHANGED
@@ -1,8 +1,16 @@
1
1
  # LogSpy
2
2
 
3
- LogSpy is a Rack middleware sending request log to [Amazon SQS](http://aws.amazon.com/sqs/).
3
+ LogSpy is a Rack middleware sending request log to [Amazon SQS](http://aws.amazon.com/sqs/) on each request.
4
+
5
+ ## How it works
6
+
4
7
  After each request, `log_spy` opens a new thread and sends the request log payload as a `json` string onto [AWS SQS](http://aws.amazon.com/sqs/).
5
8
 
9
+ ## Why not use Papertrail or other log collector?
10
+
11
+ Logspy does not intend to replace the log collectors like Papertrail or something similar.
12
+ The purpose of Logspy is to record each request and its params so that we can easily analyse even replay requests within a certain period.
13
+
6
14
  ## Installation
7
15
 
8
16
  Add this line to your application's Gemfile:
@@ -21,17 +29,19 @@ Or install it yourself as:
21
29
 
22
30
  require and use the middleware:
23
31
 
24
- - bare rack:
32
+ - Bare Rack:
25
33
 
26
34
  ```ruby
27
35
  require 'log_spy'
28
36
  use LogSpy::Spy, 'aws-sqs-url'
29
37
  ```
30
38
 
31
- - rails:
39
+ - Rails:
32
40
  ```ruby
33
- # application.rb
34
- config.middleware.use LogSpy::Spy, 'aws-sqs-url', :reigon => 'ap-southeast-1'
41
+ # config/application.rb
42
+ config.middleware.use LogSpy::Spy, 'aws-sqs-url', :reigon => 'ap-southeast-1',
43
+ :access_key_id => 'the-key-id',
44
+ :secret_access_key => 'the-secret'
35
45
  ```
36
46
 
37
47
  ## API Documents:
@@ -40,21 +50,25 @@ config.middleware.use LogSpy::Spy, 'aws-sqs-url', :reigon => 'ap-southeast-1'
40
50
  - usage: `use LogSpy::Spy, <aws-sqs-url>[, <options>]`
41
51
  - params:
42
52
  - `aws-sqs-url`(required): the [Queue URL](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/ImportantIdentifiers.html) of SQS, which identifies the queue.
43
- - `options`(optional): if given, `log_spy` would pass it to initialize [`AWS::SQS`](http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SQS.html)
53
+ - `options`(optional): if given, `log_spy` would pass it to initialize [`Aws::SQS`](http://docs.aws.amazon.com/sdkforruby/api/Aws/SQS.html)
44
54
 
45
55
  ### the payload format sends to AWS SQS:
46
56
 
47
- ```json
57
+ ```javascript
48
58
  {
49
59
  "path": "/the/request/path",
50
60
  "status": 200,
51
61
  "execution_time": 145.3, // in ms
62
+ "controller_action": "users#show", // if env['action_dispatch.request.parameters'] exists
52
63
  "request": {
53
64
  "content_type": "application/json",
54
65
  "request_method": "post",
55
66
  "ip": "123.1.1.1",
56
67
  "query_string": "query-key=query-val&hello=world",
57
- "body": "body-key=body-val"
68
+ "body": "body-key=body-val",
69
+ "cookies": {
70
+ "cookie_key": "cookie_val"
71
+ }
58
72
  },
59
73
 
60
74
  // if got exception
@@ -18,25 +18,37 @@ class LogSpy::Payload
18
18
  :request_method => @req.request_method,
19
19
  :ip => @req.ip,
20
20
  :query_string => @req.query_string,
21
+ :cookies => @req.cookies,
21
22
  :body => request_body
22
23
  }
23
24
  }
24
25
 
26
+ append_error_if_exists(hash)
27
+ append_controller_action_if_exists(hash)
28
+
29
+ hash.to_json
30
+ end
31
+
32
+ def append_error_if_exists hash
25
33
  if @error
26
34
  hash[:error] = { :message => @error.message, :backtrace => @error.backtrace }
27
35
  end
36
+ end
37
+ private :append_error_if_exists
28
38
 
39
+ def append_controller_action_if_exists hash
29
40
  if controller_params = @req.env['action_dispatch.request.parameters']
30
41
  hash[:controller_action] = "#{controller_params['controller']}##{controller_params['action']}"
31
42
  end
32
-
33
- hash.to_json
34
43
  end
44
+ private :append_controller_action_if_exists
35
45
 
36
46
  def request_body
37
47
  return '' if @req.content_type =~ /multipart/
48
+ @req.body.rewind
38
49
  @req.body.read
39
- rescue Exception => e
50
+ rescue IOError
40
51
  @req.env['RAW_POST_BODY']
41
52
  end
53
+ private :request_body
42
54
  end
data/lib/log_spy/spy.rb CHANGED
@@ -15,8 +15,8 @@ class LogSpy::Spy
15
15
  def call env
16
16
  @env = env
17
17
  @start_time = Time.now.to_f
18
- @status, header, body = @app.call(env)
19
18
 
19
+ @status, header, body = @app.call(env)
20
20
  @sqs_thread = send_sqs_async
21
21
 
22
22
  [ @status, header, body ]
@@ -33,7 +33,7 @@ class LogSpy::Spy
33
33
  def send_sqs_async(err = nil)
34
34
  @sqs_thread = Thread.new do
35
35
  status = err ? 500 : @status
36
- sqs = AWS::SQS.new(@options)
36
+ sqs_client = Aws::SQS::Client.new(@options)
37
37
  duration = ( (Time.now.to_f - @start_time) * 1000 ).round(0)
38
38
  res = OpenStruct.new({
39
39
  :duration => duration,
@@ -41,7 +41,10 @@ class LogSpy::Spy
41
41
  })
42
42
  payload = ::LogSpy::Payload.new(req, res, @start_time.to_i, err)
43
43
 
44
- sqs.queues[@sqs_url].send_message(payload.to_json)
44
+ sqs_client.send_message({
45
+ queue_url: @sqs_url,
46
+ message_body: payload.to_json
47
+ })
45
48
  end
46
49
  end
47
50
  private :send_sqs_async
@@ -1,3 +1,3 @@
1
1
  module LogSpy
2
- VERSION = "0.0.4"
2
+ VERSION = "1.0.0"
3
3
  end
data/log_spy.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 "aws-sdk"
21
+ spec.add_dependency "aws-sdk", [">= 2.2.14", "< 3.0"]
22
22
  spec.add_dependency "rack"
23
23
  spec.add_development_dependency "bundler", "~> 1.6"
24
24
  spec.add_development_dependency "rake"
data/spec/payload_spec.rb CHANGED
@@ -11,7 +11,11 @@ describe LogSpy::Payload do
11
11
  let(:body) { double(:body) }
12
12
  let(:content_type) { 'application/json' }
13
13
 
14
- let(:request) do
14
+ before :each do
15
+ allow(body).to receive_messages(:rewind => body)
16
+ end
17
+
18
+ let(:request) do
15
19
  double(:request,
16
20
  :path => path,
17
21
  :content_type => content_type,
@@ -19,6 +23,7 @@ describe LogSpy::Payload do
19
23
  :ip => ip,
20
24
  :query_string => query_string,
21
25
  :env => {},
26
+ :cookies => { :key => 'val' },
22
27
  :body => body)
23
28
  end
24
29
 
@@ -33,8 +38,8 @@ describe LogSpy::Payload do
33
38
 
34
39
  describe '::new(request, response, begin_at[, error = nil])' do
35
40
  it 'takes a request, response and an optional error to init' do
36
- payload = LogSpy::Payload.new(request, response, begin_at)
37
- payload_with_err = LogSpy::Payload.new(request, response, begin_at, error)
41
+ LogSpy::Payload.new(request, response, begin_at)
42
+ LogSpy::Payload.new(request, response, begin_at, error)
38
43
  end
39
44
  end
40
45
 
@@ -49,7 +54,8 @@ describe LogSpy::Payload do
49
54
  :content_type => content_type,
50
55
  :request_method => request_method,
51
56
  :ip => ip,
52
- :query_string => query_string
57
+ :query_string => query_string,
58
+ :cookies => request.cookies
53
59
  }
54
60
  }
55
61
  end
@@ -63,27 +69,28 @@ describe LogSpy::Payload do
63
69
  allow(request).to receive_messages(:content_type => 'multipart/form-data')
64
70
  expected_hash[:request][:content_type] = 'multipart/form-data'
65
71
  expected_hash[:request][:body] = ''
66
- expect(payload.to_json).to eq(expected_hash.to_json)
72
+ expect(payload.to_json).to eq(expected_hash.to_json)
67
73
  end
68
74
  end
69
75
 
70
76
  shared_context "if_body_readable" do
71
77
  before(:each) do
72
- allow(body).to receive_messages(:read => 'the-raw-body')
78
+ allow(body).to receive_messages(:rewind => 0)
79
+ allow(body).to receive_messages(:read => 'the-raw-body')
73
80
  expected_hash[:request][:body] = 'the-raw-body'
74
81
  end
75
82
  end
76
83
 
77
84
  shared_context 'if_body_unreadable' do
78
85
  before(:each) do
79
- allow(body).to receive(:read).and_raise(Exception, 'closed stream')
86
+ allow(body).to receive(:rewind).and_raise(IOError, 'closed stream')
80
87
  allow(request).to receive_messages(:env => { 'RAW_POST_BODY' => 'raw-post-body' })
81
88
  expected_hash[:request][:body] = 'raw-post-body'
82
89
  end
83
90
 
84
91
  end
85
92
 
86
- shared_examples "if env['action_dispatch.request.parameters']" do
93
+ shared_examples "ensure_action_dispatch_controller_params" do
87
94
  before :each do
88
95
  controller_params = { 'controller' => 'users', 'action' => 'show' }
89
96
  env = { 'action_dispatch.request.parameters' => controller_params }
@@ -92,7 +99,6 @@ describe LogSpy::Payload do
92
99
 
93
100
  it 'returns hash with `controller_action`' do
94
101
  expected_hash[:controller_action] = "users#show"
95
- expected_hash[:request][:body] = nil
96
102
 
97
103
  expect(payload.to_json).to eq(expected_hash.to_json)
98
104
  end
@@ -102,7 +108,8 @@ describe LogSpy::Payload do
102
108
  let(:payload) { LogSpy::Payload.new request, response, begin_at }
103
109
 
104
110
  context "if env['action_dispatch.request.parameters']" do
105
- include_examples "if env['action_dispatch.request.parameters']"
111
+ include_context "if_body_readable"
112
+ include_examples "ensure_action_dispatch_controller_params"
106
113
  end
107
114
 
108
115
  context "if body can be read" do
@@ -127,7 +134,8 @@ describe LogSpy::Payload do
127
134
  end
128
135
 
129
136
  context "if env['action_dispatch.request.parameters']" do
130
- include_examples "if env['action_dispatch.request.parameters']"
137
+ include_context "if_body_readable"
138
+ include_examples "ensure_action_dispatch_controller_params"
131
139
  end
132
140
 
133
141
  context "if request body can be read" do
data/spec/spy_spec.rb CHANGED
@@ -8,14 +8,15 @@ describe LogSpy::Spy do
8
8
 
9
9
  describe '#new(app, sqs_url [, options = {}])' do
10
10
  it 'takes an app, an sqs_url, and an optional options to init' do
11
- middleware = LogSpy::Spy.new(app, sqs_url)
12
- middleware_w_options = LogSpy::Spy.new(app, sqs_url, options)
11
+ LogSpy::Spy.new(app, sqs_url)
12
+ LogSpy::Spy.new(app, sqs_url, options)
13
13
  end
14
14
  end
15
15
 
16
- describe 'call' do
17
- let(:sqs) { double(:sqs, :queues => double(:[] => queue)) }
18
- let(:queue) { double(:queue, :send_message => true) }
16
+ describe '#call' do
17
+ let(:sqs) { double(:sqs, :send_message => true) }
18
+ # let(:sqs) { double(:sqs, :queues => double(:[] => queue)) }
19
+ # let(:queue) { double(:queue, :send_message => true) }
19
20
  let(:call_result) { [200, { 'Content-Type' => 'application/json' }, [ 'body' ]] }
20
21
  let(:env) { {} }
21
22
 
@@ -28,29 +29,22 @@ describe LogSpy::Spy do
28
29
  let(:three_sec_later) { now + duration }
29
30
 
30
31
  before :each do
31
- allow(AWS::SQS).to receive_messages(:new => sqs)
32
+ allow(Aws::SQS::Client).to receive_messages(:new => sqs)
32
33
  allow(app).to receive_messages(:call => call_result)
33
34
  allow(Rack::Request).to receive_messages(:new => request)
34
35
  allow(LogSpy::Payload).to receive_messages(:new => payload)
35
36
  allow(Time).to receive(:now).and_return(now, three_sec_later)
36
37
  end
37
38
 
38
- it 'config sqs with options' do
39
- expect(AWS::SQS).to receive(:new).with(options)
39
+ it 'creates a sqs client with options' do
40
+ expect(Aws::SQS::Client).to receive(:new).with(options)
40
41
 
41
42
  middleware.call env
42
43
  middleware.sqs_thread.join
43
44
  end
44
45
 
45
- it 'sends payload json json to sqs' do
46
+ it 'creates payload with request, status, request_time' do
46
47
  expect(Rack::Request).to receive(:new).with(env)
47
-
48
- expect(queue).to receive(:send_message).with(payload.to_json)
49
- middleware.call env
50
- middleware.sqs_thread.join
51
- end
52
-
53
- it 'builds payload with request, status, request_time' do
54
48
  expect(LogSpy::Payload).to receive(:new) do |req, res, begin_at|
55
49
  expect(req).to be(request)
56
50
  expect(res.status).to eq(200)
@@ -62,6 +56,16 @@ describe LogSpy::Spy do
62
56
  middleware.sqs_thread.join
63
57
  end
64
58
 
59
+ it 'sends payload json to sqs with queue url' do
60
+ expect(sqs).to receive(:send_message).with({
61
+ queue_url: sqs_url,
62
+ message_body: payload.to_json
63
+ })
64
+ middleware.call env
65
+ middleware.sqs_thread.join
66
+ end
67
+
68
+
65
69
  it 'returns original result' do
66
70
  expect(middleware.call(env)).to eq(call_result)
67
71
  middleware.sqs_thread.join
@@ -73,7 +77,7 @@ describe LogSpy::Spy do
73
77
  before :each do
74
78
  allow(app).to receive(:call).and_raise(error)
75
79
  end
76
-
80
+
77
81
  it 'build payload with error' do
78
82
  expect(LogSpy::Payload).to receive(:new) do |req, res, begin_at, err|
79
83
  expect(req).to be(request)
@@ -85,7 +89,7 @@ describe LogSpy::Spy do
85
89
 
86
90
  begin
87
91
  middleware.call(env)
88
- rescue Exception => e
92
+ rescue Exception
89
93
  end
90
94
 
91
95
  middleware.sqs_thread.join
@@ -100,6 +104,6 @@ describe LogSpy::Spy do
100
104
  end
101
105
 
102
106
  end
103
-
107
+
104
108
  end
105
109
  end
metadata CHANGED
@@ -1,96 +1,102 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: log_spy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yang-Hsing Lin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-23 00:00:00.000000000 Z
11
+ date: 2016-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 2.2.14
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - '>='
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: '0'
29
+ version: 2.2.14
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rack
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - '>='
37
+ - - ">="
32
38
  - !ruby/object:Gem::Version
33
39
  version: '0'
34
40
  type: :runtime
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
- - - '>='
44
+ - - ">="
39
45
  - !ruby/object:Gem::Version
40
46
  version: '0'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: bundler
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
- - - ~>
51
+ - - "~>"
46
52
  - !ruby/object:Gem::Version
47
53
  version: '1.6'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
- - - ~>
58
+ - - "~>"
53
59
  - !ruby/object:Gem::Version
54
60
  version: '1.6'
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: rake
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
- - - '>='
65
+ - - ">="
60
66
  - !ruby/object:Gem::Version
61
67
  version: '0'
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
- - - '>='
72
+ - - ">="
67
73
  - !ruby/object:Gem::Version
68
74
  version: '0'
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: rspec
71
77
  requirement: !ruby/object:Gem::Requirement
72
78
  requirements:
73
- - - '>='
79
+ - - ">="
74
80
  - !ruby/object:Gem::Version
75
81
  version: '0'
76
82
  type: :development
77
83
  prerelease: false
78
84
  version_requirements: !ruby/object:Gem::Requirement
79
85
  requirements:
80
- - - '>='
86
+ - - ">="
81
87
  - !ruby/object:Gem::Version
82
88
  version: '0'
83
- description: ' LogSpy is a rack middleware sending request log to Amazon SQS '
89
+ description: " LogSpy is a rack middleware sending request log to Amazon SQS "
84
90
  email:
85
91
  - yanghsing.lin@gmail.com
86
92
  executables: []
87
93
  extensions: []
88
94
  extra_rdoc_files: []
89
95
  files:
90
- - .gitignore
91
- - .rspec
96
+ - ".gitignore"
97
+ - ".rspec"
98
+ - CHANGELOG.md
92
99
  - Gemfile
93
- - History.md
94
100
  - LICENSE.txt
95
101
  - README.md
96
102
  - Rakefile
@@ -112,17 +118,17 @@ require_paths:
112
118
  - lib
113
119
  required_ruby_version: !ruby/object:Gem::Requirement
114
120
  requirements:
115
- - - '>='
121
+ - - ">="
116
122
  - !ruby/object:Gem::Version
117
123
  version: '0'
118
124
  required_rubygems_version: !ruby/object:Gem::Requirement
119
125
  requirements:
120
- - - '>='
126
+ - - ">="
121
127
  - !ruby/object:Gem::Version
122
128
  version: '0'
123
129
  requirements: []
124
130
  rubyforge_project:
125
- rubygems_version: 2.2.2
131
+ rubygems_version: 2.5.1
126
132
  signing_key:
127
133
  specification_version: 4
128
134
  summary: send rack application log to Amazon SQS