diff --git a/docs/changelog/6.x.x.txt b/docs/changelog/6.x.x.txt
index 3b5ff43ca..05e722f8d 100644
--- a/docs/changelog/6.x.x.txt
+++ b/docs/changelog/6.x.x.txt
@@ -5,6 +5,7 @@
the rest of WebGUI
- fix [ 1173101 ] Template in ^LoginToggle();
- Added a page to the help docs which tells you what Assets are enabled for this site.
+ - Added a new Error Handling / Logging mechanism.
6.5.5
diff --git a/etc/log.conf.original b/etc/log.conf.original
new file mode 100644
index 000000000..b515bce8d
--- /dev/null
+++ b/etc/log.conf.original
@@ -0,0 +1,6 @@
+log4perl.logger = DEBUG, mainlog
+log4perl.appender.mainlog = Log::Log4perl::Appender::File
+log4perl.appender.mainlog.filename = /var/log/webguitest.log
+log4perl.appender.mainlog.layout = PatternLayout
+log4perl.appender.mainlog.layout.ConversionPattern = %d - %p - %c - %M[%L] - %m%n
+
diff --git a/lib/WebGUI/Asset.pm b/lib/WebGUI/Asset.pm
index 5132ea2f1..b31817e3c 100644
--- a/lib/WebGUI/Asset.pm
+++ b/lib/WebGUI/Asset.pm
@@ -692,17 +692,17 @@ sub getAssetAdderLinks {
my $load = "use ".$class;
eval ($load);
if ($@) {
- WebGUI::ErrorHandler::warn("Couldn't compile ".$class." because ".$@);
+ WebGUI::ErrorHandler::error("Couldn't compile ".$class." because ".$@);
} else {
my $uiLevel = eval{$class->getUiLevel()};
if ($@) {
- WebGUI::ErrorHandler::warn("Couldn't get UI level of ".$class." because ".$@);
+ WebGUI::ErrorHandler::error("Couldn't get UI level of ".$class." because ".$@);
} else {
next if ($uiLevel > $session{user}{uiLevel});
}
my $label = eval{$class->getName()};
if ($@) {
- WebGUI::ErrorHandler::warn("Couldn't get the name of ".$class." because ".$@);
+ WebGUI::ErrorHandler::error("Couldn't get the name of ".$class." because ".$@);
} else {
my $url = $self->getUrl("func=add&class=".$class);
$url = WebGUI::URL::append($url,$addToUrl) if ($addToUrl);
@@ -1297,7 +1297,7 @@ sub getLineage {
my $className = $rules->{joinClass};
my $cmd = "use ".$className;
eval ($cmd);
- WebGUI::ErrorHandler::fatalError("Couldn't compile asset package: ".$className.". Root cause: ".$@) if ($@);
+ WebGUI::ErrorHandler::fatal("Couldn't compile asset package: ".$className.". Root cause: ".$@) if ($@);
foreach my $definition (@{$className->definition}) {
unless ($definition->{tableName} eq "asset") {
my $tableName = $definition->{tableName};
@@ -1760,14 +1760,14 @@ sub newByDynamicClass {
}
if ($className eq "") {
WebGUI::HTTP::setStatus('404',"Page Not Found");
- WebGUI::ErrorHandler::fatalError("The page not found page doesn't exist.") if ($assetId eq $session{setting}{notFoundPage});
+ WebGUI::ErrorHandler::fatal("The page not found page doesn't exist.") if ($assetId eq $session{setting}{notFoundPage});
return WebGUI::Asset->newByDynamicClass($session{setting}{notFoundPage});
}
my $cmd = "use ".$className;
eval ($cmd);
- WebGUI::ErrorHandler::fatalError("Couldn't compile asset package: ".$className.". Root cause: ".$@) if ($@);
+ WebGUI::ErrorHandler::fatal("Couldn't compile asset package: ".$className.". Root cause: ".$@) if ($@);
my $assetObject = eval{$className->new($assetId,$overrideProperties)};
- WebGUI::ErrorHandler::fatalError("Couldn't create asset instance for ".$assetId.". Root cause: ".$@) if ($@);
+ WebGUI::ErrorHandler::fatal("Couldn't create asset instance for ".$assetId.". Root cause: ".$@) if ($@);
return $assetObject;
}
@@ -1815,7 +1815,7 @@ sub newByPropertyHashRef {
my $className = $properties->{className};
my $cmd = "use ".$className;
eval ($cmd);
- WebGUI::ErrorHandler::fatalError("Couldn't compile asset package: ".$className.". Root cause: ".$@) if ($@);
+ WebGUI::ErrorHandler::fatal("Couldn't compile asset package: ".$className.". Root cause: ".$@) if ($@);
bless {_properties => $properties}, $className;
}
@@ -1966,7 +1966,7 @@ sub processTemplate {
if (defined $template) {
return $template->process(\%vars);
} else {
- WebGUI::ErrorHandler::warn("Can't instanciate template $templateId for asset ".$self->getId);
+ WebGUI::ErrorHandler::error("Can't instanciate template $templateId for asset ".$self->getId);
return "Error: Can't instanciate template ".$templateId;
}
}
diff --git a/lib/WebGUI/Asset/Template.pm b/lib/WebGUI/Asset/Template.pm
index 27e7c5c5d..22058d133 100644
--- a/lib/WebGUI/Asset/Template.pm
+++ b/lib/WebGUI/Asset/Template.pm
@@ -77,7 +77,7 @@ sub _execute {
$t->param("webgui.status"=>$WebGUI::STATUS);
return $t->output;
} else {
- WebGUI::ErrorHandler::warn("Error in template. ".$@);
+ WebGUI::ErrorHandler::error("Error in template. ".$@);
return WebGUI::International::get('template error', 'Template').$@;
}
}
@@ -250,11 +250,11 @@ sub process {
if ($session{config}{templateCacheType} =~ /file/) {
eval { mkpath($fileCacheDir) };
if($@) {
- WebGUI::ErrorHandler::warn("Could not create dir $fileCacheDir: $@\nTemplate file caching disabled");
+ WebGUI::ErrorHandler::error("Could not create dir $fileCacheDir: $@\nTemplate file caching disabled");
$error++;
}
if(not -w $fileCacheDir) {
- WebGUI::ErrorHandler::warn("Directory $fileCacheDir is not writable. Template file caching is disabled");
+ WebGUI::ErrorHandler::error("Directory $fileCacheDir is not writable. Template file caching is disabled");
$error++;
}
}
@@ -274,7 +274,7 @@ sub process {
unless (-e $file->getPath) {
$file->saveFromScalar($self->get("template"));
unless (-e $file->getPath) {
- WebGUI::ErrorHandler::warn("Could not create file ".$file->getPath."\nTemplate file caching is disabled");
+ WebGUI::ErrorHandler::error("Could not create file ".$file->getPath."\nTemplate file caching is disabled");
$params{scalarref} = \$template;
delete $params{filename};
}
diff --git a/lib/WebGUI/Asset/Wobject/IndexedSearch/Search.pm b/lib/WebGUI/Asset/Wobject/IndexedSearch/Search.pm
index a672beca4..412ed6d71 100644
--- a/lib/WebGUI/Asset/Wobject/IndexedSearch/Search.pm
+++ b/lib/WebGUI/Asset/Wobject/IndexedSearch/Search.pm
@@ -125,7 +125,7 @@ sub create {
}
$self->{_fts} = DBIx::FullTextSearch->create($self->getDbh, $self->getIndexName, %options);
if (not defined $self->{_fts}) {
- WebGUI::ErrorHandler::fatalError("IndexedSearch: Unable to create index.\n$DBIx::FullTextSearch::errstr");
+ WebGUI::ErrorHandler::error("IndexedSearch: Unable to create index.\n$DBIx::FullTextSearch::errstr");
return undef;
}
$self->{_docId} = 1;
@@ -473,7 +473,7 @@ sub open {
my ($self) = @_;
$self->{_fts} = DBIx::FullTextSearch->open($self->getDbh, $self->getIndexName);
if (not defined $self->{_fts}) {
- WebGUI::ErrorHandler::fatalError("IndexedSearch: Unable to open index.\n$DBIx::FullTextSearch::errstr");
+ WebGUI::ErrorHandler::error("IndexedSearch: Unable to open index.\n$DBIx::FullTextSearch::errstr");
return undef;
}
($self->{_docId}) = WebGUI::SQL->quickArray("select max(docId) from IndexedSearch_docInfo where indexName = ".quote($self->getIndexName));
diff --git a/lib/WebGUI/Asset/Wobject/WSClient.pm b/lib/WebGUI/Asset/Wobject/WSClient.pm
index 92e9dba24..af195af26 100644
--- a/lib/WebGUI/Asset/Wobject/WSClient.pm
+++ b/lib/WebGUI/Asset/Wobject/WSClient.pm
@@ -354,7 +354,7 @@ sub view {
# the solution is to normalize all params to another table
eval "\$arr_ref = [$param_str];";
eval { @params = @$arr_ref; };
- WebGUI::ErrorHandler::warn(WebGUI::International::get(22, "WSClient")) if $@ && $self->get('debugMode');
+ WebGUI::ErrorHandler::debug(WebGUI::International::get(22, "WSClient")) if $@ && $self->get('debugMode');
if ($self->get('execute_by_default') || grep /^$call$/,
@targetWobjects) {
@@ -363,12 +363,12 @@ sub view {
# valid looking uri, but I haven't hunted for the relevant RFC yet
if ($self->get("uri") =~ m!.+/.+!) {
- WebGUI::ErrorHandler::warn('uri=' . $self->get("uri"))
+ WebGUI::ErrorHandler::debug('uri=' . $self->get("uri"))
if $self->get('debugMode');
$soap = $self->_instantiate_soap;
} else {
- WebGUI::ErrorHandler::warn(WebGUI::International::get(23, "WSClient")) if $self->get('debugMode');
+ WebGUI::ErrorHandler::debug(WebGUI::International::get(23, "WSClient")) if $self->get('debugMode');
}
}
}
@@ -383,14 +383,14 @@ sub view {
# otherwise)". That "not stated otherwise" bit is important.
my $return = $soap->$call(@params);
- WebGUI::ErrorHandler::warn("$call(" . (join ',', @params) . ')')
+ WebGUI::ErrorHandler::debug("$call(" . (join ',', @params) . ')')
if $self->get('debugMode');
# The possible return types I've come across include a SOAP object,
# a hash reference, a blessed object or a simple scalar. Each type
# requires different handling (woohoo!) before being passed to the
# template system
- WebGUI::ErrorHandler::warn(WebGUI::International::get(24, "WSClient") . (ref $return ? ref $return : 'scalar')) if $self->get('debugMode');
+ WebGUI::ErrorHandler::debug(WebGUI::International::get(24, "WSClient") . (ref $return ? ref $return : 'scalar')) if $self->get('debugMode');
# SOAP object
if ((ref $return) =~ /SOAP/i) {
@@ -423,9 +423,9 @@ sub view {
# did the soap call fault?
if ($@) {
- WebGUI::ErrorHandler::warn($@) if $self->get('debugMode');
+ WebGUI::ErrorHandler::debug($@) if $self->get('debugMode');
$var{'soapError'} = $@;
- WebGUI::ErrorHandler::warn(WebGUI::International::get(25, "WSClient") . $var{'soapError'})
+ WebGUI::ErrorHandler::debug(WebGUI::International::get(25, "WSClient") . $var{'soapError'})
if $self->get('debugMode');
}
@@ -434,7 +434,7 @@ sub view {
WebGUI::ErrorHandler::warn("Using cached data");
}
- WebGUI::ErrorHandler::warn(Dumper(@result)) if
+ WebGUI::ErrorHandler::debug(Dumper(@result)) if
$self->get('debugMode');
# Do we need to decode utf8 data? Will only decode if modules were
@@ -508,7 +508,7 @@ sub view {
} else {
- WebGUI::ErrorHandler::warn(WebGUI::International::get(26, "WSClient") . $@) if $self->get('debugMode');
+ WebGUI::ErrorHandler::debug(WebGUI::International::get(26, "WSClient") . $@) if $self->get('debugMode');
}
# did they request a funky http header?
@@ -540,7 +540,7 @@ sub _instantiate_soap {
# we don't use fault handling with wsdls becuase they seem to behave
# differently. Not sure if that is by design.
if ( ($self->get("uri") =~ m/\.wsdl\s*$/i) || ($self->get("uri") =~ m/\.\w*\?wsdl\s*$/i) ) {
- WebGUI::ErrorHandler::warn('wsdl=' . $self->get('uri'))
+ WebGUI::ErrorHandler::debug('wsdl=' . $self->get('uri'))
if $self->get('debugMode');
# instantiate SOAP service
@@ -548,7 +548,7 @@ sub _instantiate_soap {
# standard uri namespace
} else {
- WebGUI::ErrorHandler::warn('uri=' . $self->get('uri'))
+ WebGUI::ErrorHandler::debug('uri=' . $self->get('uri'))
if $self->get('debugMode');
# instantiate SOAP service, with fault handling
@@ -562,7 +562,7 @@ sub _instantiate_soap {
# proxy the call if requested
if ($self->get("proxy") && $soap) {
- WebGUI::ErrorHandler::warn('proxy=' . $self->get('proxy'))
+ WebGUI::ErrorHandler::debug('proxy=' . $self->get('proxy'))
if $self->get('debugMode');
$soap->proxy($self->get('proxy'),
options => {compress_threshold => 10000});
diff --git a/lib/WebGUI/Auth/LDAP.pm b/lib/WebGUI/Auth/LDAP.pm
index 8667607c4..de107d18c 100644
--- a/lib/WebGUI/Auth/LDAP.pm
+++ b/lib/WebGUI/Auth/LDAP.pm
@@ -69,7 +69,7 @@ sub _isValidLDAPUser {
WebGUI::ErrorHandler::warn("Invalid LDAP information for registration of LDAP ID: ".$session{form}{'authLDAP.ldapId'});
} elsif ($auth->code > 0) {
$error .= '
LDAP error "'.$ldapStatusCode{$auth->code}.'" occured. '.WebGUI::International::get(69);
- WebGUI::ErrorHandler::warn("LDAP error: ".$ldapStatusCode{$auth->code});
+ WebGUI::ErrorHandler::error("LDAP error: ".$ldapStatusCode{$auth->code});
}
$ldap->unbind;
} else {
@@ -78,11 +78,11 @@ sub _isValidLDAPUser {
}
} else {
$error = WebGUI::International::get(2,'AuthLDAP');
- WebGUI::ErrorHandler::warn("Couldn't bind to LDAP server: ".$session{setting}{ldapURL});
+ WebGUI::ErrorHandler::error("Couldn't bind to LDAP server: ".$session{setting}{ldapURL});
}
} else {
$error = WebGUI::International::get(2,'AuthLDAP');
- WebGUI::ErrorHandler::warn("Couldn't create LDAP object: ".$uri->host);
+ WebGUI::ErrorHandler::error("Couldn't create LDAP object: ".$uri->host);
}
$self->error($error);
return $error eq "";
@@ -153,12 +153,12 @@ sub authenticate {
$error .= WebGUI::International::get(68);
}elsif($auth->code > 0){
$error .= 'LDAP error "'.$ldapStatusCode{$auth->code}.'" occured.'.WebGUI::International::get(69);
- WebGUI::ErrorHandler::warn("LDAP error: ".$ldapStatusCode{$auth->code});
+ WebGUI::ErrorHandler::error("LDAP error: ".$ldapStatusCode{$auth->code});
}
$ldap->unbind;
}else{
$error .= WebGUI::International::get(13,'AuthLDAP');
- WebGUI::ErrorHandler::warn("Could not process this LDAP URL: ".$userData->{ldapUrl});
+ WebGUI::ErrorHandler::error("Could not process this LDAP URL: ".$userData->{ldapUrl});
}
if($error ne ""){
$self->error($error);
diff --git a/lib/WebGUI/Commerce/Item.pm b/lib/WebGUI/Commerce/Item.pm
index 140edcabc..25f1bf188 100644
--- a/lib/WebGUI/Commerce/Item.pm
+++ b/lib/WebGUI/Commerce/Item.pm
@@ -43,7 +43,7 @@ This returns the description of the item. This must be implemented by an item pl
=cut
sub description {
- return WebGUI::ErrorHandler::fatalError('The description method of WebGUI::Commerce::Item must be overridden.');
+ return WebGUI::ErrorHandler::fatal('The description method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
@@ -83,7 +83,7 @@ by an item plugin.
=cut
sub id {
- return WebGUI::ErrorHandler::fatalError('The id method of WebGUI::Commerce::Item must be overridden.');
+ return WebGUI::ErrorHandler::fatal('The id method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
@@ -108,7 +108,7 @@ Returns the name of the item. This must be implemented by an item plugin.
=cut
sub name {
- return WebGUI::ErrorHandler::fatalError('The name method of WebGUI::Commerce::Item must be overridden.');
+ return WebGUI::ErrorHandler::fatal('The name method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
diff --git a/lib/WebGUI/Commerce/Payment.pm b/lib/WebGUI/Commerce/Payment.pm
index b6acd919b..37fb79c3b 100644
--- a/lib/WebGUI/Commerce/Payment.pm
+++ b/lib/WebGUI/Commerce/Payment.pm
@@ -215,7 +215,7 @@ Returns the gatewayId of the transaction. You must override this method.
=cut
sub gatewayId {
- return WebGUI::ErrorHandler::fatalError("You must override the gatewayId method in your Payment plugin.");
+ return WebGUI::ErrorHandler::fatal("You must override the gatewayId method in your Payment plugin.");
}
#-------------------------------------------------------------------
@@ -253,7 +253,7 @@ Returns the error code of the last submission.
=cut
sub errorCode {
- return WebGUI::ErrorHandler::fatalError("You must override thie errorCode method in the payment plugin.");
+ return WebGUI::ErrorHandler::fatal("You must override thie errorCode method in the payment plugin.");
}
#-------------------------------------------------------------------
@@ -292,7 +292,7 @@ Returns the (display) name of the plugin. You must override this method.
=cut
sub name {
- return WebGUI::ErrorHandler::fatalError("You must override the name method in the payment plugin.");
+ return WebGUI::ErrorHandler::fatal("You must override the name method in the payment plugin.");
}
#-------------------------------------------------------------------
@@ -363,7 +363,7 @@ Returns the result code of the transaction. You must override this method.
=cut
sub resultCode {
- return WebGUI::ErrorHandler::fatalError("You must override the resultCode method in the payment plugin.");
+ return WebGUI::ErrorHandler::fatal("You must override the resultCode method in the payment plugin.");
}
#-------------------------------------------------------------------
@@ -375,7 +375,7 @@ Returns the result message of the transaction. You must override this method.
=cut
sub resultMessage {
- return WebGUI::ErrorHandler::fatalError("You must override the resultMessage method in the payment plugin.");
+ return WebGUI::ErrorHandler::fatal("You must override the resultMessage method in the payment plugin.");
}
#-------------------------------------------------------------------
@@ -450,7 +450,7 @@ You must override this method.
=cut
sub supports {
- return WebGUI::ErrorHandler::fatalError("You must override the supports method in the payment plugin.");
+ return WebGUI::ErrorHandler::fatal("You must override the supports method in the payment plugin.");
}
#-------------------------------------------------------------------
@@ -462,7 +462,7 @@ A boolean indicating whether the payment has been finished or not. You must over
=cut
sub transactionCompleted {
- return WebGUI::ErrorHandler::fatalError("You must override the transactionCompleted method in the payment plugin.");
+ return WebGUI::ErrorHandler::fatal("You must override the transactionCompleted method in the payment plugin.");
}
#-------------------------------------------------------------------
@@ -474,7 +474,7 @@ Returns an error message if a transaction error has occurred. You must override
=cut
sub transactionError {
- return WebGUI::ErrorHandler::fatalError("You must override the transactionError method in the payment plugin.");
+ return WebGUI::ErrorHandler::fatal("You must override the transactionError method in the payment plugin.");
}
#-------------------------------------------------------------------
@@ -486,7 +486,7 @@ A boolean indicating whether the payment is pending or not. You must override th
=cut
sub transactionPending {
- return WebGUI::ErrorHandler::fatalError("You must override the transactionPending method in the payment plugin.");
+ return WebGUI::ErrorHandler::fatal("You must override the transactionPending method in the payment plugin.");
}
#-------------------------------------------------------------------
@@ -500,7 +500,7 @@ undef. You must override this method.
=cut
sub validateFormData {
- return WebGUI::ErrorHandler::fatalError("You must override the validateFormData method in the payment plugin.");
+ return WebGUI::ErrorHandler::fatal("You must override the validateFormData method in the payment plugin.");
}
1;
diff --git a/lib/WebGUI/Commerce/Payment/ITransact.pm b/lib/WebGUI/Commerce/Payment/ITransact.pm
index 52b0942ff..6bcc4700d 100644
--- a/lib/WebGUI/Commerce/Payment/ITransact.pm
+++ b/lib/WebGUI/Commerce/Payment/ITransact.pm
@@ -60,7 +60,7 @@ sub cancelRecurringPayment {
# print "FIRST PAGE SUCCESS!\n";
# print "(".$response->base.")\n";
} else {
- WebGUI::ErrorHandler::fatalError(
+ WebGUI::ErrorHandler::fatal(
'Connection Error while trying to cancel transaction '.$recurring->{transaction}->transactionId." \n".
"Could not reach login page.\n".
"(".$response->base.")\n".
@@ -83,7 +83,7 @@ sub cancelRecurringPayment {
# print "CANCELATION PAGE SUCCESS!\n";
# print "(".$response->base.")\n";
} else {
- WebGUI::ErrorHandler::fatalError(
+ WebGUI::ErrorHandler::fatal(
'Connection Error while trying to cancel transaction '.$recurring->{transaction}->transactionId." \n".
"(".$response->base.")\n".
$response->status_line. "\n");
diff --git a/lib/WebGUI/ErrorHandler.pm b/lib/WebGUI/ErrorHandler.pm
index d899e7378..53be93297 100644
--- a/lib/WebGUI/ErrorHandler.pm
+++ b/lib/WebGUI/ErrorHandler.pm
@@ -18,7 +18,9 @@ use FileHandle;
use Log::Log4perl;
use strict;
use WebGUI::Session;
+use Log::Log4perl;
+$Log::Log4perl::caller_depth++;
=head1 NAME
@@ -26,7 +28,7 @@ Package WebGUI::ErrorHandler
=head1 DESCRIPTION
-This package provides simple but effective error handling and logging for WebGUI.
+This package provides simple but effective error handling, debugging, and logging for WebGUI.
=head1 SYNOPSIS
@@ -46,7 +48,6 @@ This package provides simple but effective error handling and logging for WebGUI
WebGUI::ErrorHandler::showAudit();
WebGUI::ErrorHandler::showDebug();
WebGUI::ErrorHandler::showSecurity();
- WebGUI::ErrorHandler::showSessionVars();
WebGUI::ErrorHandler::showStackTrace();
WebGUI::ErrorHandler::showWarnings();
@@ -65,7 +66,7 @@ These functions are available from this package:
=head2 audit ( message )
-Inserts an AUDIT type message into the WebGUI log.
+A convenience function that wraps info() and includes the current username and user ID in addition to the message being logged.
=head3 message
@@ -74,22 +75,67 @@ Whatever message you wish to insert into the log.
=cut
sub audit {
- my $data = stamp("AUDIT").$WebGUI::Session::session{user}{username}
- ." (".$WebGUI::Session::session{user}{userId}.") ".$_[0]."\n";
- writeLog($data);
- $WebGUI::Session::session{debug}{audit} .= $data;
+ my $message = shift;
+ $Log::Log4perl::caller_depth++;
+ info($WebGUI::Session::session{user}{username}." (".$WebGUI::Session::session{user}{userId}.") ".$message);
+ $Log::Log4perl::caller_depth--;
}
#-------------------------------------------------------------------
-=head2 fatalError ( )
+=head2 debug ( message )
-Outputs an error message to the user and logs an error. Should only be called if the system cannot recover from an error, or if it would be unsafe to attempt to recover from an error (like compile errors or database errors).
+Adds a DEBUG type message to the log. These events should be things that are only used for diagnostic purposes.
+
+=head3 message
+
+The message you wish to add to the log.
=cut
-sub fatalError {
+sub debug {
+ my $message = shift;
+ my $logger = getLogger();
+ $logger->debug($message);
+ $WebGUI::Session::session{debug}{'debug'} .= $message;
+}
+
+
+#-------------------------------------------------------------------
+
+=head2 error ( message )
+
+Adds a ERROR type message to the log. These events should be things that are errors that are not fatal. For instance, a non-compiling plug-in or erroneous user input.
+
+=head3 message
+
+The message you wish to add to the log.
+
+=cut
+
+sub error {
+ my $message = shift;
+ my $logger = getLogger();
+ $logger->error($message);
+ $logger->debug("Stack trace for ERROR ".$message."\n".getStackTrace());
+ $WebGUI::Session::session{debug}{'error'} .= $message;
+}
+
+
+#-------------------------------------------------------------------
+
+=head2 fatal ( )
+
+Adds a FATAL type message to the log, outputs an error message to the user, and forces a close on the session. This should only be called if the system cannot recover from an error, or it would be unsafe to recover from an error like database connectivity problems.
+
+=cut
+
+sub fatal {
+ my $message = shift;
+ my $logger = getLogger();
+ $logger->fatal($message);
+ $logger->debug("Stack trace for FATAL ".$message."\n".getStackTrace());
my $cgi;
if (exists $WebGUI::Session::session{cgi}) {
$cgi = $WebGUI::Session::session{cgi};
@@ -98,10 +144,6 @@ sub fatalError {
$cgi = CGI->new;
}
print $cgi->header;
- my $toLog = stamp("FATAL").$_[0]."\n";
- $toLog .= getStackTrace();
- $toLog .= getSessionVars();
- writeLog($toLog);
unless ($WebGUI::Session::session{setting}{showDebug}) {
#NOTE: You can't internationalize this because with some types of errors that would cause an infinite loop.
print "Problem With Request
@@ -111,9 +153,8 @@ sub fatalError {
print '
'.$WebGUI::Session::session{setting}{companyEmail};
print '
'.$WebGUI::Session::session{setting}{companyURL};
} else {
- print "WebGUI Fatal Error
Something unexpected happened that caused this system to fault.";
- print $_[0]."
";
- print showStackTrace();
+ print "
WebGUI Fatal Error
Something unexpected happened that caused this system to fault.
\n";
+ print "".$message."
\n";
print showDebug();
}
WebGUI::Session::close();
@@ -123,27 +164,15 @@ sub fatalError {
#-------------------------------------------------------------------
-=head2 getAudit ( )
+=head2 getLogger ( )
-Returns a text formatted message containing the audit messages.
+Returns a reference to the logger.
=cut
-sub getAudit {
- return $WebGUI::Session::session{debug}{audit};
-}
-
-
-#-------------------------------------------------------------------
-
-=head2 getSecurity ( )
-
-Returns a text formatted message containing the security messages.
-
-=cut
-
-sub getSecurity {
- return $WebGUI::Session::session{debug}{security};
+sub getLogger {
+ Log::Log4perl::init_once($WebGUI::Session::session{config}{webguiRoot}.$WebGUI::Session::session{os}{slash}.'etc'.$WebGUI::Session::session{os}{slash}."log.conf");
+ return Log::Log4perl->get_logger($WebGUI::Session::session{config}{configFile});
}
@@ -204,9 +233,9 @@ sub getStackTrace {
#-------------------------------------------------------------------
-=head2 getWarnings ( )
+=head2 getWarn ( )
-Returns a text formatted message containing the warnings.
+Returns a text formatted message containing the WARN messages.
=cut
@@ -215,11 +244,31 @@ sub getWarnings {
}
+#-------------------------------------------------------------------
+
+=head2 info ( message )
+
+Adds an INFO type message to the log. This should be used for informational or status types of messages, such as audit information and FYIs.
+
+=head3 message
+
+The message you wish to add to the log.
+
+=cut
+
+sub info {
+ my $message = shift;
+ my $logger = getLogger();
+ $logger->info($message);
+ $WebGUI::Session::session{debug}{'info'} .= $message;
+}
+
+
#-------------------------------------------------------------------
=head2 security ( message )
-Adds a SECURITY type message to the log.
+A convenience function that wraps warn() and includes the current username, user ID, and IP address in addition to the message being logged.
=head3 message
@@ -228,26 +277,11 @@ The message you wish to add to the log.
=cut
sub security {
- my $data = stamp("SECURITY").$WebGUI::Session::session{user}{username}
- ." (".$WebGUI::Session::session{user}{userId}
- .") connecting from ".$WebGUI::Session::session{env}{REMOTE_ADDR}." attempted to ".$_[0]."\n";
- writeLog($data);
- $WebGUI::Session::session{debug}{security} .= $data;
-}
-
-
-#-------------------------------------------------------------------
-
-=head2 showAudit ( )
-
-Returns an HTML formatted message with the audit messages for display during debug operations.
-
-=cut
-
-sub showAudit {
- my $audit = getAudit();
- $audit =~ s/\n/\
\n/g;
- return ''.$audit.'
';
+ my $message = shift;
+ $Log::Log4perl::caller_depth++;
+ warn($WebGUI::Session::session{user}{username}." (".$WebGUI::Session::session{user}{userId}.") connecting from "
+ .$WebGUI::Session::session{env}{REMOTE_ADDR}." attempted to ".$message);
+ $Log::Log4perl::caller_depth--;
}
@@ -255,100 +289,36 @@ sub showAudit {
=head2 showDebug ( )
-Creates an HTML formatted string containing the most common debug information.
+Creates an HTML formatted string
=cut
sub showDebug {
- return showWarnings()
- .showSecurity()
- .showAudit()
- .showSessionVars();
+ my $text = $WebGUI::Session::session{debug}{'error'};
+ $text =~ s/\n/\
\n/g;
+ my $output = ''.$text."
\n";
+ $text = $WebGUI::Session::session{debug}{'warn'};
+ $text =~ s/\n/\
\n/g;
+ $output .= ''.$text."
\n";
+ $text = $WebGUI::Session::session{debug}{'info'};
+ $text =~ s/\n/\
\n/g;
+ $output .= ''.$text."
\n";
+ $text = $WebGUI::Session::session{debug}{'debug'};
+ $text =~ s/\n/\
\n/g;
+ $output .= ''.$text."
\n";
+ $text = getSessionVars();
+ $text =~ s/\n/\
\n/g;
+ $output .= ''.$text."
\n";
+ return $output;
}
-#-------------------------------------------------------------------
-
-=head2 showSecurity ( )
-
-Returns an HTML formatted message with the security messages for display during debug operations.
-
-=cut
-
-sub showSecurity {
- my $security = getSecurity();
- $security =~ s/\n/\
\n/g;
- return ''.$security.'
';
-}
-
-
-#-------------------------------------------------------------------
-
-=head2 showSessionVars ( )
-
-Returns an HTML formatted list of the session variables for display during debug operations.
-
-=cut
-
-sub showSessionVars {
- my $data = getSessionVars();
- $data =~ s/\n/\
\n/g;
- return ''.$data.'
';
-}
-
-
-#-------------------------------------------------------------------
-
-=head2 showStackTrace ( )
-
-Returns an HTML formatted message for displaying the stack trace during debug operations.
-
-=cut
-
-sub showStackTrace {
- my $st = getStackTrace();
- $st =~ s/\n/\
\n/g;
- return $st;
-}
-
-
-#-------------------------------------------------------------------
-
-=head2 showWarnings ( )
-
-Returns HTML formatted warnings for display during debug operations.
-
-=cut
-
-sub showWarnings {
- my $warning = getWarnings();
- $warning =~ s/\n/\
\n/g;
- return ''.$warning.'
';
-}
-
-
-#-------------------------------------------------------------------
-
-=head2 stamp ( type )
-
-Generates a stamp to be added to the log file. Use this in conjunction with your message for writeLog().
-
-=head3 type
-
-The type of message this is. You may use whatever type you wish. WebGUI currently uses AUDIT, WARNING, FATAL, and SECURITY.
-
-=cut
-
-sub stamp {
- return localtime(time)." ".$0." ".$_[0].": ";
-}
-
#-------------------------------------------------------------------
=head2 warn ( message )
-Adds a WARNING type message to the log.
+Adds a WARN type message to the log. These events should be things that are potentially severe, but not errors, such as security attempts or ineffiency problems.
=head3 message
@@ -357,35 +327,10 @@ The message you wish to add to the log.
=cut
sub warn {
- my $data = stamp("WARNING").$_[0]."\n";
- writeLog($data);
- $WebGUI::Session::session{debug}{warning} .= $data;
-}
-
-#-------------------------------------------------------------------
-
-=head2 writeLog ( message )
-
-Writes a message to the log.
-
-=head3 message
-
-The message you wish to write to the log.
-
-=cut
-
-sub writeLog {
- if (my $log = FileHandle->new(">>".$WebGUI::Session::session{config}{logfile})) {
- print $log "\n".$_[0];
- printf $log '%s:%d (sub %s) ',(caller(2))[1,2,3];
- $log->close;
- } else {
- use CGI;
- my $cgi = CGI->new;
- print STDOUT $cgi->header(). "Can't open log file: ".$WebGUI::Session::session{config}{logfile}." Check your WebGUI configuration file to set the path of the log file, and check to be sure the web server has the privileges to write to the log file.";;
- WebGUI::Session::close();
- exit;
- }
+ my $message = shift;
+ my $logger = getLogger();
+ $logger->warn($message);
+ $WebGUI::Session::session{debug}{'warn'} .= $message;
}
diff --git a/lib/WebGUI/Grouping.pm b/lib/WebGUI/Grouping.pm
index 85ee201e7..25cb0edf5 100755
--- a/lib/WebGUI/Grouping.pm
+++ b/lib/WebGUI/Grouping.pm
@@ -268,7 +268,7 @@ sub getGroupsInGroup {
if ($isRecursive) {
$loopCount++;
if ($loopCount > 99) {
- WebGUI::ErrorHandler::fatalError("Endless recursive loop detected while determining".
+ WebGUI::ErrorHandler::fatal("Endless recursive loop detected while determining".
" groups in group.\nRequested groupId: ".$groupId."\nGroups in that group: ".join(",",@$groups));
}
my @groupsOfGroups = @$groups;
diff --git a/lib/WebGUI/International.pm b/lib/WebGUI/International.pm
index 942d8f388..bc232e710 100644
--- a/lib/WebGUI/International.pm
+++ b/lib/WebGUI/International.pm
@@ -140,7 +140,7 @@ Returns a hash reference to the languages (languageId/lanugage) installed on thi
sub getLanguages {
my ($hashRef);
my $dir = $session{config}{webguiRoot}.$session{os}{slash}."lib".$session{os}{slash}."WebGUI".$session{os}{slash}."i18n";
- opendir (DIR,$dir) or WebGUI::ErrorHandler::fatalError("Can't open I18N directory! ".$dir);
+ opendir (DIR,$dir) or WebGUI::ErrorHandler::fatal("Can't open I18N directory! ".$dir);
my @files = readdir(DIR);
closedir(DIR);
foreach my $file (@files) {
diff --git a/lib/WebGUI/Macro.pm b/lib/WebGUI/Macro.pm
index 04384c47f..7b7b387fd 100644
--- a/lib/WebGUI/Macro.pm
+++ b/lib/WebGUI/Macro.pm
@@ -155,14 +155,15 @@ sub process {
my $cmd = "WebGUI::Macro::".$session{config}{macros}{$searchString};
my $load = "use ".$cmd;
eval($load);
- WebGUI::ErrorHandler::warn("Macro failed to compile: $cmd.".$@) if($@);
+ WebGUI::ErrorHandler::error("Macro failed to compile: $cmd.".$@) if($@);
$cmd = $cmd."::process";
my $result = eval{&$cmd($params)};
if ($@) {
- WebGUI::ErrorHandler::warn("Processing failed on macro: $macro: ".$@);
+ WebGUI::ErrorHandler::error("Processing failed on macro: $macro: ".$@);
} else {
if ($result =~ /\Q$macro/) {
$result = "Endless macro loop detected. Stopping recursion.";
+ WebGUI::ErrorHandler::warn($macro." : ".$result)
}
$content =~ s/\Q$macro/$result/ges;
}
diff --git a/lib/WebGUI/Operation.pm b/lib/WebGUI/Operation.pm
index 5010cd309..8a64d5ad5 100644
--- a/lib/WebGUI/Operation.pm
+++ b/lib/WebGUI/Operation.pm
@@ -56,11 +56,11 @@ sub execute {
# Load the module
$cmd = 'use '.$operation->{$op};
eval ($cmd);
- WebGUI::ErrorHandler::fatalError("Couldn't compile operation: ".$operation->{$op}.". Root cause: ".$@) if ($@);
+ WebGUI::ErrorHandler::error("Couldn't compile operation: ".$operation->{$op}.". Root cause: ".$@) if ($@);
# Call the method
$cmd = $operation->{$op} . '::www_'.$op;
$output = eval($cmd);
- WebGUI::ErrorHandler::fatalError("Couldn't execute operation : ".$cmd.". Root cause: ".$@) if ($@);
+ WebGUI::ErrorHandler::error("Couldn't execute operation : ".$cmd.". Root cause: ".$@) if ($@);
} else {
WebGUI::ErrorHandler::security("execute an invalid operation: ".$op);
}
diff --git a/lib/WebGUI/Operation/Auth.pm b/lib/WebGUI/Operation/Auth.pm
index 03ec1e6b4..895f6a78a 100644
--- a/lib/WebGUI/Operation/Auth.pm
+++ b/lib/WebGUI/Operation/Auth.pm
@@ -41,10 +41,10 @@ sub getInstance {
#Create Auth Object
my $cmd = "WebGUI::Auth::".$authMethod;
my $load = "use ".$cmd;
- WebGUI::ErrorHandler::fatalError("Authentication module failed to compile: $cmd.".$@) if($@);
+ WebGUI::ErrorHandler::fatal("Authentication module failed to compile: $cmd.".$@) if($@);
eval($load);
my $auth = eval{$cmd->new($authMethod,$userId)};
- WebGUI::ErrorHandler::fatalError("Couldn't instanciate authentication module: $authMethod. Root cause: ".$@) if($@);
+ WebGUI::ErrorHandler::fatal("Couldn't instanciate authentication module: $authMethod. Root cause: ".$@) if($@);
return $auth;
}
diff --git a/lib/WebGUI/Operation/Help.pm b/lib/WebGUI/Operation/Help.pm
index dd4e22c97..26ee59ee8 100644
--- a/lib/WebGUI/Operation/Help.pm
+++ b/lib/WebGUI/Operation/Help.pm
@@ -68,7 +68,7 @@ sub www_viewHelpIndex {
tie %helpIndex, "Tie::IxHash";
my $i;
my $dir = $session{config}{webguiRoot}.$session{os}{slash}."lib".$session{os}{slash}."WebGUI".$session{os}{slash}."Help";
- opendir (DIR,$dir) or WebGUI::ErrorHandler::fatalError("Can't open Help directory!");
+ opendir (DIR,$dir) or WebGUI::ErrorHandler::fatal("Can't open Help directory!");
my @files = readdir(DIR);
closedir(DIR);
foreach my $file (@files) {
@@ -85,7 +85,7 @@ sub www_viewHelpIndex {
$i++;
}
} else {
- WebGUI::ErrorHandler::warn("Help failed to compile: $namespace. ".$@);
+ WebGUI::ErrorHandler::error("Help failed to compile: $namespace. ".$@);
}
}
}
diff --git a/lib/WebGUI/SQL.pm b/lib/WebGUI/SQL.pm
index 163a7564d..3a1385db8 100644
--- a/lib/WebGUI/SQL.pm
+++ b/lib/WebGUI/SQL.pm
@@ -93,7 +93,7 @@ Returns the next row of data as an array.
=cut
sub array {
- return $_[0]->{_sth}->fetchrow_array() or WebGUI::ErrorHandler::fatalError("Couldn't fetch array. ".$_[0]->{_sth}->errstr);
+ return $_[0]->{_sth}->fetchrow_array() or WebGUI::ErrorHandler::fatal("Couldn't fetch array. ".$_[0]->{_sth}->errstr);
}
@@ -279,7 +279,7 @@ sub execute {
my $self = shift;
my $placeholders = shift || [];
my $sql = $self->{_sql};
- $self->{_sth}->execute(@{$placeholders}) or WebGUI::ErrorHandler::fatalError("Couldn't execute prepared statement: $sql Root cause: ". DBI->errstr);
+ $self->{_sth}->execute(@{$placeholders}) or WebGUI::ErrorHandler::fatal("Couldn't execute prepared statement: $sql Root cause: ". DBI->errstr);
}
diff --git a/lib/WebGUI/Storage.pm b/lib/WebGUI/Storage.pm
index 9596b9dbe..59986d00a 100644
--- a/lib/WebGUI/Storage.pm
+++ b/lib/WebGUI/Storage.pm
@@ -93,7 +93,7 @@ sub _addError {
my $self = shift;
my $errorMessage = shift;
push(@{$self->{_errors}},$errorMessage);
- WebGUI::ErrorHandler::warn($errorMessage);
+ WebGUI::ErrorHandler::error($errorMessage);
}
@@ -148,7 +148,7 @@ sub addFileFromFilesystem {
}
$filename = WebGUI::URL::makeCompliant($filename);
if (-d $pathToFile) {
- WebGUI::ErrorHandler::warn($pathToFile." is a directory, not a file.");
+ WebGUI::ErrorHandler::error($pathToFile." is a directory, not a file.");
} else {
$a = FileHandle->new($pathToFile,"r");
if (defined $a) {
diff --git a/lib/WebGUI/Storage/Image.pm b/lib/WebGUI/Storage/Image.pm
index c0c23d56d..43224da90 100644
--- a/lib/WebGUI/Storage/Image.pm
+++ b/lib/WebGUI/Storage/Image.pm
@@ -94,17 +94,17 @@ sub generateThumbnail {
my $filename = shift;
my $thumbnailSize = shift || $session{setting}{thumbnailSize};
unless (defined $filename) {
- WebGUI::ErrorHandler::warn("Can't generate a thumbnail when you haven't specified a file.");
+ WebGUI::ErrorHandler::error("Can't generate a thumbnail when you haven't specified a file.");
return 0;
}
unless ($self->isImage($filename)) {
- WebGUI::ErrorHandler::warn("Can't generate a thumbnail for something that's not an image.");
+ WebGUI::ErrorHandler::error("Can't generate a thumbnail for something that's not an image.");
return 0;
}
my $image = Image::Magick->new;
my $error = $image->Read($self->getPath($filename));
if ($error) {
- WebGUI::ErrorHandler::warn("Couldn't read image for thumbnail creation: ".$error);
+ WebGUI::ErrorHandler::error("Couldn't read image for thumbnail creation: ".$error);
return 0;
}
my ($x, $y) = $image->Get('width','height');
@@ -116,7 +116,7 @@ sub generateThumbnail {
}
$error = $image->Write($self->getPath.$session{os}{slash}.'thumb-'.$filename);
if ($error) {
- WebGUI::ErrorHandler::warn("Couldn't create thumbnail: ".$error);
+ WebGUI::ErrorHandler::error("Couldn't create thumbnail: ".$error);
return 0;
}
return 1;
@@ -159,17 +159,17 @@ sub getSizeInPixels {
my $self = shift;
my $filename = shift;
unless (defined $filename) {
- WebGUI::ErrorHandler::warn("Can't check the size when you haven't specified a file.");
+ WebGUI::ErrorHandler::error("Can't check the size when you haven't specified a file.");
return 0;
}
unless ($self->isImage($filename)) {
- WebGUI::ErrorHandler::warn("Can't check the size of something that's not an image.");
+ WebGUI::ErrorHandler::error("Can't check the size of something that's not an image.");
return 0;
}
my $image = Image::Magick->new;
my $error = $image->Read($self->getPath($filename));
if ($error) {
- WebGUI::ErrorHandler::warn("Couldn't read image to check the size of it: ".$error);
+ WebGUI::ErrorHandler::error("Couldn't read image to check the size of it: ".$error);
return 0;
}
return $image->Get('width','height');
@@ -239,21 +239,21 @@ sub resize {
my $width = shift;
my $height = shift;
unless (defined $filename) {
- WebGUI::ErrorHandler::warn("Can't resize when you haven't specified a file.");
+ WebGUI::ErrorHandler::error("Can't resize when you haven't specified a file.");
return 0;
}
unless ($self->isImage($filename)) {
- WebGUI::ErrorHandler::warn("Can't resize something that's not an image.");
+ WebGUI::ErrorHandler::error("Can't resize something that's not an image.");
return 0;
}
unless ($width || $height) {
- WebGUI::ErrorHandler::warn("Can't resize with no resizing parameters.");
+ WebGUI::ErrorHandler::error("Can't resize with no resizing parameters.");
return 0;
}
my $image = Image::Magick->new;
my $error = $image->Read($self->getPath($filename));
if ($error) {
- WebGUI::ErrorHandler::warn("Couldn't read image for resizing: ".$error);
+ WebGUI::ErrorHandler::error("Couldn't read image for resizing: ".$error);
return 0;
}
my ($x, $y) = $image->Get('width','height');
@@ -265,7 +265,7 @@ sub resize {
$image->Scale(width=>$width, height=>$height);
$error = $image->Write($self->getPath($filename));
if ($error) {
- WebGUI::ErrorHandler::warn("Couldn't create thumbnail: ".$error);
+ WebGUI::ErrorHandler::error("Couldn't create thumbnail: ".$error);
return 0;
}
return 1;
diff --git a/sbin/preload.perl b/sbin/preload.perl
index 01205049c..6c0a8b8e5 100644
--- a/sbin/preload.perl
+++ b/sbin/preload.perl
@@ -43,6 +43,7 @@ use HTML::TagFilter ();
use HTML::Template ();
use Parse::PlainConfig ();
use Net::SMTP ();
+use Log::Log4perl ();
use Cache::Cache ();
use Tie::IxHash ();
use Tie::CPHash ();
diff --git a/sbin/testEnvironment.pl b/sbin/testEnvironment.pl
index 8ef350ed5..1fa656653 100644
--- a/sbin/testEnvironment.pl
+++ b/sbin/testEnvironment.pl
@@ -60,6 +60,7 @@ checkModule("XML::Simple",2.09);
checkModule("SOAP::Lite",0.60);
checkModule("Time::HiRes",1.38);
checkModule("Image::Magick",5.47,1);
+checkModule("Log::Log4perl",0.51);
checkModule("Net::LDAP",0.25);
checkModule("Date::Manip",5.42);
checkModule("HTML::Highlight",0.20);
diff --git a/sbin/userImport.pl b/sbin/userImport.pl
index 7dec9e729..6e7d70745 100644
--- a/sbin/userImport.pl
+++ b/sbin/userImport.pl
@@ -314,7 +314,7 @@ while() {
$u->status($user{status});
my $cmd = "WebGUI::Auth::".$authMethod;
my $load = "use ".$cmd;
- WebGUI::ErrorHandler::fatalError("Authentication module failed to compile: $cmd.".$@) if($@);
+ WebGUI::ErrorHandler::fatal("Authentication module failed to compile: $cmd.".$@) if($@);
eval($load);
my $auth = eval{$cmd->new($authMethod,$u->userId)};
$auth->saveParams($u->userId,"WebGUI",{identifier=>$user{identifier}});