sniffer 0.1.0 → 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.
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