Logging has been implemented for exceptions
This commit is contained in:
parent
6af93506f1
commit
f15cb63d32
@ -18,6 +18,7 @@ use BusinessLogic\Tickets\TicketValidators;
|
|||||||
use BusinessLogic\Tickets\TrackingIdGenerator;
|
use BusinessLogic\Tickets\TrackingIdGenerator;
|
||||||
use BusinessLogic\Tickets\VerifiedEmailChecker;
|
use BusinessLogic\Tickets\VerifiedEmailChecker;
|
||||||
use DataAccess\Categories\CategoryGateway;
|
use DataAccess\Categories\CategoryGateway;
|
||||||
|
use DataAccess\Logging\LoggingGateway;
|
||||||
use DataAccess\Security\BanGateway;
|
use DataAccess\Security\BanGateway;
|
||||||
use DataAccess\Security\UserGateway;
|
use DataAccess\Security\UserGateway;
|
||||||
use DataAccess\Settings\ModsForHeskSettingsGateway;
|
use DataAccess\Settings\ModsForHeskSettingsGateway;
|
||||||
@ -38,6 +39,9 @@ class ApplicationContext {
|
|||||||
// API Checker
|
// API Checker
|
||||||
$this->get[ApiChecker::class] = new ApiChecker($this->get[ModsForHeskSettingsGateway::class]);
|
$this->get[ApiChecker::class] = new ApiChecker($this->get[ModsForHeskSettingsGateway::class]);
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
$this->get[LoggingGateway::class] = new LoggingGateway();
|
||||||
|
|
||||||
// Verified Email Checker
|
// Verified Email Checker
|
||||||
$this->get[VerifiedEmailGateway::class] = new VerifiedEmailGateway();
|
$this->get[VerifiedEmailGateway::class] = new VerifiedEmailGateway();
|
||||||
$this->get[VerifiedEmailChecker::class] = new VerifiedEmailChecker($this->get[VerifiedEmailGateway::class]);
|
$this->get[VerifiedEmailChecker::class] = new VerifiedEmailChecker($this->get[VerifiedEmailGateway::class]);
|
||||||
|
47
api/DataAccess/Logging/LoggingGateway.php
Normal file
47
api/DataAccess/Logging/LoggingGateway.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DataAccess\Logging;
|
||||||
|
|
||||||
|
|
||||||
|
use BusinessLogic\Security\UserContext;
|
||||||
|
use DataAccess\CommonDao;
|
||||||
|
|
||||||
|
class LoggingGateway extends CommonDao {
|
||||||
|
function logDebug($location, $message, $stackTrace, $userContext, $heskSettings) {
|
||||||
|
return $this->log(Severity::DEBUG, $location, $message, $stackTrace, $userContext, $heskSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
function logInfo($location, $message, $stackTrace, $userContext, $heskSettings) {
|
||||||
|
return $this->log(Severity::INFO, $location, $message, $stackTrace, $userContext, $heskSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
function logWarning($location, $message, $stackTrace, $userContext, $heskSettings) {
|
||||||
|
return $this->log(Severity::WARNING, $location, $message, $stackTrace, $userContext, $heskSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
function logError($location, $message, $stackTrace, $userContext, $heskSettings) {
|
||||||
|
return $this->log(Severity::ERROR, $location, $message, $stackTrace, $userContext, $heskSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $severity int (from Severity)
|
||||||
|
* @param $location string
|
||||||
|
* @param $message string
|
||||||
|
* @param $userContext UserContext
|
||||||
|
* @param $heskSettings array
|
||||||
|
* @return int|null|string The inserted ID, or null on failure.
|
||||||
|
*/
|
||||||
|
private function log($severity, $location, $message, $stackTrace, $userContext, $heskSettings) {
|
||||||
|
$this->init();
|
||||||
|
|
||||||
|
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($heskSettings['db_pfix']) . "logging` (`username`, `message`, `severity`, `location`, `timestamp`, `stack_trace`)
|
||||||
|
VALUES ('" . hesk_dbEscape($userContext->username) . "',
|
||||||
|
'" . hesk_dbEscape($message) . "', " . intval($severity) . ", '" . hesk_dbEscape($location) . "', NOW(), '" . hesk_dbEscape($stackTrace) . "')");
|
||||||
|
|
||||||
|
$insertedId = hesk_dbInsertID();
|
||||||
|
|
||||||
|
$this->close();
|
||||||
|
|
||||||
|
return $insertedId;
|
||||||
|
}
|
||||||
|
}
|
11
api/DataAccess/Logging/Severity.php
Normal file
11
api/DataAccess/Logging/Severity.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DataAccess\Logging;
|
||||||
|
|
||||||
|
|
||||||
|
class Severity {
|
||||||
|
const DEBUG = 0;
|
||||||
|
const INFO = 1;
|
||||||
|
const WARNING = 2;
|
||||||
|
const ERROR = 3;
|
||||||
|
}
|
@ -29,7 +29,7 @@ function assertApiIsEnabled() {
|
|||||||
$apiChecker = $applicationContext->get[\BusinessLogic\Settings\ApiChecker::class];
|
$apiChecker = $applicationContext->get[\BusinessLogic\Settings\ApiChecker::class];
|
||||||
|
|
||||||
if (!$apiChecker->isApiEnabled($hesk_settings)) {
|
if (!$apiChecker->isApiEnabled($hesk_settings)) {
|
||||||
http_response_code(404);
|
print output(array('message' => 'API Disabled'), 404);
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,18 @@ function errorHandler($errorNumber, $errorMessage, $errorFile, $errorLine) {
|
|||||||
* @param $exception Exception
|
* @param $exception Exception
|
||||||
*/
|
*/
|
||||||
function exceptionHandler($exception) {
|
function exceptionHandler($exception) {
|
||||||
//-- TODO Log an error
|
global $applicationContext, $userContext, $hesk_settings;
|
||||||
|
|
||||||
|
if (strpos($exception->getTraceAsString(), 'LoggingGateway') !== false) {
|
||||||
|
//-- Suppress these for now, as it would cause issues to output two JSONs at one time.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @var $loggingGateway \DataAccess\Logging\LoggingGateway */
|
||||||
|
$loggingGateway = $applicationContext->get[\DataAccess\Logging\LoggingGateway::class];
|
||||||
|
|
||||||
|
// We don't cast API Friendly Exceptions as they're user-generated errors
|
||||||
if (exceptionIsOfType($exception, \BusinessLogic\Exceptions\ApiFriendlyException::class)) {
|
if (exceptionIsOfType($exception, \BusinessLogic\Exceptions\ApiFriendlyException::class)) {
|
||||||
/* @var $castedException \BusinessLogic\Exceptions\ApiFriendlyException */
|
/* @var $castedException \BusinessLogic\Exceptions\ApiFriendlyException */
|
||||||
$castedException = $exception;
|
$castedException = $exception;
|
||||||
@ -62,14 +73,58 @@ function exceptionHandler($exception) {
|
|||||||
} elseif (exceptionIsOfType($exception, \Core\Exceptions\SQLException::class)) {
|
} elseif (exceptionIsOfType($exception, \Core\Exceptions\SQLException::class)) {
|
||||||
/* @var $castedException \Core\Exceptions\SQLException */
|
/* @var $castedException \Core\Exceptions\SQLException */
|
||||||
$castedException = $exception;
|
$castedException = $exception;
|
||||||
print_error("Fought an uncaught SQL exception", sprintf("%s\n\n%s", $castedException->failingQuery, $exception->getTraceAsString()));
|
|
||||||
|
$logId = tryToLog(getLoggingLocation($exception),
|
||||||
|
"Fought an uncaught SQL exception: " . $castedException->failingQuery, $castedException->getTraceAsString(),
|
||||||
|
$userContext, $hesk_settings);
|
||||||
|
|
||||||
|
$logIdText = $logId === null ? "Additionally, the error could not be logged! :'(" : "Log ID: {$logId}";
|
||||||
|
print_error("SQL Exception", "Fought an uncaught SQL exception. Check the logs for more information. {$logIdText}");
|
||||||
} else {
|
} else {
|
||||||
print_error("Fought an uncaught exception of type " . get_class($exception), sprintf("%s\n\n%s", $exception->getMessage(), $exception->getTraceAsString()));
|
$logId = tryToLog(getLoggingLocation($exception),
|
||||||
|
$exception->getMessage(), $exception->getTraceAsString(),
|
||||||
|
$userContext, $hesk_settings);
|
||||||
|
|
||||||
|
$logIdText = $logId === null ? "Additionally, the error could not be logged! :'(" : "Log ID: {$logId}";
|
||||||
|
print_error("Exception Occurred", "Fought an uncaught exception. Check the logs for more information. {$logIdText}");
|
||||||
}
|
}
|
||||||
// Log more stuff to logging table if possible; we'll catch any exceptions from this
|
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $location string
|
||||||
|
* @param $message string
|
||||||
|
* @param $stackTrace string
|
||||||
|
* @param $userContext \BusinessLogic\Security\UserContext
|
||||||
|
* @param $heskSettings array
|
||||||
|
* @return int|null The inserted ID, or null if failed to log
|
||||||
|
* @internal param Exception $exception
|
||||||
|
*/
|
||||||
|
function tryToLog($location, $message, $stackTrace, $userContext, $heskSettings) {
|
||||||
|
global $applicationContext;
|
||||||
|
|
||||||
|
/* @var $loggingGateway \DataAccess\Logging\LoggingGateway */
|
||||||
|
$loggingGateway = $applicationContext->get[\DataAccess\Logging\LoggingGateway::class];
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $loggingGateway->logError($location, $message, $stackTrace, $userContext, $heskSettings);
|
||||||
|
} catch (Exception $squished) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $exception Exception
|
||||||
|
* @return string The location of the exception
|
||||||
|
*/
|
||||||
|
function getLoggingLocation($exception) {
|
||||||
|
// http://stackoverflow.com/a/9133897/1509431
|
||||||
|
$trace = $exception->getTrace();
|
||||||
|
$lastCall = $trace[0];
|
||||||
|
return basename($lastCall['file'], '.php');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $exception Exception thrown exception
|
* @param $exception Exception thrown exception
|
||||||
* @param $class string The name of the expected exception type
|
* @param $class string The name of the expected exception type
|
||||||
|
@ -958,4 +958,11 @@ function execute303Scripts() {
|
|||||||
hesk_dbConnect();
|
hesk_dbConnect();
|
||||||
|
|
||||||
updateVersion('3.0.3');
|
updateVersion('3.0.3');
|
||||||
|
}
|
||||||
|
|
||||||
|
function execute310Scripts() {
|
||||||
|
global $hesk_settings;
|
||||||
|
hesk_dbConnect();
|
||||||
|
|
||||||
|
executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "logging` ADD COLUMN `stack_trace` TEXT");
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user