mirror of
https://github.com/rest-client/rest-client.git
synced 2022-11-09 13:49:40 -05:00
Merge pull request #538 from kaiuhl/per-resource-logging
Optional Resource and Request logging
This commit is contained in:
commit
18332b4461
7 changed files with 70 additions and 25 deletions
11
README.md
11
README.md
|
@ -528,7 +528,7 @@ $ restclient put http://example.com/resource < input_body
|
|||
|
||||
## Logging
|
||||
|
||||
To enable logging you can:
|
||||
To enable logging globally you can:
|
||||
|
||||
- set RestClient.log with a Ruby Logger, or
|
||||
- set an environment variable to avoid modifying the code (in this case you can use a file name, "stdout" or "stderr"):
|
||||
|
@ -536,7 +536,14 @@ To enable logging you can:
|
|||
```ruby
|
||||
$ RESTCLIENT_LOG=stdout path/to/my/program
|
||||
```
|
||||
Either produces logs like this:
|
||||
|
||||
You can also set individual loggers when instantiating a Resource:
|
||||
|
||||
```ruby
|
||||
resource = RestClient::Resource.new 'http://example.com/resource', log: Logger.new(STDOUT)
|
||||
```
|
||||
|
||||
All options produce logs like this:
|
||||
|
||||
```ruby
|
||||
RestClient.get "http://some/resource"
|
||||
|
|
|
@ -137,6 +137,7 @@ module RestClient
|
|||
end
|
||||
end
|
||||
|
||||
@log = args[:log]
|
||||
@tf = nil # If you are a raw request, this is your tempfile
|
||||
@max_redirects = args[:max_redirects] || 10
|
||||
@processed_headers = make_headers headers
|
||||
|
@ -531,19 +532,24 @@ module RestClient
|
|||
redacted_uri.to_s
|
||||
end
|
||||
|
||||
# Default to the global logger if there's not a request-specific one
|
||||
def log
|
||||
@log || RestClient.log
|
||||
end
|
||||
|
||||
def log_request
|
||||
return unless RestClient.log
|
||||
return unless log
|
||||
|
||||
out = []
|
||||
|
||||
out << "RestClient.#{method} #{redacted_url.inspect}"
|
||||
out << payload.short_inspect if payload
|
||||
out << processed_headers.to_a.sort.map { |(k, v)| [k.inspect, v.inspect].join("=>") }.join(", ")
|
||||
RestClient.log << out.join(', ') + "\n"
|
||||
log << out.join(', ') + "\n"
|
||||
end
|
||||
|
||||
def log_response res
|
||||
return unless RestClient.log
|
||||
return unless log
|
||||
|
||||
size = if @raw_response
|
||||
File.size(@tf.path)
|
||||
|
@ -551,7 +557,7 @@ module RestClient
|
|||
res.body.nil? ? 0 : res.body.size
|
||||
end
|
||||
|
||||
RestClient.log << "# => #{res.code} #{res.class.to_s.gsub(/^Net::HTTP/, '')} | #{(res['Content-type'] || '').gsub(/;.*$/, '')} #{size} bytes\n"
|
||||
log << "# => #{res.code} #{res.class.to_s.gsub(/^Net::HTTP/, '')} | #{(res['Content-type'] || '').gsub(/;.*$/, '')} #{size} bytes\n"
|
||||
end
|
||||
|
||||
# Return a hash of headers whose keys are capitalized strings
|
||||
|
@ -782,13 +788,13 @@ module RestClient
|
|||
http_response.read_body do |chunk|
|
||||
@tf.write chunk
|
||||
size += chunk.size
|
||||
if RestClient.log
|
||||
if log
|
||||
if size == 0
|
||||
RestClient.log << "%s %s done (0 length file)\n" % [@method, @url]
|
||||
log << "%s %s done (0 length file)\n" % [@method, @url]
|
||||
elsif total == 0
|
||||
RestClient.log << "%s %s (zero content length)\n" % [@method, @url]
|
||||
log << "%s %s (zero content length)\n" % [@method, @url]
|
||||
else
|
||||
RestClient.log << "%s %s %d%% done (%d of %d)\n" % [@method, @url, (size * 100) / total, size, total]
|
||||
log << "%s %s %d%% done (%d of %d)\n" % [@method, @url, (size * 100) / total, size, total]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,7 +51,8 @@ module RestClient
|
|||
Request.execute(options.merge(
|
||||
:method => :get,
|
||||
:url => url,
|
||||
:headers => headers), &(block || @block))
|
||||
:headers => headers,
|
||||
:log => log), &(block || @block))
|
||||
end
|
||||
|
||||
def head(additional_headers={}, &block)
|
||||
|
@ -59,7 +60,8 @@ module RestClient
|
|||
Request.execute(options.merge(
|
||||
:method => :head,
|
||||
:url => url,
|
||||
:headers => headers), &(block || @block))
|
||||
:headers => headers,
|
||||
:log => log), &(block || @block))
|
||||
end
|
||||
|
||||
def post(payload, additional_headers={}, &block)
|
||||
|
@ -68,7 +70,8 @@ module RestClient
|
|||
:method => :post,
|
||||
:url => url,
|
||||
:payload => payload,
|
||||
:headers => headers), &(block || @block))
|
||||
:headers => headers,
|
||||
:log => log), &(block || @block))
|
||||
end
|
||||
|
||||
def put(payload, additional_headers={}, &block)
|
||||
|
@ -77,7 +80,8 @@ module RestClient
|
|||
:method => :put,
|
||||
:url => url,
|
||||
:payload => payload,
|
||||
:headers => headers), &(block || @block))
|
||||
:headers => headers,
|
||||
:log => log), &(block || @block))
|
||||
end
|
||||
|
||||
def patch(payload, additional_headers={}, &block)
|
||||
|
@ -86,7 +90,8 @@ module RestClient
|
|||
:method => :patch,
|
||||
:url => url,
|
||||
:payload => payload,
|
||||
:headers => headers), &(block || @block))
|
||||
:headers => headers,
|
||||
:log => log), &(block || @block))
|
||||
end
|
||||
|
||||
def delete(additional_headers={}, &block)
|
||||
|
@ -94,7 +99,8 @@ module RestClient
|
|||
Request.execute(options.merge(
|
||||
:method => :delete,
|
||||
:url => url,
|
||||
:headers => headers), &(block || @block))
|
||||
:headers => headers,
|
||||
:log => log), &(block || @block))
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -121,6 +127,10 @@ module RestClient
|
|||
options[:open_timeout]
|
||||
end
|
||||
|
||||
def log
|
||||
options[:log] || RestClient.log
|
||||
end
|
||||
|
||||
# Construct a subresource, preserving authentication.
|
||||
#
|
||||
# Example:
|
||||
|
|
|
@ -38,6 +38,10 @@ module RestClient
|
|||
"<RestClient::Response #{code.inspect} #{body_truncated(10).inspect}>"
|
||||
end
|
||||
|
||||
def log
|
||||
request.log
|
||||
end
|
||||
|
||||
def self.create(body, net_http_res, request)
|
||||
result = self.new(body || '')
|
||||
|
||||
|
@ -54,8 +58,8 @@ module RestClient
|
|||
begin
|
||||
encoding = Encoding.find(charset) if charset
|
||||
rescue ArgumentError
|
||||
if RestClient.log
|
||||
RestClient.log << "No such encoding: #{charset.inspect}"
|
||||
if response.log
|
||||
response.log << "No such encoding: #{charset.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -694,6 +694,12 @@ describe RestClient::Request, :include_helpers do
|
|||
RestClient::Request.new(:method => :get, :url => 'http://user:password@url', :headers => {:user_agent => 'rest-client'}).log_request
|
||||
expect(log[0]).to eq %Q{RestClient.get "http://user:REDACTED@url", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
|
||||
end
|
||||
|
||||
it 'logs to a passed logger, if provided' do
|
||||
logger = double('logger', '<<' => true)
|
||||
expect(logger).to receive(:<<)
|
||||
RestClient::Request.new(:method => :get, :url => 'http://user:password@url', log: logger).log_request
|
||||
end
|
||||
end
|
||||
|
||||
it "strips the charset from the response content type" do
|
||||
|
|
|
@ -7,37 +7,37 @@ describe RestClient::Resource do
|
|||
|
||||
context "Resource delegation" do
|
||||
it "GET" do
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :get, :url => 'http://some/resource', :headers => {'X-Something' => '1'}, :user => 'jane', :password => 'mypass')
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :get, :url => 'http://some/resource', :headers => {'X-Something' => '1'}, :user => 'jane', :password => 'mypass', :log => nil)
|
||||
@resource.get
|
||||
end
|
||||
|
||||
it "HEAD" do
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :head, :url => 'http://some/resource', :headers => {'X-Something' => '1'}, :user => 'jane', :password => 'mypass')
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :head, :url => 'http://some/resource', :headers => {'X-Something' => '1'}, :user => 'jane', :password => 'mypass', :log => nil)
|
||||
@resource.head
|
||||
end
|
||||
|
||||
it "POST" do
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :post, :url => 'http://some/resource', :payload => 'abc', :headers => {:content_type => 'image/jpg', 'X-Something' => '1'}, :user => 'jane', :password => 'mypass')
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :post, :url => 'http://some/resource', :payload => 'abc', :headers => {:content_type => 'image/jpg', 'X-Something' => '1'}, :user => 'jane', :password => 'mypass', :log => nil)
|
||||
@resource.post 'abc', :content_type => 'image/jpg'
|
||||
end
|
||||
|
||||
it "PUT" do
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :put, :url => 'http://some/resource', :payload => 'abc', :headers => {:content_type => 'image/jpg', 'X-Something' => '1'}, :user => 'jane', :password => 'mypass')
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :put, :url => 'http://some/resource', :payload => 'abc', :headers => {:content_type => 'image/jpg', 'X-Something' => '1'}, :user => 'jane', :password => 'mypass', :log => nil)
|
||||
@resource.put 'abc', :content_type => 'image/jpg'
|
||||
end
|
||||
|
||||
it "PATCH" do
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :patch, :url => 'http://some/resource', :payload => 'abc', :headers => {:content_type => 'image/jpg', 'X-Something' => '1'}, :user => 'jane', :password => 'mypass')
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :patch, :url => 'http://some/resource', :payload => 'abc', :headers => {:content_type => 'image/jpg', 'X-Something' => '1'}, :user => 'jane', :password => 'mypass', :log => nil)
|
||||
@resource.patch 'abc', :content_type => 'image/jpg'
|
||||
end
|
||||
|
||||
it "DELETE" do
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :delete, :url => 'http://some/resource', :headers => {'X-Something' => '1'}, :user => 'jane', :password => 'mypass')
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :delete, :url => 'http://some/resource', :headers => {'X-Something' => '1'}, :user => 'jane', :password => 'mypass', :log => nil)
|
||||
@resource.delete
|
||||
end
|
||||
|
||||
it "overrides resource headers" do
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :get, :url => 'http://some/resource', :headers => {'X-Something' => '2'}, :user => 'jane', :password => 'mypass')
|
||||
expect(RestClient::Request).to receive(:execute).with(:method => :get, :url => 'http://some/resource', :headers => {'X-Something' => '2'}, :user => 'jane', :password => 'mypass', :log => nil)
|
||||
@resource.get 'X-Something' => '2'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -238,4 +238,16 @@ describe RestClient::Response, :include_helpers do
|
|||
end
|
||||
end
|
||||
|
||||
describe "logging" do
|
||||
it "uses the request's logger" do
|
||||
stub_request(:get, 'http://some/resource').to_return(body: 'potato', status: 200)
|
||||
|
||||
logger = double('logger', '<<' => true)
|
||||
request = RestClient::Request.new(url: 'http://some/resource', method: :get, log: logger)
|
||||
|
||||
expect(logger).to receive(:<<)
|
||||
|
||||
request.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue