log_spy 0.0.4 → 1.0.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.
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