Exception NOT_LOGGED_ON
Which is not very helpful. I have no solution for this at this time, but in this case continued to write the script to attempt to get what I needed, hoping the function module would work for me, and it did.### Log on to the XMB Interface
my $rca = $rfc->function_lookup("SXMI_LOGON");
my $xln = $rca->create_function_call;
$xln->EXTCOMPANY('TWDC'); # this is a name of your choosing
$xln->EXTPRODUCT('RFCTEST'); # this is a name of your choosing
$xln->INTERFACE('XMB'); # this is one of the valid interfaces
$xln->parameter('VERSION')->value('0.1'); # this version must coincide with the interface
$xln->invoke;
print "Session ID: ".$xln->SESSIONID."
"; # this line is informational only
Your script has to pass the EXTCOMPANY parameter, which is a name of your choosing. Additionally, EXTPRODUCT is also something that you define. These parameters are designed to denote a third-party company's product information. The INTERFACE is one of the valid SAP interfaces, which must coincide with the correct VERSION. (You may notice that VERSION must be passed differently than the others, as it is a reserved word in perl - thanks to Piers for alerting me to that) You can then only execute function modules from the interface you have logged on to. Valid INTERFACE/VERSION combinations in my ECC 6.0 system, as of this writing, are: *" EXPORTING
*" VALUE(SESSIONID) LIKE TXMILOGRAW-SESSIONID
So you can see that we've retrieved and printed the exported value for SESSIONID in the following manner:print "Session ID: ".$xln->SESSIONID."
"
This line is not required, but including it lets us know that we've logged on to the interface successfully, by virtue of the fact that we've been assigned a session id. Of course, if the logon is not successful, you should see an error, so it's really your choice whether to leave this line in your script.for my $x (0 .. $#server) { # we're looping through each of the server names here
my $rcc = $rfc->function_lookup("SXMI_XMB_SYSLOG_READ");
my $slr = $rcc->create_function_call;
$slr->SERVER_NAME($server[$x]); # passing in the current server name from the loop
$slr->EXTERNAL_USER_NAME('GOOFY'); # this does not have to be a user in the SAP system
$slr->invoke;
# SYSLOG_TBL is the structure we're reading from
foreach my $row (@{$slr->SYSLOG_TBL}) { # it contains a hash with only one key/value pair, the key
print trim($row->{'LINE'})."
"; # for which is called simply LINE, and the value is 255 characters long
} # even if it is less than 255 chars, it will be padded with spaces on the
} # end, which is why I'm using this trim function to remove trailing spaces
Notice that I have provided a value for EXTERNAL_USER_NAME. This is not a valid name in the SAP system, it's simply a name that a third party product would pass to identify who is using that product, so you can make something up here. Also, using the default values for the SXMI_XMB_SYSLOG_READ function module, it will only read the last ten minutes of each server's system log. So this script would be designed to be run every ten minutes from a scheduler (like cron, for instance), or the default from and to values would have to be overridden to expand the length of time.#!/usr/bin/perl -w
use strict;
use sapnwrfc;
my $srvcnt = 0;
my @server = ();
SAPNW::Rfc->load_config;
my $rfc = SAPNW::Rfc->rfc_connect;
### Enumerate the list of available servers
my $rcb = $rfc->function_lookup("TH_SERVER_LIST");
my $tsl = $rcb->create_function_call;
$tsl->invoke;
foreach my $row (@{$tsl->LIST}) {
$server[$srvcnt]=trim($row->{'NAME'});
$srvcnt ++;
}
### Log on to the XMB Interface
my $rca = $rfc->function_lookup("SXMI_LOGON");
my $xln = $rca->create_function_call;
$xln->EXTCOMPANY('TWDC');
$xln->EXTPRODUCT('RFCTEST');
$xln->INTERFACE('XMB');
$xln->parameter('VERSION')->value('0.1');
$xln->invoke;
print "Session ID: ".$xln->SESSIONID."
";
### For each app server, read its system log
for my $x (0 .. $#server) {
my $rcc = $rfc->function_lookup("SXMI_XMB_SYSLOG_READ");
my $slr = $rcc->create_function_call;
$slr->SERVER_NAME($server[$x]);
$slr->EXTERNAL_USER_NAME('GOOFY');
$slr->invoke;
foreach my $row (@{$slr->SYSLOG_TBL}) {
print trim($row->{'LINE'})."
";
}
}
### Log off of the XMB Interface
my $rcd = $rfc->function_lookup("SXMI_LOGOFF");
my $xlf = $rcd->create_function_call;
$xlf->INTERFACE('XMB');
$xlf->invoke;
$rfc->disconnect();
### trim function, to remove leading and/or trailing spaces
sub trim {
my @OUT = @_;
for (@OUT) {
s/^s+//;
s/s+$//;
}
return wantarray ? @OUT : $OUT[0];
}
And, when executed, it will print out the system log for each application server in the system, similar to this:System Log: Local Analysis of apsrv002 for apsrv019_RQA_00 1
---------------------------------------------------
|From date/time............. 06/19/2009 / 13:56:23|
|To date/time............... 06/19/2009 / 14:06:23|
| |
|User....................... |
|Transaction code........... |
|Terminal................... * |
|Task / Number.............. |
|Problem class.............. |
|Instance.................... |
|Further restrictions....... |
|Sorted ? ................ SOFI |
|Pages with single entries 00000080 |
|With statistics............ |
| |
---------------------------------------------------
System Log: Local Analysis of apsrv002 for apsrv019_RQA_00 2
Date : 06/19/2009
----------------------------------------------------------------------------------------------------------------------------------
|Time |SAP instance |User |Program |Priority|Grp|N|Text |
----------------------------------------------------------------------------------------------------------------------------------
|13:57:01|apsrv019_RQA_00|USERJ001|RM06XB00| |R2 |C|Terminal 00220 in status DISC |
|13:57:01|apsrv019_RQA_00|USERJ001|RM06XB00| |R4 |7|Delete session 001 after error 004 |
|13:57:01|apsrv019_RQA_00| | | |Q0 |G|Request (type DIA) cannot be processed |
|14:05:59|apsrv019_RQA_00| | | |Q0 |4|Connection to user 26452 (USERA033 ), terminal 251 (desktop1-001) lost|
----------------------------------------------------------------------------------------------------------------------------------
Reading:
Number of records read......... 0000002895
Number of records selected..... 0000000004
Old records skipped............ 0000002891
Further selection:
Number of records read......... 0000000004
Number of records selected..... 0000000004
Number of records printed...... 0000000004
End of system log
System Log: Local Analysis of apsrv002 for apsrv019_RQA_00 3
C o n t e n t s
-----------------------------------------------------------------
|Content |Page| Start | End |
-----------------------------------------------------------------
|Selection criteria| 1 | | |
| | 2 |06/19/2009 13:57:01|06/19/2009 14:05:59|
|Contents | 3 | | |
-----------------------------------------------------------------
End of program
In the Perl and SAP Adventures, Part 4, we'll take it just a bit further and make this script actually useful by giving it the ability to search the system log for relevant text, and send an alert if found.