diff --git a/lib/sniffer.rb b/lib/sniffer.rb index 67c16c9..de7249e 100644 --- a/lib/sniffer.rb +++ b/lib/sniffer.rb @@ -11,36 +11,57 @@ module Sniffer class << self extend Forwardable - def current - stack.last - end - def_delegators :current, :config, :enable!, :disable!, :enabled?, - :clear!, :reset!, :data, :store, :logger, :configure - def capture(config = nil) - controller = Controller.new(config) - stack.push(controller) + def capture(options = {}) + # TODO: make Anyway config to support creation with hash + config = Sniffer::Config.new + { enabled: true }.merge!(options).each do |k, v| + config.send("#{k}=", v) + end + sniffer = Instance.new(config) + sniffers.push(sniffer) yield if block_given? - controller + sniffer ensure - stack.pop + sniffers.pop + end + + def enabled? + sniffers.any?(&:enabled?) + end + + def store(data_item) + sniffers.each do |sniffer| + sniffer.store(data_item) if sniffer.enabled? + end + end + + def log(data_item) + sniffers.each do |sniffer| + next if !sniffer.enabled? || sniffer.logger.nil? + sniffer.logger.log(sniffer.config.severity, data_item.to_json) + end end private - def stack - Thread.current[:stack] ||= [Controller.new] + def default + sniffers.first + end + def_delegators :default, :config, :enable!, :disable!, :clear!, :reset!, :data + + def sniffers + Thread.current[:sniffers] ||= [Instance.new] end end # Holds all the sniffer logic - class Controller - def initialize(config = nil) - @config = config || Config.new + class Instance + def initialize(config = Config.new) + @config = config end def config - @config ||= Config.new yield @config if block_given? @config end @@ -83,7 +104,7 @@ def logger end end - private_constant :Controller + private_constant :Instance end require_relative "sniffer/adapters/net_http_adapter" diff --git a/lib/sniffer/adapters/curb_adapter.rb b/lib/sniffer/adapters/curb_adapter.rb index 38ca97d..277a8b4 100644 --- a/lib/sniffer/adapters/curb_adapter.rb +++ b/lib/sniffer/adapters/curb_adapter.rb @@ -75,7 +75,7 @@ def sniffer_response(timing) body: body_str, timing: timing) - data_item.log + Sniffer.log(data_item) end end end diff --git a/lib/sniffer/adapters/ethon_adapter.rb b/lib/sniffer/adapters/ethon_adapter.rb index e082c37..6512bbc 100644 --- a/lib/sniffer/adapters/ethon_adapter.rb +++ b/lib/sniffer/adapters/ethon_adapter.rb @@ -66,8 +66,7 @@ def perform_with_sniffer headers: hash_headers, body: @response_body, timing: bm) - @data_item.log - + Sniffer.log(@data_item) end if Ethon.logger.debug? diff --git a/lib/sniffer/adapters/eventmachine_adapter.rb b/lib/sniffer/adapters/eventmachine_adapter.rb index 1d53541..1103080 100644 --- a/lib/sniffer/adapters/eventmachine_adapter.rb +++ b/lib/sniffer/adapters/eventmachine_adapter.rb @@ -50,7 +50,7 @@ def parse_response_header_with_sniffer(header, version, status) def on_body_data_with_sniffer(data) if Sniffer.enabled? @data_item.response.body = data - @data_item.log + Sniffer.log(@data_item) end on_body_data_without_sniffer(data) diff --git a/lib/sniffer/adapters/http_adapter.rb b/lib/sniffer/adapters/http_adapter.rb index 1ade264..645172b 100644 --- a/lib/sniffer/adapters/http_adapter.rb +++ b/lib/sniffer/adapters/http_adapter.rb @@ -55,7 +55,7 @@ def request_with_sniffer(verb, uri, opts = {}) body: @res.body.to_s, timing: bm) - data_item.log + Sniffer.log(data_item) end return @res unless opts.follow diff --git a/lib/sniffer/adapters/httpclient_adapter.rb b/lib/sniffer/adapters/httpclient_adapter.rb index 7efe835..7011a98 100644 --- a/lib/sniffer/adapters/httpclient_adapter.rb +++ b/lib/sniffer/adapters/httpclient_adapter.rb @@ -46,7 +46,7 @@ def do_get_block_with_sniffer(req, proxy, conn, &block) conn.push(res) - data_item.log + Sniffer.log(data_item) end raise retryable_response unless retryable_response.nil? diff --git a/lib/sniffer/adapters/net_http_adapter.rb b/lib/sniffer/adapters/net_http_adapter.rb index 8681cce..31ed5b9 100644 --- a/lib/sniffer/adapters/net_http_adapter.rb +++ b/lib/sniffer/adapters/net_http_adapter.rb @@ -38,7 +38,7 @@ def request_with_sniffer(req, body = nil, &block) body: @response.body.to_s, timing: bm) - data_item.log + Sniffer.log(data_item) end @response diff --git a/lib/sniffer/adapters/patron_adapter.rb b/lib/sniffer/adapters/patron_adapter.rb index 9127286..30294cd 100644 --- a/lib/sniffer/adapters/patron_adapter.rb +++ b/lib/sniffer/adapters/patron_adapter.rb @@ -36,7 +36,7 @@ def request_with_sniffer(action_name, url, headers, options = {}) body: @res.body.to_s, timing: bm) - data_item.log + Sniffer.log(data_item) end @res diff --git a/lib/sniffer/data_item.rb b/lib/sniffer/data_item.rb index aa775eb..ff17153 100644 --- a/lib/sniffer/data_item.rb +++ b/lib/sniffer/data_item.rb @@ -16,13 +16,8 @@ def to_h } end - def log - Sniffer.logger.log(Sniffer.config.severity, to_json) - end - def to_log - return {} unless Sniffer.config.logger - request.to_log.merge(response.to_log) + (request.nil? ? {} : request.to_log).merge(response.nil? ? {} : response.to_log) end def to_json @@ -66,7 +61,7 @@ def to_log hash[:query] = query end - if log_settings["request_headers"] + if log_settings["request_headers"] && headers headers.each do |(k, v)| hash[:"rq_#{k.to_s.tr("-", '_').downcase}"] = v end @@ -97,7 +92,7 @@ def to_log {}.tap do |hash| hash[:status] = status if log_settings["response_status"] - if log_settings["response_headers"] + if log_settings["response_headers"] && headers headers.each do |(k, v)| hash[:"rs_#{k.to_s.tr("-", '_').downcase}"] = v end diff --git a/spec/sniffer/data_item_spec.rb b/spec/sniffer/data_item_spec.rb index 1128160..15377b0 100644 --- a/spec/sniffer/data_item_spec.rb +++ b/spec/sniffer/data_item_spec.rb @@ -7,14 +7,26 @@ expect(described_class.new.to_h).to eq(request: nil, response: nil) end - context "#to_log" - it 'returns {} if logger disabled' do - Sniffer.config.logger = false - expect(subject.to_log).to eq({}) - end + context "#to_log" do + it 'returns {} if logger disabled' do + subject.request = Sniffer::DataItem::Request.new + subject.response = Sniffer::DataItem::Response.new + expect(subject.to_log).to( + eq( + port: nil, + host: nil, + query: nil, + method: nil, + request_body: nil, + status: nil, + timing: nil, + response_body: nil + ) + ) + end - it 'returns {} if logger is nil' do - Sniffer.config.logger = nil - expect(subject.to_log).to eq({}) + it 'returns {} if request and response are nil' do + expect(subject.to_log).to eq({}) + end end end diff --git a/spec/sniffer_spec.rb b/spec/sniffer_spec.rb index 1d9c5f1..5b2cf71 100644 --- a/spec/sniffer_spec.rb +++ b/spec/sniffer_spec.rb @@ -31,14 +31,14 @@ end describe ".store" do - it 'stores data items' do + it 'stores data items', enabled: true do data_item = Sniffer::DataItem.new expect { Sniffer.store(data_item) }.to change { Sniffer.data.include?(data_item) }.to(true) end - it 'stores no more than capacity if set (and rotate by default)' do + it 'stores no more than capacity if set (and rotate by default)', enabled: true do Sniffer.config.store = { capacity: 1 } first = Sniffer::DataItem.new @@ -51,7 +51,7 @@ expect(Sniffer.data.include?(second)).to be_truthy end - it 'do not stores data without rotation' do + it 'do not stores data without rotation', enabled: true do Sniffer.config.store = { capacity: 1, rotate: false } first = Sniffer::DataItem.new @@ -65,7 +65,7 @@ end context ".clear!" do - it 'clears data' do + it 'clears data', enabled: true do Sniffer.store(Sniffer::DataItem.new) expect { @@ -99,18 +99,24 @@ end.not_to change { Sniffer.enabled? } end - context 'capture' do + context 'capture', enabled: true do it do item = Sniffer::DataItem.new Sniffer.data.push(item) captured_item = Sniffer::DataItem.new + nested_captured_item = Sniffer::DataItem.new + nested = nil captured = Sniffer.capture do - Sniffer.data.push(captured_item) + Sniffer.store(captured_item) + nested = Sniffer.capture do + Sniffer.store(nested_captured_item) + end end - expect(Sniffer.data).to eq [item] - expect(captured.data).to eq [captured_item] + expect(Sniffer.data).to eq [item, captured_item, nested_captured_item] + expect(captured.data).to eq [captured_item, nested_captured_item] + expect(nested.data).to eq [nested_captured_item] end end end