Skip to content

Commit

Permalink
add an option to pretty print xml for the log
Browse files Browse the repository at this point in the history
closes #280 and #256
  • Loading branch information
rubiii committed Jun 6, 2012
1 parent ed0260f commit f2d09bc
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 61 deletions.
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
## UPCOMING

* Feature: [pull request 289](https://github.com/rubiii/savon/pull/289) - Allow the SOAP envelope header
to be set as a String.
* Feature: [#289](https://github.com/rubiii/savon/pull/289) - Allow the SOAP envelope header to be set as a String.

* Feature: Added an option to pretty print XML in log messages. Closes [#256](https://github.com/rubiii/savon/issues/256)
and [#280](https://github.com/rubiii/savon/issues/280).

``` ruby
Savon.config.pretty_print_xml = true # global
client.config.pretty_print_xml = true # per client instance
```

* Refactoring:
* Added `Savon.client` as a shortcut for creating a new `Savon::Client`
Expand Down
2 changes: 1 addition & 1 deletion lib/savon/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "savon/soap"

module Savon
Config = Struct.new(:logger, :raise_errors, :soap_version, :env_namespace, :soap_header) do
Config = Struct.new(:logger, :pretty_print_xml, :raise_errors, :soap_version, :env_namespace, :soap_header) do

def self.default
config = new
Expand Down
47 changes: 47 additions & 0 deletions lib/savon/log_message.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module Savon
class LogMessage

def initialize(message, filter, options = {})
self.message = message
self.filter = filter
self.with_pretty = options[:pretty]
self.with_filter = options[:filter]
end

attr_accessor :message, :filter, :with_pretty, :with_filter

def filter?
with_filter && filter.any?
end

def pretty?
with_pretty
end

def to_s
return message unless pretty? || filter?

doc = Nokogiri::XML(message)
doc = apply_filter(doc) if filter?
doc.to_xml(pretty_options)
end

private

def apply_filter(doc)
return doc unless doc.errors.empty?

filter.each do |fi|
doc.xpath("//*[local-name()='#{fi}']").each { |node| node.content = "***FILTERED***" }
end

doc
end

def pretty_options
return {} unless pretty?
{ :indent => 2 }
end

end
end
26 changes: 5 additions & 21 deletions lib/savon/logger.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require "logger"
require "nokogiri"
require "savon/log_message"

module Savon
class Logger
Expand All @@ -10,16 +11,12 @@ def initialize(device = $stdout)

attr_accessor :device

def log(message)
subject.send(level, message)
def log(message, options = {})
log_raw LogMessage.new(message, filter, options).to_s
end

def log_filtered(message)
if filter.empty?
log(message)
else
log filter_xml(message)
end
def log_raw(message)
subject.send(level, message)
end

attr_writer :subject, :level, :filter
Expand All @@ -36,18 +33,5 @@ def filter
@filter ||= []
end

private

def filter_xml(xml)
doc = Nokogiri::XML(xml)
return xml unless doc.errors.empty?

filter.each do |fi|
doc.xpath("//*[local-name()='#{fi}']").each { |node| node.content = "***FILTERED***" }
end

doc.root.to_s
end

end
end
4 changes: 2 additions & 2 deletions lib/savon/soap/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ def with_logging
def log_request(url, headers, body)
config.logger.log "SOAP request: #{url}"
config.logger.log headers.map { |key, value| "#{key}: #{value}" }.join(", ")
config.logger.log_filtered body
config.logger.log body, :pretty => config.pretty_print_xml, :filter => true
end

# Logs the SOAP response +code+ and +body+.
def log_response(code, body)
config.logger.log "SOAP response (status #{code}):"
config.logger.log body
config.logger.log body, :pretty => config.pretty_print_xml
end

end
Expand Down
48 changes: 23 additions & 25 deletions spec/savon/logger_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,31 @@

describe Savon::Logger do

let(:logger) { subject }
let(:logger) { subject }
let(:message) { "<?xml version='1.0'?><hello>world</hello>" }
let(:pretty_message) { Nokogiri::XML(message) }
let(:filtered_message) { Nokogiri::XML("<?xml version='1.0'?><hello>***FILTERED***</hello>") }

it "logs a given message" do
logger.subject.expects(logger.level).with(Fixture.response(:authentication))
logger.log Fixture.response(:authentication)
end

describe "#log_filtered" do
it "does not filter messages when no log filter was set" do
logger.subject.expects(logger.level).with(Fixture.response(:authentication))
logger.log_filtered Fixture.response(:authentication)
end

it "filters element values" do
logger.filter = ["logType", "logTime"]
filtered_values = /Notes Log|2010-09-21T18:22:01|2010-09-21T18:22:07/

logger.subject.expects(logger.level).with do |msg|
msg !~ filtered_values &&
msg.include?('<ns10:logTime>***FILTERED***</ns10:logTime>') &&
msg.include?('<ns10:logType>***FILTERED***</ns10:logType>') &&
msg.include?('<ns11:logTime>***FILTERED***</ns11:logTime>') &&
msg.include?('<ns11:logType>***FILTERED***</ns11:logType>')
end

logger.log_filtered Fixture.response(:list)
end
logger.subject.expects(logger.level).with(message)
logger.log(message)
end

it "logs a given message (pretty)" do
logger.subject.expects(logger.level).with(pretty_message.to_xml(:indent => 2))
logger.log(message, :pretty => true)
end

it "logs a given message (filtered)" do
logger.subject.expects(logger.level).with(filtered_message.to_s)
logger.filter << :hello
warn logger.log(message, :filter => true)
end

it "logs a given message (pretty and filtered)" do
logger.subject.expects(logger.level).with(filtered_message.to_xml(:indent => 2))
logger.filter << :hello
warn logger.log(message, :pretty => true, :filter => true)
end

it "defaults to wrap the standard Logger" do
Expand Down
10 changes: 0 additions & 10 deletions spec/savon/soap/request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,6 @@
HTTPI.expects(:post).returns(HTTPI::Response.new 200, {}, Fixture.response(:authentication))
soap_request.response.should be_a(Savon::SOAP::Response)
end

it "logs the filtered SOAP request body" do
HTTPI.stubs(:post).returns(HTTPI::Response.new 200, {}, "")

config.logger.stubs(:log).times(2)
config.logger.expects(:log_filtered).with(soap.to_xml)
config.logger.stubs(:log).times(2)

soap_request.response
end
end

end

0 comments on commit f2d09bc

Please sign in to comment.