Search code examples
perlloggingsoapsoap-clientsoaplite

SOAP::Lite log transport request/response with custom identifier


I would like to log SOAP::Lite transport request/response contents using a custom identifier (e.g. a transaction-id or txn_id in my example below):

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

use SOAP::Lite +trace => [ transport => \&log_transport, ];

sub log_transport {
    my ($in) = @_;
    if (ref($in) eq "HTTP::Request") {
        # INSERT INTO logs ( txn_id, request ) VALUES ( $tnx_id, $in->content )
        say STDERR Dumper(ref($in), $in->content);
    }
    elsif (ref($in) eq "HTTP::Response") {
        # UPDATE logs SET response = '$in->content' WHERE txn_id = $tnx_id
        say STDERR Dumper(ref($in), $in->content);  
    }
}

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
my $soap = SOAP::Lite->proxy('https://www.dataaccess.com/webservicesserver/NumberConversion.wso?op=NumberToWords');
$soap->serializer()->register_ns('http://www.dataaccess.com/webservicesserver/' ,"ns");

sub getWords
{
    my ($number, $txn_id) = @_ ;

    my $method = SOAP::Data->name("ns:NumberToWords");
    my @params = ( SOAP::Data->name("ubiNum" => $number) );
    my $response = $soap->call($method => @params);

    if (!$response->fault) {
        say STDOUT "NumberToWords = " . $response->result;
    }
    else {
        say STDERR "error: " . (defined $response->faultstring? $response->faultstring : $soap->transport->status);
    }
}

getWords(444, '123abc');

In my example above, how can I pass the transaction-id 123abc to my logger?

P.S. I do not wish to use:

$soap->outputxml(1)->call($method => @params)

Solution

  • It does not seem like the SOAP::Trace transport callback supports extra argument passing. As a workaround you could use a lexical variable declared in the outer scope like this:

    use strict;
    use warnings;
    use Data::Dumper;
    
    my $TXN_ID;
    use SOAP::Lite +trace => [ transport => \&log_transport, ];
    
    sub log_transport {
        my ($in) = @_;
        say STDERR "Logging transaction id: $TXN_ID:";
        if (ref($in) eq "HTTP::Request") {
            # INSERT INTO logs ( txn_id, request ) VALUES ( $tnx_id, $in->content )
            say STDERR Dumper(ref($in), $in->content);
        }
        elsif (ref($in) eq "HTTP::Response") {
            # UPDATE logs SET response = '$in->content' WHERE txn_id = $tnx_id
            say STDERR Dumper(ref($in), $in->content);  
        }
    }
    
    $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
    my $soap = SOAP::Lite->proxy('https://www.dataaccess.com/webservicesserver/NumberConversion.wso?op=NumberToWords');
    $soap->serializer()->register_ns('http://www.dataaccess.com/webservicesserver/' ,"ns");
    
    sub getWords
    {
        my ($number, $txn_id) = @_ ;
    
        $TXN_ID = $txn_id;
        my $method = SOAP::Data->name("ns:NumberToWords");
        my @params = ( SOAP::Data->name("ubiNum" => $number) );
        my $response = $soap->call($method => @params);
    
        if (!$response->fault) {
            say STDOUT "NumberToWords = " . $response->result;
        }
        else {
            say STDERR "error: " . (defined $response->faultstring? $response->faultstring : $soap->transport->status);
        }
    }
    
    getWords(444, '123abc');