MDConsole/src/MDOutputHandler.php

180 lines
4.9 KiB
PHP

<?PHP
/**
* This file offers a class for handling outputs and logging.
*
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
*/
/**
* Class for handling outputs and logs for museum-digital's background tools.
*/
class MDOutputHandler {
/*
* Variables
*/
/** @var integer */
private $_verbosity;
/** @var string */
private $_context;
/** @var string */
private $_logfile;
/** @var integer */
private $_counter;
/** @var boolean */
private $_file_logging;
/** @var float */
private $_startTime;
/**
* Function human_filesize translates byte-level filesizes to human readable ones.
* Thanks to Jeffrey Sambells http://jeffreysambells.com/2012/10/25/human-readable-filesize-php
*
* @param integer $bytes A file size, e.g. returned from filesize().
* @param integer $decimals Number of decimal digits to allow.
*
* @return string
*/
final private function _human_filesize(int $bytes, int $decimals = 2):string {
$size = ['B','kB','MB','GB','TB','PB','EB','ZB','YB'];
$factor = floor((strlen((string)$bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . $size[$factor];
}
/**
* Setter function for the verbosity option.
*
* @param integer $input New value of boolean value verbosity.
*
* @return void
*/
final public function setVerbosity(int $input = 0):void {
$this->_verbosity = $input;
}
/**
* Setter function for the additional context description.
*
* @param string $input New value.
*
* @return void
*/
final public function setContext(string $input = ""):void {
$this->_context = $input;
}
/**
* Setter function for file logging.
*
* @param boolean $input New value.
*
* @return void
*/
final public function setFileLogging(bool $input = false):void {
$this->_file_logging = $input;
if ($this->_file_logging === true) {
if (!is_dir(__DIR__ . "/../logs")) mkdir(__DIR__ . "/../logs", 0755);
touch($this->_logfile);
}
}
/**
* Main function of this class.
* Formats a message uniformly and writes it to the log, maybe also to stdout.
*
* @param string $msg Message to log.
* @param integer $statusCode Status code.
* 0: Note
* 1: Skipped
* 2: Update
* 3: Error.
*
* @return void
*/
final public function toLog(string $msg, int $statusCode = 0):void {
// Get parts for generating the message to log.
$this->_counter++; // Increment counter
$date = date("Y-m-d H:i:s"); // Get current date & time.
switch ($statusCode) {
case MDConsole::STATUS_SKIPPED:
$statusSymbol = "-";
break;
case MDConsole::STATUS_UPDATE:
$statusSymbol = "U";
break;
case MDConsole::STATUS_ERROR:
$statusSymbol = "E";
break;
case MDConsole::STATUS_DELETION:
$statusSymbol = "D";
break;
case MDConsole::STATUS_NOTICE:
default:
$statusSymbol = "N";
break;
}
if (!empty($this->_context)) $contextStr = "{$this->_context}";
else $contextStr = "";
// Generate the message to log.
$message = "$statusSymbol{$contextStr}#" . sprintf("%1$07s", $this->_counter) . "" . sprintf("%1$7s", $this->_human_filesize(memory_get_usage())) . "{$date}{$msg}" . PHP_EOL;
if ($this->_file_logging === true) {
file_put_contents($this->_logfile, $message, FILE_APPEND);
}
if (($this->_verbosity > 0 && in_array($statusCode, [MDConsole::STATUS_UPDATE, MDConsole::STATUS_DELETION, MDConsole::STATUS_ERROR])) || $this->_verbosity === 2) echo $message;
if ($this->_counter % 250 === 0) {
echo '―――> ' . sprintf("%1$07d", $this->_counter) . " operations processed" . PHP_EOL;
echo str_replace("_", "", sprintf("%'_80s", "_")) . PHP_EOL;
}
}
/**
* Constructor function that sets defaults and ensures the logfile exists.
*/
public function __construct() {
$this->_startTime = microtime(true);
$this->_counter = 0;
$this->setVerbosity();
$this->setContext();
$this->setFileLogging();
$this->_logfile = __DIR__ . "/../logs/" . date("Ymd_His") . ".txt";
// Ensure the log directory exists
$this->toLog("Activated logger.");
}
/**
* Destructor.
*
* @return void
*/
function __destruct() {
$endtime = microtime(true);
$this->toLog("Finished operation. Processing duration: " . strval($endtime - $this->_startTime));
}
}