tags:

views:

35

answers:

1

I try to log all soap calls, with subrutine called and arguments passed to the subroutine, my solution was this:

#!/usr/bin/perl -w
use SOAP::Transport::HTTP;

SOAP::Transport::HTTP::CGI   
    -> dispatch_to('SoapStatus')
    -> handle;

package SoapStatus;

use POSIX qw(strftime);

# Can I capture arguments and called sub from here ?
#&myLog(@_);

sub myLog
{
    my $now_string = POSIX::strftime "%Y-%m-%d %H:%M:%S", localtime;
    open(my $tmp_file, ">>", "/tmp/soap.log") or die "Can not open log file: $!\n";
    print $tmp_file $now_string.' '.$ENV{'REMOTE_USER'}.' '.$ENV{'REMOTE_ADDR'}.' '.(caller(1))[3].'('.(join(', ', @_)).')'."\n";
    close($tmp_file) or die "Can not close file: $!\n";
    return 0;
}

sub test
{
    myLog(@_);
    ...
    return @something;
}

My question is, there is a way of capturing arguments from inside the package block, but outside the sub, so I do not need to call myLog from every sub ?

EDIT: This is the script where the call is made ( the script is on another server )

#!/usr/bin/perl -w
use SOAP::Lite;
use Data::Dumper;
$user='myUser';
$pass='myPass';

@soap = SOAP::Lite
  -> uri('https://example.com/SoapStatus')
  -> proxy('https://'.$user.':'.$pass.'@example.com/cgi-bin/soap/soap.cgi')
  -> test('var1', 'var2')
  -> result;
print Dumper \@soap;

The log file looks like this:

2010-08-16 17:38:33 myUser 10.10.10.1 SoapStatus::test(SoapStatus, var1, var2)
2010-08-16 17:38:47 myUser 10.10.10.1 SoapStatus::test(SoapStatus, var1, var2)

using SOAP trace in the server script:

#!/usr/bin/perl -w
use SOAP::Transport::HTTP;
use POSIX qw(strftime);

SOAP::Transport::HTTP::CGI   
    -> dispatch_to('SoapStatus')
    -> handle;
use SOAP::Lite +trace => [ method, parameters => \&myLog ];

sub myLog
{
    my $now_string = POSIX::strftime "%Y-%m-%d %H:%M:%S", localtime;
    open(my $tmp_file, ">>", "/tmp/soap.log") or die "Can not open log file: $!\n";
    print $tmp_file $now_string.' '.$ENV{'REMOTE_USER'}.' '.$ENV{'REMOTE_ADDR'}.' '.(join(', ', @_)).')'."\n";
    close($tmp_file) or die "Can not close file: $!\n";
    return 0;
}

package SoapStatus;

sub test
{
    myLog(@_);
    ...
    return @something;
}

I get 2 rows in the log file:

2010-08-16 17:19:56 radu.maris 193.231.238.8 var1,var2
2010-08-16 17:19:56 radu.maris 193.231.238.8 testResponse,response1,response2

response1 and response 2 are part of @something returned by the test sub.

How can I make it print something like the pervious log example, I mean force it to print method and parameters on the same line, and how to get rid of "Response" word that is sticked to the name of the sub called ?, I cant find anithing in the documentation ( still searching ... )

+3  A: 

Your code is confusing. When is the SOAP call supposed to be made? When is the call supposed to be logged?

You can create a wrapper around your SOAP calls:

sub log_and_dispatch {
    log_soap( @_ );
    dispatch_soap( @_ );
}

However, on closer examination, it looks like Soap::Trace might be what you are looking for.

Alternatively, you could use Hook::LexWrap or Sub::Override to write wrappers for all routines you want to log. I suspect Hook::LexWrap would be more suitable for what you are trying to do.

Sinan Ünür
I would like to log the call outside of the subroutine that gets called via SOAP, as a fail safe macanism, beacause I have a lot of subs and don't wanna foget to add a call to myLog(@_) on each one of them ( and there are others that are making or modifing the subroutines and I'm sure they will forget ), I will take a look at SOAP::TRACE asap.
Radu