/** * The logger should implement this method to perform the actual log committal. * * @param int $level The log level * @param string $message The text message to log * @param string $category The category of log message * @param array $additionalData Any number of additional key value pairs which can be understood by specific * logs (e.g. an API log might understand what AuthenticationToken means) * @return mixed */ protected function writeFormattedEntry($level, $message, $category = "", $additionalData) { // There are a number of occasions where this method can cause an infinite loop: // // 1) Writing a database entry could cause PDO log entries to be generated // 2) If any of the following lines should through warnings or notices AND these are set to report // through this logger. // // For this reason we ask the log framework to suspend logging until this method is complete. Log::disableLogging(); $logEntryModelClassName = $this->logEntryModelClassName; /** @var RhubarbLogEntry $logEntry */ $logEntry = new $logEntryModelClassName(); $logEntry->Level = $level; $logEntry->LogSession = $this->uniqueIdentifier; $logEntry->IpAddress = self::getRemoteIP(); $logEntry->Category = $category == "" ? "CORE" : $category; $logEntry->EntryDate = "now"; $logEntry->ExecutionTime = $this->getExecutionTime(); $logEntry->ExecutionGapTime = $this->getTimeSinceLastLog(); $logEntry->Message = $message; $logEntry->Request = isset($_SERVER["SCRIPT_URI"]) ? $_SERVER["SCRIPT_URI"] : ''; $logEntry->Host = isset($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : ''; $logEntry->ScriptName = isset($_SERVER["SCRIPT_NAME"]) ? $_SERVER["SCRIPT_NAME"] : ''; if (is_array($additionalData) || is_object($additionalData)) { $additionalData = json_encode($additionalData, JSON_PRETTY_PRINT); } $logEntry->AdditionalData = $additionalData; $logEntry->save(); Log::enableLogging(); }
public function testLogCanHaveCustomFilter() { global $logFilter; Log::error("This is a test we should not see", "ignore"); $this->assertCount(0, $this->log->entries); $logFilter = true; Log::error("This is a test we should not see", "test"); $this->assertCount(0, $this->log->entries); }
public static function setUpBeforeClass() { parent::setUpBeforeClass(); Module::registerModule(new UnitTestExceptionModule()); Module::initialiseModules(); Log::clearLogs(); Log::attachLog(self::$log = new UnitTestLog(Log::ERROR_LEVEL)); ExceptionHandler::enableExceptionTrapping(); }
public function send(Sendable $email) { $recipientList = $email->getRecipientList(); Log::debug("Sending message to " . $recipientList, "EMAIL"); mail($recipientList, $email->getSubject(), $email->getBodyRaw(), $email->getMailHeadersAsString(), "-f" . $email->getSender()->email); Log::indent(); Log::debug("Sent message to " . $recipientList, "EMAIL"); Log::outdent(); }
protected function setUp() { parent::setUp(); $this->application = new Application(); $this->application->registerModule(new UnitTestingModule()); $this->application->registerModule(new UnitTestExceptionModule()); $this->application->initialiseModules(); Log::clearLogs(); Log::attachLog(self::$log = new UnitTestLog(Log::ERROR_LEVEL)); ExceptionHandler::enableExceptionTrapping(); }
public static function setUpBeforeClass() { parent::setUpBeforeClass(); Repository::setDefaultRepositoryClassName(MySql::class); self::SetDefaultConnectionSettings(); Log::DisableLogging(); $unitTestingSolutionSchema = new UnitTestingSolutionSchema(); $unitTestingSolutionSchema->checkModelSchemas(); // Make sure the test model objects have the any other repository disconnected. Model::deleteRepositories(); }
protected function shouldLog($category) { global $logFilter; // Yes, it's a global - it's a unit test. Get over it. if ($category == "ignore") { return false; } if (isset($logFilter) && $logFilter) { return false; } return parent::shouldLog($category); }
private static final function sendItem(CommunicationItem $item) { if ($item->Sent) { Log::warning("Attempt blocked to send already sent email", "COMMS", ["CommunicationItemID" => $item->CommunicationItemID, "EmailProvider" => self::$emailProviderClassName]); return true; } $sendable = $item->getSendable(); $providerClass = $sendable->getProviderClassName(); $provider = self::getContainer()->getInstance($providerClass); if ($provider instanceof CaptureToCommunicationsProcessorInterface) { throw new InvalidProviderException(); } try { $provider->send($sendable); $item->markSent(); } catch (\Exception $exception) { $item->Status = CommunicationItem::STATUS_FAILED; } $item->markSent(); $item->save(); Log::debug("Sending communication by Email", "COMMS", ["CommunicationID" => $item->CommunicationID, "EmailProvider" => self::$emailProviderClassName]); return $item->Status == CommunicationItem::STATUS_SENT; }
public function testMessageIsIndented() { Log::indent(); Log::debug("Indented Message", "test"); $this->assertEquals(" Indented Message", $this->log->entries[0][0]); }
public function __construct($logLevel, Logger $logger) { parent::__construct($logLevel); $this->logger = $logger; }
<?php namespace Your\WebApp; use Rhubarb\Crown\Context; use Rhubarb\Crown\Exceptions\Handlers\ExceptionHandler; use Rhubarb\Crown\Logging\Log; use Rhubarb\Crown\Logging\PhpLog; use Rhubarb\Stem\StemSettings; $dbSettings = new StemSettings(); $dbSettings->Host = "localhost"; $dbSettings->Username = "******"; $dbSettings->Password = ""; $dbSettings->Database = "ogredb"; // Add a PHP logger Log::attachLog(new PhpLog(Log::ALL)); $con = new Context(); $con->DeveloperMode = true; // Switch off exception trapping. You should have this on in the production environment. ExceptionHandler::disableExceptionTrapping();
<?php namespace Project\Liberty; use Rhubarb\Crown\Context; use Rhubarb\Crown\Exceptions\Handlers\ExceptionHandler; use Rhubarb\Crown\Logging\Log; use Rhubarb\Crown\Logging\PhpLog; use Rhubarb\Stem\StemSettings; $dbSettings = new StemSettings(); $dbSettings->Host = "localhost"; $dbSettings->Username = "******"; $dbSettings->Password = ""; $dbSettings->Database = "vagrant"; $set = new Context(); $set->DeveloperMode = true; // Add a PHP logger Log::attachLog(new PhpLog(Log::ERROR_LEVEL)); ExceptionHandler::disableExceptionTrapping();
/** * Executes the statement with any supplied named parameters on the connection provided. * * If no connection is provided the default connection will be used. * * @param $statement * @param array $namedParameters * @param \PDO $connection * @param bool $isInsertQuery True if the query is an insert and the ID should be returned * @throws \Rhubarb\Stem\Exceptions\RepositoryStatementException * @return \PDOStatement */ public static function executeStatement($statement, $namedParameters = [], $connection = null, $isInsertQuery = false) { if ($connection === null) { $connection = static::getDefaultConnection(); } self::$secondLastStatement = self::$lastStatement; self::$lastStatement = $statement; self::$lastParams = $namedParameters; $pdoStatement = $connection->prepare($statement); Log::CreateEntry(Log::PERFORMANCE_LEVEL | Log::REPOSITORY_LEVEL, function () use($statement, $namedParameters, $connection) { $newStatement = $statement; array_walk($namedParameters, function ($value, $key) use(&$newStatement, &$params, $connection) { // Note this is not attempting to make secure queries - this is purely illustrative for the logs // However we do at least do addslashes so if you want to cut and paste a query from the log to // try it - it should work in most cases. $newStatement = str_replace(':' . $key, $connection->quote($value), $newStatement); }); return "Executing PDO statement " . $newStatement; }, "PDO"); if (!$pdoStatement->execute($namedParameters)) { $error = $pdoStatement->errorInfo(); throw new RepositoryStatementException($error[2], $statement); } if ($isInsertQuery) { $pdoStatement = $connection->lastInsertId(); } Log::CreateEntry(Log::PERFORMANCE_LEVEL | Log::REPOSITORY_LEVEL, "Statement successful", "PDO"); return $pdoStatement; }
public function send() { $subject = $this->getSubject(); $html = $this->getHtml(); $text = $this->getText(); Log::Debug("Sending email `" . $subject . "` to recipients: " . $this->getRecipientList(), "EMAIL"); Log::BulkData("Email content", "EMAIL", $this->getMailHeadersAsString() . "\r\n\r\n" . ($html != "") ? $html : $text); $emailProvider = EmailProvider::getDefaultEmailProvider(); $emailProvider->sendEmail($this); }
/** * Return the response when appropriate or false if no response could be generated. * * If child handlers are present they are given priority. * * @param mixed $request * @param bool|string $currentUrlFragment * @return bool|Response */ public function generateResponse($request = null, $currentUrlFragment = false) { if ($currentUrlFragment === false) { $currentUrlFragment = $request->urlPath; } if (!$this->matchesRequest($request, $currentUrlFragment)) { return false; } UrlHandler::setExecutingUrlHandler($this); Log::debug(function () { return "Handler " . get_class($this) . " selected to generate response"; }, "ROUTER"); Log::indent(); $context = new PhpContext(); $context->UrlHandler = $this; $this->matchingUrl = $this->getMatchingUrlFragment($request, $currentUrlFragment); if ($this->parentHandler) { $this->handledUrl = $this->parentHandler->handledUrl . $this->matchingUrl; } else { $this->handledUrl = $this->matchingUrl; } $childUrlFragment = substr($currentUrlFragment, strlen($this->matchingUrl)); foreach ($this->childUrlHandlers as $childHandler) { $response = $childHandler->generateResponse($request, $childUrlFragment); if ($response !== false) { return $response; } } $response = $this->generateResponseForRequest($request, $currentUrlFragment); Log::debug(function () use($response) { if ($response !== false) { return "Response generated by handler"; } return "Handler deferred generation"; }, "ROUTER"); Log::outdent(); return $response; }
protected function logException(RhubarbException $er) { Log::error("Unhandled " . basename(get_class($er)) . " `" . $er->getMessage() . "` in line " . $er->getLine() . " in " . $er->getFile(), "ERROR", $er); }
/** * Generates the response content for the client. * * This is normally called by platform/execute-http.php and must be called after all * modules have been registered to guarantee the correct output. * * @static * @param Request $request * @return string|Response */ public final function generateResponseForRequest(Request $request) { $this->setAsRunningApplication(); $this->request = $request; $this->activeRequest = $request; $additionalData = []; if ($request instanceof WebRequest) { if (!empty($request->GetData)) { $additionalData = $request->GetData; } } Log::createEntry(Log::PERFORMANCE_LEVEL | Log::DEBUG_LEVEL, function () use($request) { if ($request instanceof WebRequest) { return "Generating response for url " . $request->urlPath; } if ($request instanceof CliRequest) { return "Starting CLI response"; } return ""; }, "ROUTER", $additionalData); Log::indent(); // an empty-string Response to fall back on if nothing else is generated $response = new HtmlResponse(); $response->setContent(''); $filterResponse = true; try { // Iterate over each handler and ask them to generate a response. // If they do return a response we return that and exit the loop. // If they return false then we assume they couldn't handle the URL // and continue to the next handler. foreach ($this->rootHandlers as $handler) { $generatedResponse = $handler->generateResponse($request); if ($generatedResponse !== false) { Log::debug(function () use($handler) { return ["Handler `" . get_class($handler) . "` generated response.", []]; }, "ROUTER"); // it should be preferred for a handler to return a Response object, // but checking this here retains the option for them to just return // their output if ($generatedResponse instanceof Response) { $response = $generatedResponse; } else { $response->setContent($generatedResponse); } break; } } } catch (ForceResponseException $er) { // Clear any previous output in buffers to ensure we only send the forced response while (ob_get_level()) { ob_end_clean(); } $response = $er->getResponse(); $filterResponse = false; } catch (StopGeneratingResponseException $er) { $filterResponse = false; } catch (RhubarbException $er) { $handler = $this->container()->getInstance(ExceptionHandler::class); $response = $handler->processException($er); } catch (\Exception $er) { $handler = $this->container()->getInstance(ExceptionHandler::class); $response = $handler->processException(new NonRhubarbException($er)); } if ($filterResponse) { Log::createEntry(Log::PERFORMANCE_LEVEL | Log::DEBUG_LEVEL, "Output filters started", "ROUTER"); Log::indent(); $filters = $this->getAllResponseFilters(); foreach ($filters as $filter) { $response = $filter->processResponse($response); } Log::createEntry(Log::PERFORMANCE_LEVEL | Log::DEBUG_LEVEL, "Output filters finished", "ROUTER"); Log::outdent(); } Log::performance("Response generated", "ROUTER"); Log::outdent(); return $response; }
* limitations under the License. */ /** * execute-http.php is the entry point for all HTTP requests for Rhubarb applications. * The only exceptions to this are when webserver URL rewriting goes directly to * a resource for performance reasons, e.g. accessing static content like images * and CSS files. */ use Rhubarb\Crown\Logging\Log; use Rhubarb\Crown\Module; // Change the working directory to the top level project folder. chdir(__DIR__ . "/../../../../"); // Initiate our bootstrap script to boot all libraries required. require_once __DIR__ . "/boot.php"; require_once __DIR__ . "/../src/Module.php"; require_once __DIR__ . "/../src/Context.php"; $request = \Rhubarb\Crown\Context::currentRequest(); try { // Pass control to the Module class and ask it to generate a response for the // incoming request. $response = Module::generateResponseForRequest($request); $response->send(); } catch (\Exception $er) { $context = new \Rhubarb\Crown\Context(); if ($context->DeveloperMode) { Log::error($er->getMessage(), "ERROR"); print "<pre>Exception: " . get_class($er) . "\nMessage: " . $er->getMessage() . "\nStack Trace:\n" . $er->getTraceAsString(); } } Log::debug("Request Complete", "ROUTER");
/** * Generates the response content for the client. * * This is normally called by platform/execute-http.php and must be called after all * modules have been registered to guarantee the correct output. * * @static * @param Request\Request $request * @return string */ public static function generateResponseForRequest(Request\Request $request) { // Set the current request to be this one. $context = new Context(); $context->Request = $request; $additionalData = []; if ($request instanceof WebRequest) { if (!empty($request->GetData)) { $additionalData = $request->GetData; } } Log::createEntry(Log::PERFORMANCE_LEVEL | Log::DEBUG_LEVEL, function () use($request) { if ($request instanceof WebRequest) { return "Generating response for url " . $request->UrlPath; } if ($request instanceof CliRequest) { return "Starting CLI response"; } return ""; }, "ROUTER", $additionalData); Log::indent(); $handlers = self::getAllUrlHandlers(); // an empty-string Response to fall back on if nothing else is generated $response = new HtmlResponse(); $response->SetContent(''); $filterResponse = true; try { // Iterate over each handler and ask them to generate a response. // If they do return a response we return that and exit the loop. // If they return false then we assume they couldn't handle the URL // and continue to the next handler. foreach ($handlers as $handler) { $generatedResponse = $handler->generateResponse($request); if ($generatedResponse !== false) { Log::Debug(function () use($handler) { return ["Handler `" . get_class($handler) . "` generated response.", []]; }, "ROUTER"); // it should be preferred for a handler to return a Response object, // but checking this here retains the option for them to just return // their output if ($generatedResponse instanceof Response) { $response = $generatedResponse; } else { $response->setContent($generatedResponse); } break; } } } catch (ForceResponseException $er) { $response = $er->getResponse(); $filterResponse = false; } catch (StopGeneratingResponseException $er) { $filterResponse = false; } catch (RhubarbException $er) { $response = ExceptionHandler::processException($er); } catch (\Exception $er) { $response = ExceptionHandler::processException(new NonRhubarbException($er)); } if ($filterResponse) { Log::createEntry(Log::PERFORMANCE_LEVEL | Log::DEBUG_LEVEL, "Output filters started", "ROUTER"); Log::indent(); $filters = self::getAllResponseFilters(); foreach ($filters as $filter) { $response = $filter->processResponse($response); } Log::createEntry(Log::PERFORMANCE_LEVEL | Log::DEBUG_LEVEL, "Output filters finished", "ROUTER"); Log::outdent(); } Log::performance("Response generated", "ROUTER"); Log::outdent(); return $response; }
protected function logSending() { $subject = $this->getSubject(); $html = $this->getHtml(); $text = $this->getText(); Log::debug("Sending email `" . $subject . "` to recipients: " . $this->getRecipientList(), "EMAIL"); Log::bulkData("Email content", "EMAIL", $this->getMailHeadersAsString() . "\r\n\r\n" . ($html != "") ? $html : $text); }