sniffer 0.1.0 → 0.2.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: e61d38c32a8f74c8fabdd9113a45892685be34c8
4
- data.tar.gz: 5ab43be1021421ec32cde7df4d2f33692318fda9
3
+ metadata.gz: 8a791b41dd917e6bd37ad0a30f52edfb29316305
4
+ data.tar.gz: '08393e568d23b31a060406b390b85ddee72c20a5'
5
5
  SHA512:
6
- metadata.gz: 66ed0687f93be90af88b3a6b440350163f1f25284827e8359ed36dec78554c4fc8f55607f365090a358539f4a1e4e8db7ba4ac4f7b993c1a7d6c477c6c47fe55
7
- data.tar.gz: ae3bb49ab20fd5fb84f9fe7e70c05c00e16141f43ee04aec53b627ec2e9f0269a2feb3fd54cd66a2de897390ebb96bfecd392f1e9bc4ce7945a75b7058002463
6
+ metadata.gz: 70eea24423a67f79778531924b3957d87f64d73ef62198bd7ad76dc05f24ae363706e5a29f69b99a961f2e4dc86509b2e6a35fa5c6d65ca69fc7b585ab678b33
7
+ data.tar.gz: d0178703da107888ebd02bd115f64ebed1421fc72618708b649b7d711e3f0ac5da58e3ffcb07c7da30318ee2f8146b7802b4c33eab1a22a8bd2eff21a2104054
@@ -33,12 +33,18 @@ Style/BlockDelimiters:
33
33
  Exclude:
34
34
  - 'spec/**/*.rb'
35
35
 
36
+ Style/DoubleNegation:
37
+ Enabled: false
38
+
36
39
  Layout/SpaceInsideStringInterpolation:
37
40
  EnforcedStyle: no_space
38
41
 
39
42
  Lint/AmbiguousRegexpLiteral:
40
43
  Enabled: false
41
44
 
45
+ Lint/AmbiguousBlockAssociation:
46
+ Enabled: false
47
+
42
48
  Metrics/MethodLength:
43
49
  Exclude:
44
50
  - 'spec/**/*.rb'
@@ -1,14 +1,5 @@
1
1
  sudo: false
2
2
  language: ruby
3
- env:
4
- global:
5
- - CC_TEST_REPORTER_ID=bc054bdf814431bf40559f1cd62a86956fa5666296895400e1282a47ec6d1c69
6
3
  rvm:
4
+ - 2.2.2
7
5
  - 2.4.2
8
- before_install: gem install bundler -v 1.15.4
9
- before_script:
10
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
11
- - chmod +x ./cc-test-reporter
12
- - ./cc-test-reporter before-build
13
- after_script:
14
- - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
@@ -0,0 +1,12 @@
1
+ ## 0.2.0 (January 8, 2018) ##
2
+
3
+ * Added Excon adapter
4
+ * Added EventMachine adapter
5
+ * Added `rotate` option
6
+ * Added storage capacity feature
7
+ * Added ruby 2.2 support
8
+
9
+
10
+ ## 0.1.0 (November 14, 2017) ##
11
+
12
+ * Initial version
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
- # Sniffer [![Build Status](https://travis-ci.org/aderyabin/sniffer.svg?branch=master)](https://travis-ci.org/aderyabin/sniffer) [![Gem Version](https://badge.fury.io/rb/sniffer.svg)](https://rubygems.org/gems/sniffer) [![Maintainability](https://api.codeclimate.com/v1/badges/640cb17b3d748a49653f/maintainability)](https://codeclimate.com/github/aderyabin/sniffer/maintainability)
1
+ # Sniffer
2
2
 
3
+ [![Build Status](https://travis-ci.org/aderyabin/sniffer.svg?branch=master)](https://travis-ci.org/aderyabin/sniffer) [![Gem Version](https://badge.fury.io/rb/sniffer.svg)](https://rubygems.org/gems/sniffer) [![Join the chat at https://gitter.im/aderyabin/sniffer](https://badges.gitter.im/aderyabin/sniffer.svg)](https://gitter.im/aderyabin/sniffer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
3
4
 
4
5
  Sniffer aims to help:
5
6
 
@@ -15,6 +16,8 @@ Sniffer supports most common HTTP accessing libraries:
15
16
  * [Curb](https://github.com/taf2/curb/)
16
17
  * [Ethon](https://github.com/typhoeus/ethon)
17
18
  * [Typhoeus](https://github.com/typhoeus/typhoeus)
19
+ * [EM-HTTP-Request](https://github.com/igrigorik/em-http-request)
20
+ * [Excon](https://github.com/excon/excon)
18
21
 
19
22
 
20
23
  <a href="https://evilmartians.com/">
@@ -45,11 +48,11 @@ Or install it yourself as:
45
48
  Sniffer default options:
46
49
 
47
50
  ```ruby
48
- Sniffer.config do
49
- logger: Logger.new($stdout),
50
- severity: Logger::Severity::DEBUG,
51
+ Sniffer.config do |c|
52
+ c.logger = Logger.new($stdout),
53
+ c.severity = Logger::Severity::DEBUG,
51
54
  # HTTP options to log
52
- log: {
55
+ c.log = {
53
56
  request_url: true,
54
57
  request_headers: true,
55
58
  request_body: true,
@@ -59,8 +62,8 @@ Sniffer.config do
59
62
  response_body: true,
60
63
  timing: true
61
64
  },
62
- store: true, # save requests/responses to Sniffer.data
63
- enabled: false # Sniffer disabled by default
65
+ c.store = true, # save requests/responses to Sniffer.data
66
+ c.enabled = false # Sniffer disabled by default
64
67
  end
65
68
  ```
66
69
 
@@ -108,6 +111,18 @@ You can clear saved data
108
111
  Sniffer.clear!
109
112
  ```
110
113
 
114
+ You can configure capacity of storage to prevent the huge memory usage and set up log rotation.
115
+ By default log rotation is active (when capacity is set) and log works like a queue.
116
+ If rotation is disabled - requests will be logged until result log size reaches the capacity.
117
+
118
+ ```
119
+ # will fill the storage and stop logging
120
+ Sniffer.config.store = {capacity: 1000, rotate: false}
121
+
122
+ # will rotate logs to fit 1000 results (rotate is true by default)
123
+ Sniffer.config.store = {capacity: 1000}
124
+ ```
125
+
111
126
  You can reset config to default
112
127
 
113
128
  ```
@@ -139,6 +154,13 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
139
154
 
140
155
  Bug reports and pull requests are welcome on GitHub at https://github.com/aderyabin/sniffer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
141
156
 
157
+ ## Acknowledge
158
+
159
+ * [Sergey Ponomarev](https://github.com/sponomarev)
160
+ * [Salahutdinov Dmitry](https://github.com/dsalahutdinov)
161
+ * [Stanislav Chereshkevich](https://github.com/dissident)
162
+ * [Anatoliy Kurichev](https://github.com/russo-matrosso)
163
+
142
164
  ## License
143
165
 
144
166
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -5,14 +5,11 @@ require "logger"
5
5
  require_relative "sniffer/version"
6
6
  require_relative "sniffer/config"
7
7
  require_relative "sniffer/data_item"
8
+ require_relative "sniffer/data"
8
9
 
9
10
  # Sniffer allows to log http requests
10
11
  module Sniffer
11
- @data = Set.new
12
-
13
12
  class << self
14
- attr_reader :data
15
-
16
13
  def config
17
14
  @config ||= Config.new
18
15
  yield @config if block_given?
@@ -20,15 +17,16 @@ module Sniffer
20
17
  end
21
18
 
22
19
  def enable!
23
- config.enabled = true
20
+ Thread.current[:sniffer] = true
24
21
  end
25
22
 
26
23
  def disable!
27
- config.enabled = false
24
+ Thread.current[:sniffer] = false
28
25
  end
29
26
 
30
27
  def enabled?
31
- config.enabled
28
+ Thread.current[:sniffer] = config.enabled if Thread.current[:sniffer].nil?
29
+ !!Thread.current[:sniffer]
32
30
  end
33
31
 
34
32
  def configure
@@ -41,11 +39,16 @@ module Sniffer
41
39
 
42
40
  def reset!
43
41
  @config = Config.new
42
+ Thread.current[:sniffer] = config.enabled
44
43
  clear!
45
44
  end
46
45
 
46
+ def data
47
+ @data ||= Sniffer::Data.new
48
+ end
49
+
47
50
  def store(data_item)
48
- @data.add(data_item) if config.store
51
+ data.store(data_item)
49
52
  end
50
53
 
51
54
  def logger
@@ -60,3 +63,5 @@ require_relative "sniffer/adapters/http_adapter"
60
63
  require_relative "sniffer/adapters/patron_adapter"
61
64
  require_relative "sniffer/adapters/curb_adapter"
62
65
  require_relative "sniffer/adapters/ethon_adapter"
66
+ require_relative "sniffer/adapters/eventmachine_adapter"
67
+ require_relative "sniffer/adapters/excon_adapter"
@@ -14,7 +14,6 @@ module Sniffer
14
14
  end
15
15
  end
16
16
 
17
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
18
17
  def http_with_sniffer(verb)
19
18
  sniffer_request(verb)
20
19
 
@@ -47,6 +46,7 @@ module Sniffer
47
46
  @data_item ||= Sniffer::DataItem.new if Sniffer.enabled?
48
47
  end
49
48
 
49
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
50
50
  def sniffer_request(verb, *args)
51
51
  return unless data_item
52
52
 
@@ -63,6 +63,7 @@ module Sniffer
63
63
 
64
64
  Sniffer.store(data_item)
65
65
  end
66
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
66
67
 
67
68
  def sniffer_response(timing)
68
69
  return unless data_item
@@ -70,9 +70,7 @@ module Sniffer
70
70
 
71
71
  end
72
72
 
73
- if Ethon.logger.debug?
74
- Ethon.logger.debug { "ETHON: performed #{log_inspect}" }
75
- end
73
+ Ethon.logger.debug { "ETHON: performed #{log_inspect}" } if Ethon.logger.debug?
76
74
  complete
77
75
 
78
76
  @return_code
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sniffer
4
+ module Adapters
5
+ # Em-Http-Connection Adapter
6
+ module EventMachineAdapter
7
+ # Overrides #send_request, #parse_response, #on_body_data
8
+ module Client
9
+ def self.included(base)
10
+ base.class_eval do
11
+ alias_method :send_request_without_sniffer, :send_request
12
+ alias_method :send_request, :send_request_with_sniffer
13
+ alias_method :parse_response_header_without_sniffer, :parse_response_header
14
+ alias_method :parse_response_header, :parse_response_header_with_sniffer
15
+ alias_method :on_body_data_without_sniffer, :on_body_data
16
+ alias_method :on_body_data, :on_body_data_with_sniffer
17
+ end
18
+ end
19
+
20
+ # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
21
+ def send_request_with_sniffer(head, body)
22
+ if Sniffer.enabled?
23
+ @data_item = Sniffer::DataItem.new
24
+ @data_item.response = Sniffer::DataItem::Response.new
25
+ @data_item.request = Sniffer::DataItem::Request.new(host: @req.host,
26
+ method: @req.method.to_sym,
27
+ query: encode_query(@req.uri, @req.query),
28
+ headers: @req.headers,
29
+ body: @req.body.to_s,
30
+ port: @req.port)
31
+ Sniffer.store(@data_item)
32
+
33
+ @start_time = Time.now
34
+ end
35
+
36
+ send_request_without_sniffer(head, body)
37
+ end
38
+ # rubocop:enable Metrics/AbcSize,Metrics/MethodLength
39
+
40
+ def parse_response_header_with_sniffer(header, version, status)
41
+ if Sniffer.enabled?
42
+ @data_item.response.timing = Time.now - @start_time
43
+ @data_item.response.status = status
44
+ @data_item.response.headers = header
45
+ end
46
+
47
+ parse_response_header_without_sniffer(header, version, status)
48
+ end
49
+
50
+ def on_body_data_with_sniffer(data)
51
+ if Sniffer.enabled?
52
+ @data_item.response.body = data
53
+ @data_item.log
54
+ end
55
+
56
+ on_body_data_without_sniffer(data)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ EventMachine::HttpClient.send(:include, Sniffer::Adapters::EventMachineAdapter::Client) if defined?(::EventMachine)
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sniffer
4
+ module Adapters
5
+ # Excon adapter
6
+ module ExconAdapter
7
+ def self.included(base)
8
+ base.class_eval do
9
+ alias_method :request_without_sniffer, :request
10
+ alias_method :request, :request_with_sniffer
11
+ end
12
+ end
13
+
14
+ # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
15
+ def request_with_sniffer(params = {}, &block)
16
+ if Sniffer.enabled?
17
+ datum = data.merge(params)
18
+ data_item = Sniffer::DataItem.new
19
+ data_item.request = Sniffer::DataItem::Request.new(host: datum[:host],
20
+ method: datum[:method],
21
+ query: datum[:path] + ::Excon::Utils.query_string(datum),
22
+ headers: datum[:headers] || {},
23
+ body: datum[:body].to_s,
24
+ port: datum[:port])
25
+
26
+ Sniffer.store(data_item)
27
+ end
28
+
29
+ bm = Benchmark.realtime do
30
+ @response = request_without_sniffer(params, &block)
31
+ end
32
+
33
+ if Sniffer.enabled?
34
+ data_item.response = Sniffer::DataItem::Response.new(status: @response.status,
35
+ headers: @response.headers,
36
+ body: @response.body,
37
+ timing: bm)
38
+
39
+ data_item.log
40
+ end
41
+
42
+ @response
43
+ end
44
+ # rubocop:enable Metrics/AbcSize,Metrics/MethodLength
45
+ end
46
+ end
47
+ end
48
+
49
+ ::Excon::Connection.send(:include, Sniffer::Adapters::ExconAdapter) if defined?(::Excon::Connection)
@@ -21,5 +21,18 @@ module Sniffer
21
21
  },
22
22
  store: true,
23
23
  enabled: false
24
+
25
+ def capacity?
26
+ store.is_a?(Hash) && store.key?(:capacity)
27
+ end
28
+
29
+ def capacity
30
+ store.fetch(:capacity).to_i
31
+ end
32
+
33
+ def rotate?
34
+ return false unless capacity?
35
+ store.fetch(:rotate, true)
36
+ end
24
37
  end
25
38
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sniffer
4
+ # Data class stores the data and controls capacity
5
+ class Data < Array
6
+ def store(data_item)
7
+ return unless config.store
8
+
9
+ if config.rotate?
10
+ rotate(data_item)
11
+ else
12
+ push(data_item) unless overflow?
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def rotate(data_item)
19
+ shift if overflow?
20
+ push(data_item)
21
+ end
22
+
23
+ def overflow?
24
+ config.capacity? && length >= config.capacity
25
+ end
26
+
27
+ def config
28
+ Sniffer.config
29
+ end
30
+ end
31
+ end
@@ -11,8 +11,8 @@ module Sniffer
11
11
 
12
12
  def to_h
13
13
  {
14
- request: request&.to_h,
15
- response: response&.to_h
14
+ request: request && request.to_h,
15
+ response: response && response.to_h
16
16
  }
17
17
  end
18
18
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sniffer
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -35,4 +35,6 @@ Gem::Specification.new do |spec|
35
35
  spec.add_development_dependency "curb", ">= 0.9.4"
36
36
  spec.add_development_dependency "ethon", ">= 0.11.0"
37
37
  spec.add_development_dependency "typhoeus", ">= 0.9.0"
38
+ spec.add_development_dependency "em-http-request", ">= 1.1.0"
39
+ spec.add_development_dependency "excon", ">= 0.60.0"
38
40
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sniffer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Deryabin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-14 00:00:00.000000000 Z
11
+ date: 2018-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anyway_config
@@ -220,6 +220,34 @@ dependencies:
220
220
  - - ">="
221
221
  - !ruby/object:Gem::Version
222
222
  version: 0.9.0
223
+ - !ruby/object:Gem::Dependency
224
+ name: em-http-request
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: 1.1.0
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: 1.1.0
237
+ - !ruby/object:Gem::Dependency
238
+ name: excon
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: 0.60.0
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: 0.60.0
223
251
  description: Analyze HTTP Requests
224
252
  email:
225
253
  - aderyabin@evilmartians.com
@@ -232,6 +260,7 @@ files:
232
260
  - ".rubocop.yml"
233
261
  - ".ruby-version"
234
262
  - ".travis.yml"
263
+ - CHANGELOG.md
235
264
  - CODE_OF_CONDUCT.md
236
265
  - Gemfile
237
266
  - LICENSE.txt
@@ -243,11 +272,14 @@ files:
243
272
  - lib/sniffer.rb
244
273
  - lib/sniffer/adapters/curb_adapter.rb
245
274
  - lib/sniffer/adapters/ethon_adapter.rb
275
+ - lib/sniffer/adapters/eventmachine_adapter.rb
276
+ - lib/sniffer/adapters/excon_adapter.rb
246
277
  - lib/sniffer/adapters/http_adapter.rb
247
278
  - lib/sniffer/adapters/httpclient_adapter.rb
248
279
  - lib/sniffer/adapters/net_http_adapter.rb
249
280
  - lib/sniffer/adapters/patron_adapter.rb
250
281
  - lib/sniffer/config.rb
282
+ - lib/sniffer/data.rb
251
283
  - lib/sniffer/data_item.rb
252
284
  - lib/sniffer/version.rb
253
285
  - sniffer.gemspec