mirror of
https://github.com/processwire/processwire.git
synced 2025-08-08 07:47:00 +02:00
Various improvements to FileLog and WireLog classes. Plus add new deleteAll() and pruneAll() methods to WireLog class.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* Creates and maintains a text-based log file.
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* ProcessWire 3.x, Copyright 2023 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
*/
|
||||
@@ -89,6 +89,7 @@ class FileLog extends Wire {
|
||||
*
|
||||
*/
|
||||
public function __construct($path, $identifier = '') {
|
||||
parent::__construct();
|
||||
|
||||
if($identifier) {
|
||||
$path = rtrim($path, '/') . '/';
|
||||
@@ -98,19 +99,32 @@ class FileLog extends Wire {
|
||||
$path = dirname($path) . '/';
|
||||
}
|
||||
$this->path = $path;
|
||||
if(!is_dir($path)) $this->wire('files')->mkdir($path);
|
||||
}
|
||||
|
||||
public function __get($key) {
|
||||
if($key == 'delimiter') return $this->delimeter; // @todo learn how to spell
|
||||
return parent::__get($key);
|
||||
|
||||
/**
|
||||
* Wired to API
|
||||
*
|
||||
*/
|
||||
public function wired() {
|
||||
parent::wired();
|
||||
$this->path();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*
|
||||
*/
|
||||
public function __get($name) {
|
||||
if($name == 'delimiter') return $this->delimeter; // @todo learn how to spell
|
||||
return parent::__get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean a string for use in a log file entry
|
||||
*
|
||||
* @param $str
|
||||
* @return mixed|string
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
protected function cleanStr($str) {
|
||||
@@ -219,7 +233,7 @@ class FileLog extends Wire {
|
||||
|
||||
// if we were creating the file, make sure it has the right permission
|
||||
if($mode === 'w') {
|
||||
$files = $this->wire('files'); /** @var WireFileTools $files */
|
||||
$files = $this->wire()->files;
|
||||
$files->chmod($this->logFilename);
|
||||
}
|
||||
|
||||
@@ -271,18 +285,42 @@ class FileLog extends Wire {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filesize
|
||||
*
|
||||
* @return int|false
|
||||
*
|
||||
*/
|
||||
public function size() {
|
||||
return filesize($this->logFilename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file basename
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function filename() {
|
||||
return basename($this->logFilename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file pathname
|
||||
*
|
||||
* @return string|bool
|
||||
*
|
||||
*/
|
||||
public function pathname() {
|
||||
return $this->logFilename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file modification time
|
||||
*
|
||||
* @return int|false
|
||||
*
|
||||
*/
|
||||
public function mtime() {
|
||||
return filemtime($this->logFilename);
|
||||
}
|
||||
@@ -483,7 +521,7 @@ class FileLog extends Wire {
|
||||
}
|
||||
|
||||
if($options['toFile']) {
|
||||
$toFile = $this->path . basename($options['toFile']);
|
||||
$toFile = $this->path() . basename($options['toFile']);
|
||||
$fp = fopen($toFile, 'w');
|
||||
if(!$fp) throw new \Exception("Unable to open file for writing: $toFile");
|
||||
} else {
|
||||
@@ -536,7 +574,7 @@ class FileLog extends Wire {
|
||||
|
||||
if($fp) {
|
||||
fclose($fp);
|
||||
$this->wire('files')->chmod($toFile);
|
||||
$this->wire()->files->chmod($toFile);
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
@@ -553,8 +591,7 @@ class FileLog extends Wire {
|
||||
* @param $line
|
||||
* @param array $options
|
||||
* @param bool $stopNow Populates this with true when it can determine no more lines are necessary.
|
||||
* @return bool|int Returns boolean true if valid, false if not.
|
||||
* If valid as a result of a date comparison, the unix timestmap for the line is returned.
|
||||
* @return bool Returns boolean true if valid, false if not.
|
||||
*
|
||||
*/
|
||||
protected function isValidLine($line, array $options, &$stopNow) {
|
||||
@@ -623,13 +660,15 @@ class FileLog extends Wire {
|
||||
|
||||
fclose($fpw);
|
||||
fclose($fpr);
|
||||
|
||||
$files = $this->wire()->files;
|
||||
|
||||
if($cnt) {
|
||||
$this->wire('files')->unlink($filename, true);
|
||||
$this->wire('files')->rename("$filename.new", $filename, true);
|
||||
$this->wire('files')->chmod($filename);
|
||||
$files->unlink($filename, true);
|
||||
$files->rename("$filename.new", $filename, true);
|
||||
$files->chmod($filename);
|
||||
} else {
|
||||
$this->wire('files')->unlink("$filename.new", true);
|
||||
$files->unlink("$filename.new", true);
|
||||
}
|
||||
|
||||
return $cnt;
|
||||
@@ -651,8 +690,9 @@ class FileLog extends Wire {
|
||||
'dateTo' => time(),
|
||||
));
|
||||
if(file_exists($toFile)) {
|
||||
$this->wire('files')->unlink($this->logFilename, true);
|
||||
$this->wire('files')->rename($toFile, $this->logFilename, true);
|
||||
$files = $this->wire()->files;
|
||||
$files->unlink($this->logFilename, true);
|
||||
$files->rename($toFile, $this->logFilename, true);
|
||||
return $qty;
|
||||
}
|
||||
return 0;
|
||||
@@ -665,7 +705,7 @@ class FileLog extends Wire {
|
||||
*
|
||||
*/
|
||||
public function delete() {
|
||||
return $this->wire('files')->unlink($this->logFilename, true);
|
||||
return $this->wire()->files->unlink($this->logFilename, true);
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
@@ -704,6 +744,16 @@ class FileLog extends Wire {
|
||||
if($chunkSize > 0) $this->chunkSize = (int) $chunkSize;
|
||||
return $this->chunkSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path where the log is stored (with trailing slash)
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function path() {
|
||||
if(!is_dir($this->path)) $this->wire()->files->mkdir($this->path);
|
||||
return $this->path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* #pw-summary Enables creation of logs, logging of events, and management of logs.
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2019 by Ryan Cramer
|
||||
* ProcessWire 3.x, Copyright 2023 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* @method bool save($name, $text, $options = array())
|
||||
@@ -139,14 +139,15 @@ class WireLog extends Wire {
|
||||
if($options['url']) {
|
||||
$url = $options['url'];
|
||||
} else {
|
||||
$input = $this->wire('input');
|
||||
$input = $this->wire()->input;
|
||||
$sanitizer = $this->wire()->sanitizer;
|
||||
$url = $input ? $input->httpUrl() : '';
|
||||
if(strlen($url) && $input) {
|
||||
if(count($input->get)) {
|
||||
$url .= "?";
|
||||
foreach($input->get as $k => $v) {
|
||||
$k = $this->wire('sanitizer')->name($k);
|
||||
$v = $this->wire('sanitizer')->name($v);
|
||||
$k = $sanitizer->name($k);
|
||||
$v = $sanitizer->name($v);
|
||||
$url .= "$k=$v&";
|
||||
}
|
||||
$url = rtrim($url, "&");
|
||||
@@ -201,7 +202,8 @@ class WireLog extends Wire {
|
||||
/**
|
||||
* Return array of all logs, sorted by name
|
||||
*
|
||||
* Each log entry is an array that includes the following:
|
||||
* Each item in returned array is an associative array that includes the following:
|
||||
*
|
||||
* - `name` (string): Name of log file, excluding extension.
|
||||
* - `file` (string): Full path and filename of log file.
|
||||
* - `size` (int): Size in bytes
|
||||
@@ -216,13 +218,8 @@ class WireLog extends Wire {
|
||||
public function getLogs($sortNewest = false) {
|
||||
|
||||
$logs = array();
|
||||
$dir = new \DirectoryIterator($this->wire('config')->paths->logs);
|
||||
|
||||
foreach($dir as $file) {
|
||||
if($file->isDot() || $file->isDir()) continue;
|
||||
if($file->getExtension() != $this->logExtension) continue;
|
||||
$name = basename($file, '.' . $this->logExtension);
|
||||
if($name != $this->wire('sanitizer')->pageName($name)) continue;
|
||||
foreach($this->getFiles() as $name => $file) {
|
||||
|
||||
if($sortNewest) {
|
||||
$sortKey = $file->getMTime();
|
||||
@@ -245,7 +242,7 @@ class WireLog extends Wire {
|
||||
ksort($logs);
|
||||
}
|
||||
|
||||
return $logs;
|
||||
return array_values($logs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,10 +257,37 @@ class WireLog extends Wire {
|
||||
*/
|
||||
public function getFilename($name) {
|
||||
$name = strtolower($name);
|
||||
if($name !== $this->wire('sanitizer')->pageName($name)) {
|
||||
if($name !== $this->wire()->sanitizer->pageName($name)) {
|
||||
throw new WireException("Log name must contain only [-_.a-z0-9] with no extension");
|
||||
}
|
||||
return $this->wire('config')->paths->logs . $name . '.' . $this->logExtension;
|
||||
return $this->path() . $name . '.' . $this->logExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SplFileInfo objects for each log file indexed by log name
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @return \SplFileInfo[]
|
||||
* @throws WireException
|
||||
* @since 3.0.214
|
||||
*
|
||||
*/
|
||||
public function getFiles() {
|
||||
|
||||
$dir = new \DirectoryIterator($this->path());
|
||||
$sanitizer = $this->wire()->sanitizer;
|
||||
$files = array();
|
||||
|
||||
foreach($dir as $file) {
|
||||
if($file->isDot() || $file->isDir()) continue;
|
||||
if($file->getExtension() != $this->logExtension) continue;
|
||||
$name = $file->getBasename(".$this->logExtension");
|
||||
if($name != $sanitizer->pageName($name)) continue;
|
||||
$files[$name] = $file;
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -299,7 +323,7 @@ class WireLog extends Wire {
|
||||
*
|
||||
*/
|
||||
public function getLines($name, array $options = array()) {
|
||||
$pageNum = !empty($options['pageNum']) ? $options['pageNum'] : $this->wire('input')->pageNum;
|
||||
$pageNum = !empty($options['pageNum']) ? $options['pageNum'] : $this->wire()->input->pageNum;
|
||||
unset($options['pageNum']);
|
||||
$log = $this->getFileLog($name);
|
||||
$limit = isset($options['limit']) ? (int) $options['limit'] : 100;
|
||||
@@ -334,7 +358,7 @@ class WireLog extends Wire {
|
||||
|
||||
$log = $this->getFileLog($name);
|
||||
$limit = isset($options['limit']) ? $options['limit'] : 100;
|
||||
$pageNum = !empty($options['pageNum']) ? $options['pageNum'] : $this->wire('input')->pageNum;
|
||||
$pageNum = !empty($options['pageNum']) ? $options['pageNum'] : $this->wire()->input->pageNum;
|
||||
unset($options['pageNum']);
|
||||
$lines = $log->find($limit, $pageNum, $options);
|
||||
|
||||
@@ -446,7 +470,7 @@ class WireLog extends Wire {
|
||||
*/
|
||||
public function getDate($name, $dateFrom, $dateTo = 0, $limit = 100) {
|
||||
$log = $this->getFileLog($name);
|
||||
$pageNum = $this->wire('input')->pageNum();
|
||||
$pageNum = $this->wire()->input->pageNum();
|
||||
return $log->getDate($dateFrom, $dateTo, $pageNum, $limit);
|
||||
}
|
||||
|
||||
@@ -466,6 +490,35 @@ class WireLog extends Wire {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all log files
|
||||
*
|
||||
* @param bool $throw Throw WireException if any delete fails? (default=false)
|
||||
* @return array Basenames of deleted log files
|
||||
* @since 3.0.214
|
||||
*
|
||||
*/
|
||||
public function deleteAll($throw = false) {
|
||||
|
||||
$deleted = array();
|
||||
$failed = array();
|
||||
|
||||
foreach($this->getFiles() as $name => $file) {
|
||||
$log = $this->getFileLog($name);
|
||||
if($log && $log->delete()) {
|
||||
$deleted[] = $name;
|
||||
} else {
|
||||
$failed[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
if($throw && count($failed)) {
|
||||
throw new WireException("Failed to delete logs: " . implode(', ', $failed));
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prune log file to contain only entries from last [n] days
|
||||
*
|
||||
@@ -473,7 +526,7 @@ class WireLog extends Wire {
|
||||
*
|
||||
* @param string $name Name of log file, excluding path and extension.
|
||||
* @param int $days Number of days
|
||||
* @return int Number of items in new log file or boolean false on failure
|
||||
* @return int Number of items in newly pruned log file or boolean false on failure
|
||||
* @throws WireException
|
||||
*
|
||||
*/
|
||||
@@ -485,6 +538,22 @@ class WireLog extends Wire {
|
||||
return $log->pruneDate($oldestDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prune all log files to given number of days
|
||||
*
|
||||
* @param int $days
|
||||
* @return array
|
||||
* @since 3.0.214
|
||||
*
|
||||
*/
|
||||
public function pruneAll($days) {
|
||||
$result = array();
|
||||
foreach($this->getFiles() as $name => $filename) {
|
||||
$result[$name] = $this->prune($name, $days);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns instance of FileLog for given log name
|
||||
*
|
||||
@@ -500,6 +569,7 @@ class WireLog extends Wire {
|
||||
$filename = $this->getFilename($name);
|
||||
$key = "$filename$delimiter";
|
||||
if(isset($this->fileLogs[$key])) return $this->fileLogs[$key];
|
||||
/** @var FileLog $log */
|
||||
$log = $this->wire(new FileLog($filename));
|
||||
$log->setDelimiter($delimiter);
|
||||
$this->fileLogs[$key] = $log;
|
||||
@@ -534,4 +604,14 @@ class WireLog extends Wire {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return disk path to log files
|
||||
*
|
||||
* @return string
|
||||
* @since 3.0.214
|
||||
*
|
||||
*/
|
||||
public function path() {
|
||||
return $this->wire()->config->paths->logs;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user