Adding http request/response logging to SOAP::Lite

Sometimes I just want to save the xml versions of the SOAP requests and responses (generally to share with someone else).

The SOAP::Lite perldoc page points to using SOAP::Trace. It has lots of good stuff but its a bit heavy. And in my case, I'm trying to figure out how to log response and requests over http so the following will hopefully help simplify my next search. :)

here is my approach, first the code (all good things start in code :) :
package SOAP::HTTP::Logging;

use warnings;
use strict;

use Exporter;

our @EXPORT = qw(
enable_logging
disable_logging
soap_log_file
log_message
);

our $logfile;
our $logboth = 0;
our $log_request = 0;
our $log_response = 0;

# setup global options
sub enable_logging { $log_request = $log_response = 1; }
sub disable_logging { $log_request = $log_response = 0; }
sub soap_log_file { $logfile = shift if @_; return $logfile; }

# logging sub
sub log_message {
my $in = shift; # SOAP::Lite pushes in the object its called on

# only log configured and enabled
return unless $logfile; # no logfile
return unless ref $in; # only handle objects
return unless $in->can('content'); # object must have content method

# only log if enabled
return unless $log_request or $log_response;

# make logfile more userfriendly
my $pre = "";

# decode prefix
$pre = ( ref $in eq 'HTTP::Request' ? 'Request' :
ref $in eq 'HTTP::Response' ? 'Response' :
'Unknown' );

# open logfile and write out information
open my $fh, '>>', $logfile
or return; ## sliently fail for now

printf $fh "%s [%d] %s: %s\n", scalar localtime, $$,
$pre, ( $in->content ? $in->content : 'N/A' );

close $fh;

## done
return;
}

1;
Well jezz, after copying that all over maybe that would be a good cpan module.

To use it, in the calling code add:
#!/usr/bin/perl

use strict;
use warnings;

use SOAP::HTTP::Logging;
use SOAP::Lite +trace => [
transport => &SOAP::HTTP::Logging::log_message
];

## ... somewhere before doing soap calls ...

# enable library logging
enable_logging();

# where to write log
soap_log_file( 'soap_transport.log' ); # might want a fullpath

# do your soap stuff
my $soap = SOAP::Lite->proxy( 'http://localhost' )->uri( '/Foo/Bar');
my $res = $soap->hi();

# disable logging some reason
disable_logging();

# different request
$res = $soap->login( $username, $password );

# log somewhere else
enable_logging();
soap_log_file( 'new_service_calls.log' );

$res = $soap->account_profile_2(); # a new version of calls

exit;
That's it. I can see several places to improve this code. (like better warnings on failure to open the file, better output formatting (or custom output formatting), xml tidy output, etc...

Comments

Popular posts from this blog

2 ways to get SQLite to put dates into columns

BootstrapX clickover

Bootstrap (by Twitter) loading in page content for Popovers