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\VerifiedEmailChecker;
|
||||
use DataAccess\Categories\CategoryGateway;
|
||||
use DataAccess\Logging\LoggingGateway;
|
||||
use DataAccess\Security\BanGateway;
|
||||
use DataAccess\Security\UserGateway;
|
||||
use DataAccess\Settings\ModsForHeskSettingsGateway;
|
||||
@ -38,6 +39,9 @@ class ApplicationContext {
|
||||
// API Checker
|
||||
$this->get[ApiChecker::class] = new ApiChecker($this->get[ModsForHeskSettingsGateway::class]);
|
||||
|
||||
// Logging
|
||||
$this->get[LoggingGateway::class] = new LoggingGateway();
|
||||
|
||||
// Verified Email Checker
|
||||
$this->get[VerifiedEmailGateway::class] = new VerifiedEmailGateway();
|
||||
$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];
|
||||
|
||||
if (!$apiChecker->isApiEnabled($hesk_settings)) {
|
||||
http_response_code(404);
|
||||
print output(array('message' => 'API Disabled'), 404);
|
||||
die();
|
||||
}
|
||||
|
||||
@ -53,7 +53,18 @@ function errorHandler($errorNumber, $errorMessage, $errorFile, $errorLine) {
|
||||
* @param $exception 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)) {
|
||||
/* @var $castedException \BusinessLogic\Exceptions\ApiFriendlyException */
|
||||
$castedException = $exception;
|
||||
@ -62,14 +73,58 @@ function exceptionHandler($exception) {
|
||||
} elseif (exceptionIsOfType($exception, \Core\Exceptions\SQLException::class)) {
|
||||
/* @var $castedException \Core\Exceptions\SQLException */
|
||||
$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 {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 $class string The name of the expected exception type
|
||||
|
@ -958,4 +958,11 @@ function execute303Scripts() {
|
||||
hesk_dbConnect();
|
||||
|
||||
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