mirror of
https://github.com/rest-client/rest-client.git
synced 2022-11-09 13:49:40 -05:00
Add optional Resource-specific logging
This commit is contained in:
parent
5269c842b8
commit
72bd7b1e04
7 changed files with 70 additions and 25 deletions
11
README.md
11
README.md
|
@ -498,7 +498,7 @@ $ restclient put http://example.com/resource < input_body
|
||||||
|
|
||||||
## Logging
|
## Logging
|
||||||
|
|
||||||
To enable logging you can:
|
To enable logging globally you can:
|
||||||
|
|
||||||
- set RestClient.log with a Ruby Logger, or
|
- 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"):
|
- set an environment variable to avoid modifying the code (in this case you can use a file name, "stdout" or "stderr"):
|
||||||
|
@ -506,7 +506,14 @@ To enable logging you can:
|
||||||
```ruby
|
```ruby
|
||||||
$ RESTCLIENT_LOG=stdout path/to/my/program
|
$ 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
|
```ruby
|
||||||
RestClient.get "http://some/resource"
|
RestClient.get "http://some/resource"
|
||||||
|
|
|
@ -131,6 +131,7 @@ module RestClient
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@log = args[:log]
|
||||||
@tf = nil # If you are a raw request, this is your tempfile
|
@tf = nil # If you are a raw request, this is your tempfile
|
||||||
@max_redirects = args[:max_redirects] || 10
|
@max_redirects = args[:max_redirects] || 10
|
||||||
@processed_headers = make_headers headers
|
@processed_headers = make_headers headers
|
||||||
|
@ -525,19 +526,24 @@ module RestClient
|
||||||
redacted_uri.to_s
|
redacted_uri.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Default to the global logger if there's not a request-specific one
|
||||||
|
def log
|
||||||
|
@log || RestClient.log
|
||||||
|
end
|
||||||
|
|
||||||
def log_request
|
def log_request
|
||||||
return unless RestClient.log
|
return unless log
|
||||||
|
|
||||||
out = []
|
out = []
|
||||||
|
|
||||||
out << "RestClient.#{method} #{redacted_url.inspect}"
|
out << "RestClient.#{method} #{redacted_url.inspect}"
|
||||||
out << payload.short_inspect if payload
|
out << payload.short_inspect if payload
|
||||||
out << processed_headers.to_a.sort.map { |(k, v)| [k.inspect, v.inspect].join("=>") }.join(", ")
|
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
|
end
|
||||||
|
|
||||||
def log_response res
|
def log_response res
|
||||||
return unless RestClient.log
|
return unless log
|
||||||
|
|
||||||
size = if @raw_response
|
size = if @raw_response
|
||||||
File.size(@tf.path)
|
File.size(@tf.path)
|
||||||
|
@ -545,7 +551,7 @@ module RestClient
|
||||||
res.body.nil? ? 0 : res.body.size
|
res.body.nil? ? 0 : res.body.size
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
# Return a hash of headers whose keys are capitalized strings
|
# Return a hash of headers whose keys are capitalized strings
|
||||||
|
@ -776,13 +782,13 @@ module RestClient
|
||||||
http_response.read_body do |chunk|
|
http_response.read_body do |chunk|
|
||||||
@tf.write chunk
|
@tf.write chunk
|
||||||
size += chunk.size
|
size += chunk.size
|
||||||
if RestClient.log
|
if log
|
||||||
if size == 0
|
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
|
elsif total == 0
|
||||||
RestClient.log << "%s %s (zero content length)\n" % [@method, @url]
|
log << "%s %s (zero content length)\n" % [@method, @url]
|
||||||
else
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,7 +51,8 @@ module RestClient
|
||||||
Request.execute(options.merge(
|
Request.execute(options.merge(
|
||||||
:method => :get,
|
:method => :get,
|
||||||
:url => url,
|
:url => url,
|
||||||
:headers => headers), &(block || @block))
|
:headers => headers,
|
||||||
|
:log => log), &(block || @block))
|
||||||
end
|
end
|
||||||
|
|
||||||
def head(additional_headers={}, &block)
|
def head(additional_headers={}, &block)
|
||||||
|
@ -59,7 +60,8 @@ module RestClient
|
||||||
Request.execute(options.merge(
|
Request.execute(options.merge(
|
||||||
:method => :head,
|
:method => :head,
|
||||||
:url => url,
|
:url => url,
|
||||||
:headers => headers), &(block || @block))
|
:headers => headers,
|
||||||
|
:log => log), &(block || @block))
|
||||||
end
|
end
|
||||||
|
|
||||||
def post(payload, additional_headers={}, &block)
|
def post(payload, additional_headers={}, &block)
|
||||||
|
@ -68,7 +70,8 @@ module RestClient
|
||||||
:method => :post,
|
:method => :post,
|
||||||
:url => url,
|
:url => url,
|
||||||
:payload => payload,
|
:payload => payload,
|
||||||
:headers => headers), &(block || @block))
|
:headers => headers,
|
||||||
|
:log => log), &(block || @block))
|
||||||
end
|
end
|
||||||
|
|
||||||
def put(payload, additional_headers={}, &block)
|
def put(payload, additional_headers={}, &block)
|
||||||
|
@ -77,7 +80,8 @@ module RestClient
|
||||||
:method => :put,
|
:method => :put,
|
||||||
:url => url,
|
:url => url,
|
||||||
:payload => payload,
|
:payload => payload,
|
||||||
:headers => headers), &(block || @block))
|
:headers => headers,
|
||||||
|
:log => log), &(block || @block))
|
||||||
end
|
end
|
||||||
|
|
||||||
def patch(payload, additional_headers={}, &block)
|
def patch(payload, additional_headers={}, &block)
|
||||||
|
@ -86,7 +90,8 @@ module RestClient
|
||||||
:method => :patch,
|
:method => :patch,
|
||||||
:url => url,
|
:url => url,
|
||||||
:payload => payload,
|
:payload => payload,
|
||||||
:headers => headers), &(block || @block))
|
:headers => headers,
|
||||||
|
:log => log), &(block || @block))
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete(additional_headers={}, &block)
|
def delete(additional_headers={}, &block)
|
||||||
|
@ -94,7 +99,8 @@ module RestClient
|
||||||
Request.execute(options.merge(
|
Request.execute(options.merge(
|
||||||
:method => :delete,
|
:method => :delete,
|
||||||
:url => url,
|
:url => url,
|
||||||
:headers => headers), &(block || @block))
|
:headers => headers,
|
||||||
|
:log => log), &(block || @block))
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
|
@ -121,6 +127,10 @@ module RestClient
|
||||||
options[:open_timeout]
|
options[:open_timeout]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def log
|
||||||
|
options[:log] || RestClient.log
|
||||||
|
end
|
||||||
|
|
||||||
# Construct a subresource, preserving authentication.
|
# Construct a subresource, preserving authentication.
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
|
|
@ -38,6 +38,10 @@ module RestClient
|
||||||
"<RestClient::Response #{code.inspect} #{body_truncated(10).inspect}>"
|
"<RestClient::Response #{code.inspect} #{body_truncated(10).inspect}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def log
|
||||||
|
request.log
|
||||||
|
end
|
||||||
|
|
||||||
def self.create(body, net_http_res, request)
|
def self.create(body, net_http_res, request)
|
||||||
result = self.new(body || '')
|
result = self.new(body || '')
|
||||||
|
|
||||||
|
@ -54,8 +58,8 @@ module RestClient
|
||||||
begin
|
begin
|
||||||
encoding = Encoding.find(charset) if charset
|
encoding = Encoding.find(charset) if charset
|
||||||
rescue ArgumentError
|
rescue ArgumentError
|
||||||
if RestClient.log
|
if response.log
|
||||||
RestClient.log << "No such encoding: #{charset.inspect}"
|
response.log << "No such encoding: #{charset.inspect}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -687,6 +687,12 @@ describe RestClient::Request, :include_helpers do
|
||||||
RestClient::Request.new(:method => :get, :url => 'http://user:password@url', :headers => {:user_agent => 'rest-client'}).log_request
|
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}
|
expect(log[0]).to eq %Q{RestClient.get "http://user:REDACTED@url", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
it "strips the charset from the response content type" do
|
it "strips the charset from the response content type" do
|
||||||
|
|
|
@ -7,37 +7,37 @@ describe RestClient::Resource do
|
||||||
|
|
||||||
context "Resource delegation" do
|
context "Resource delegation" do
|
||||||
it "GET" 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
|
@resource.get
|
||||||
end
|
end
|
||||||
|
|
||||||
it "HEAD" do
|
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
|
@resource.head
|
||||||
end
|
end
|
||||||
|
|
||||||
it "POST" do
|
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'
|
@resource.post 'abc', :content_type => 'image/jpg'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "PUT" do
|
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'
|
@resource.put 'abc', :content_type => 'image/jpg'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "PATCH" do
|
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'
|
@resource.patch 'abc', :content_type => 'image/jpg'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "DELETE" do
|
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
|
@resource.delete
|
||||||
end
|
end
|
||||||
|
|
||||||
it "overrides resource headers" do
|
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'
|
@resource.get 'X-Something' => '2'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -238,4 +238,16 @@ describe RestClient::Response, :include_helpers do
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
Loading…
Reference in a new issue