Add Syslog "S" option

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@150 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
lissav 2007-12-11 14:18:45 +00:00
parent 4e02a82513
commit 7f1ccdbd77

View File

@ -4,18 +4,13 @@
package xCAT::MsgUtils;
use strict;
use Sys::Syslog;
use locale;
use Socket;
use File::Path;
my $msgs;
my $distro;
$::XCATLOG = "/var/log/xcat";
$::NOK = -1;
$::OK = 0;
umask(0022); # This sets umask for all files so that group and world only
$::NOK = -1;
$::OK = 0;
#--------------------------------------------------------------------------------
@ -46,71 +41,136 @@ This program module file, supports the xcat messaging and logging
#--------------------------------------------------------------------------------
=head1 Subroutines by Functional Group
=head1 Subroutines
=cut
=head3 message
Display a msg stdout, stderr, or a log file.
Display a msg STDOUT,STDERR or return to callback function.
If callback routine is provide, the message will be returned to the callback
routine and logged, if logging is requested.
This function is primarily meant for commands and other code that is sending
output directly to the user. Even the log is really a capture of this
interactive output.
routine.
If callback routime is not provide, the message is displayed to STDOUT or
STDERR.
Arguments:
The arguments of the message() function are:
if $::VERBOSE is set, the message will be displayed.
If $::LOG_FILE_HANDLE is set, the message goes to both
the screen and that log file. (Verbose msgs will be sent to
the log file even if $::VERBOSE is not set.)
A timestamp will automatically be put in front on any message
that is logged unless the T option is specified.
if address of the call_back is provided,
then the message will be returned
as data to the call_back routine.
If address of the callback is provided,
then the message will be returned either
as data to the client's callback routine or to the
xcat daemon or Client.pm ( bypass) for display/logging.
See flags below.
- The argument is the message to be displayed/logged.
If address of the callback is not provide, then
the message will be displayed to STDERR or STDOUT or
added to SYSLOG. See flags below.
For compatibility with existing code, the message routine will
move the data into the appropriate callback structure, if required.
See example below, if the input to the message routine
has the "data" structure filled in for an error message, then
the message routine will move the $rsp->{data}->[0] to
$rsp->{error}->[0]. This will allow xcatd/Client.pm will process
all but "data" messages.
The current client code should not have to change.
my %rsp;
$rsp->{data}->[0] = "Job did not run. \n";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
Here the message routine will move $rsp->{data}->[0] to
$rsp->{error}->[0], to match the "E"message code.
Note the message
routine will only check for the data to either exist in
$rsp->{error}->[0] already, or to exist in $rsp->{data}->[0].
Here's the meaning of the 1st character, if a callback specified:
D - DATA this is returned to the client callback routine
E - error this is displayed/logged by daemon/Client.pm.
I - informational this is displayed/logged by daemon/Client.pm.
S - Message will be logged to syslog ( severe error)
syslog facily (local4) and priority (err) will be used.
See /etc/syslog.conf file for the destination of the
messages.
Note S can be combined with other flags for example
SE logs message to syslog to also display the
message by daemon/ Client.pm.
V - verbose. This flag is not valid, the calling routine
should check for verbose mode before calling the message
routine and only use the I flag for the message.
If V flag is detected, it will be changed to an I flag.
W - warning this is displayed/logged by daemon/Client.pm.
Here's the meaning of the 1st character:
I - informational goes to stdout
E - error. This type of message will be sent to stderr.
V - verbose. This message should only be displayed,
if $::VERBOSE is set.
T - Do not log timestamp,
If $::LOG_FILE_HANDLE is set, the message goes to both
the screen and that log file. (Verbose msgs will be sent to
the log file even if $::VERBOSE is not set.)
A timestamp will automatically be put in front on any message
that is logged.
Optionally a T can be put before any of the above characters
"not" put a timestamp on
before the message when it is logged.
Note: T must be the first character.
Here's the meaning of the 1st character, if no callback specified:
D - DATA goes to STDOUT
E - error. This type of message will be sent to STDERR.
I - informational goes to STDOUT
S - Message will be logged to syslog ( severe error)
Note S can be combined with other flags for example
SE logs message to syslog and is sent to STDERR.
V - verbose. This flag is not valid, the calling routine
should check for verbose mode before calling the message
routine and only use the I flag for the message.
If V flag is detected, it will be changed to an I flag.
W - warning goes to STDOUT.
Returns:
none
Error:
_none
none
Example:
Use with no callback
xCAT::MsgUtils->message('E', "Operation $value1 failed\n");
Use of T flag
xCAT::MsgUtils->message('TI', "Operation $value1 failed\n");
Use of callback
xCAT::MsgUtils->message('I', $rsp,$call_back);
where $rsp is a data response structure for the callback function
xCAT::MsgUtils->message('S', "Host $host not responding\n");
xCAT::MsgUtils->message('SI', "Host $host not responding\n");
Use with callback
my %rsp;
$rsp->{data}->[0] = "Job did not run. \n";
xCAT::MsgUtils->message("D", $rsp, $::CALLBACK);
my %rsp;
$rsp->{error}->[0] = "No hosts in node list\n";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
my %rsp;
$rsp->{info}->[0] = "No hosts in node list\n";
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
my %rsp;
$rsp->{warning}->[0] = "No hosts in node list\n";
xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
my %rsp;
$rsp->{error}->[0] = "Host not responding\n";
xCAT::MsgUtils->message("S", $rsp, $::CALLBACK);
my %rsp;
$rsp->{error}->[0] = "Host not responding\n";
xCAT::MsgUtils->message("SE", $rsp, $::CALLBACK);
my %rsp;
$rsp->{info}->[0] = "Host not responding\n";
xCAT::MsgUtils->message("SI", $rsp, $::CALLBACK);
Comments:
Returns:
none
@ -125,227 +185,89 @@ sub message
# Process the arguments
shift; # get rid of the class name
my $sevcode = shift;
my $msg = shift;
my $sev = shift;
my $rsp = shift;
my $call_back = shift; # optional
# Parse the severity code
my $i = 1;
my $notimestamp = 0;
my $sev = substr($sevcode, 0, 1);
# should be I, E, V, T
if ($sev eq 'T') # do not put timestamp
{
$notimestamp = 1; # no timestamp
$i = 2; # logically shift everything by 1 char
$sev = substr($sevcode, 1, 1); # now should be either I,E,V
}
# should be I, D, E, S, W
# or S(I, D, E, S, W)
my $stdouterrf = \*STDOUT;
my $stdouterrd = '';
if (my $sev =~ /[E]/)
if ($sev =~ /[E]/)
{
$stdouterrf = \*STDERR;
$stdouterrd = '1>&2';
}
if (defined($::LOG_FILE_HANDLE))
{
if ($notimestamp == 0)
{ # print a timestamp
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
localtime(time);
my $time = $hour . ":" . $min . ":" . $sec . " ";
print $::LOG_FILE_HANDLE $time;
print $::LOG_FILE_HANDLE " ";
}
print $::LOG_FILE_HANDLE $msg;
if ($sev eq 'V')
{ # verbose should have been handled in calling routine
$sev = "I";
}
if ($sev eq 'SV')
{ # verbose should have been handled in calling routine
$sev = "SI";
}
# if V option and $::VERBOSE set or not V option then display
# Note Verbose messages, will be thrown away if verbose is not
# turned on and there is no logging.
if (($sev eq 'V' && $::VERBOSE) || ($sev ne 'V'))
{
if ($call_back)
{ # callback routine provided
$call_back->($msg);
}
else
# check that correct structure is filled in
# and move to correct structure. If the data is not in the
# structure corresponding to the $sev, then look for it in "data"
if ($call_back)
{ # callback routine provided
if (($sev eq 'I') || ($sev eq 'SI'))
{
print $stdouterrf $msg; # print the message
if (!($rsp->{info}->[0])) # no info data
{ # no error data
$rsp->{info}->[0] = $rsp->{data}->[0];
# $rsp->{data}->[0] = "";
}
}
if (($sev eq 'E') || ($sev eq 'S') || ($sev eq 'SE'))
{
if (!($rsp->{error}->[0])) # no error data
{ # no error data
$rsp->{error}->[0] = $rsp->{data}->[0];
# $rsp->{data}->[0] = "";
}
}
if (($sev eq 'W') || ($sev eq 'SW'))
{
if (!($rsp->{warning}->[0])) # no warning data
{ # no error data
$rsp->{warning}->[0] = $rsp->{data}->[0];
# $rsp->{data}->[0] = "";
}
}
if ($sev ne 'S')
{ # not just syslog
$call_back->($rsp); # send message to daemon/Client.pm unless
# data structure which is output by the commands
# callback routine.
}
}
else # no callback provided
{
if ($sev ne 'S') # syslog only
{
print $stdouterrf $rsp; # print the message
}
}
if ($sev =~ /[S]/)
{
# need to syslog , the message
openlog("xCAT", '', 'local4');
syslog("err", $rsp);
closelog();
}
return 0;
}
#--------------------------------------------------------------------------------
=head2 Message Logging Routines
=cut
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
=head3 backup_logfile
Backup the current logfile. Move logfile to logfile.1. Shift all other logfiles
(logfile.[1-3]) up one number. The original logfile.4 is removed as in a FIFO.
Arguments:
$logFileName
Returns:
$::OK
Error:
undefined
Example:
xCAT::MsgUtils->backup_logfile($logfile);
Comments:
Never used outside of ServerUtils.
=cut
#--------------------------------------------------------------------------------
sub backup_logfile
{
my ($class, $logfile) = @_;
my ($logfile1) = $logfile . ".1";
my ($logfile2) = $logfile . ".2";
my ($logfile3) = $logfile . ".3";
my ($logfile4) = $logfile . ".4";
if (-f $logfile)
{
rename($logfile3, $logfile4) if (-f $logfile3);
rename($logfile2, $logfile3) if (-f $logfile2);
rename($logfile1, $logfile2) if (-f $logfile1);
rename($logfile, $logfile1);
}
return $::OK;
}
#--------------------------------------------------------------------------------
=head3 start_logging
Start logging messages to a logfile. Return the log file handle so it
can be used to close the file when done logging.
Arguments:
$logFile
Returns:
$::LOG_FILE_HANDLE
Globals:
$::LOG_FILE_HANDLE
$::XCATLOG
Error:
$::NOK
Example:
xCAT::MsgUtils->start_logging($cfmupdatenode.log);
Comments:
Common method for logging script runtime output.
=cut
#--------------------------------------------------------------------------------
sub start_logging
{
my ($class, $logfile) = @_;
my ($cmd, $rc);
xCAT::MsgUtils->backup_logfile($logfile);
# create the log directory if it's not already there
if (!-d $::XCATLOG)
{
mkdir($::XCATLOG, 0755);
}
# open the log file
unless (open(LOGFILE, ">>$logfile"))
{
# Cannot open file
xCAT::MsgUtils->message("E", "Cannot open file: $logfile.\n");
return $::NOK;
}
$::LOG_FILE_HANDLE = \*LOGFILE;
# Print the date to the top of the logfile
my $sdate = localtime(time);
chomp $sdate;
my $program = xCAT::Utils->programName();
xCAT::MsgUtils->message(
"TV",
"#--------------------------------------------------------------------------#\n"
);
xCAT::MsgUtils->message("TV", "$program: Logging Started:$sdate\n");
xCAT::MsgUtils->message("TV", "Input: $::command_line\n");
xCAT::MsgUtils->message(
"TV",
"#--------------------------------------------------------------------------#\n"
);
return ($::LOG_FILE_HANDLE);
}
#--------------------------------------------------------------------------------
=head3 stop_logging
Turn off message logging close file. Routine expects to have a file handle
passed in via the global $::LOG_FILE_HANDLE.
Arguments:
Returns:
$::OK
Globals:
$::LOG_FILE_HANDLE
Error:
none
Example:
xCAT::MsgUtils->stop_logging($cfmupdatenode.log);
Comments:
closes the logfile and undefines $::LOG_FILE_HANDLE
even on error.
=cut
#--------------------------------------------------------------------------------
sub stop_logging
{
my ($class) = @_;
if (defined($::LOG_FILE_HANDLE))
{
my $sdate = localtime(time);
chomp $sdate;
my $program = xCAT::Utils->programName();
xCAT::MsgUtils->message(
"TV",
"#--------------------------------------------------------------------------#\n"
);
xCAT::MsgUtils->message("TV", "$program: Logging Stopped: $sdate\n");
xCAT::MsgUtils->message(
"TV",
"#--------------------------------------------------------------------------#\n"
);
close($::LOG_FILE_HANDLE);
undef $::LOG_FILE_HANDLE;
}
return $::OK;
}
1;