Files
ave-cms-alt/class/class.logs.php

351 lines
9.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* AVE.cms
*
* Класс, предназначенный для управления журналом системных сообщений
* (Оптимизировано чтение для больших файлов логов)
*
* @package AVE.cms
* @version 4.x
* @filesource
* @copyright © 2007-2014 AVE.cms, http://www.ave-cms.ru
*
*/
class AVE_Logs
{
/**
* Свойства класса
*/
/**
* Файлы для хранения записей
*
* @public
*/
public $_404dir = '/tmp/logs/404.csv';
public $_logdir = '/tmp/logs/log.csv';
public $_sqldir = '/tmp/logs/sql.csv';
/**
* Внутренние методы класса
*/
/**
* Вспомогательный метод для чтения последних строк файла с конца
*
* @param string $file_name Путь к файлу
* @param int $_count Количество строк, которые нужно прочитать
* @param int $chunk_size Размер блока для чтения
* @return array Массив строк в прямом хронологическом порядке
*/
private function readLastLines($file_name, $_count, $chunk_size = 8192)
{
if (!file_exists($file_name) || !($fp = @fopen($file_name, 'rb'))) {
return [];
}
$file_size = @filesize($file_name);
$pos = $file_size;
$buffer = '';
$raw_lines = [];
// Чтение файла блоками с конца
while ($pos > 0 && count($raw_lines) < $_count) {
$bytes_to_read = min($chunk_size, $pos);
$pos -= $bytes_to_read;
fseek($fp, $pos);
$chunk = fread($fp, $bytes_to_read);
$buffer = $chunk . $buffer;
if ($pos == 0) {
$lines = explode("\n", $buffer);
$buffer = '';
} else {
$lines = explode("\n", $buffer);
$buffer = array_shift($lines);
}
foreach (array_reverse($lines) as $line) {
if (trim($line) !== '') {
$raw_lines[] = $line;
if (count($raw_lines) >= $_count) {
break 2;
}
}
}
}
fclose($fp);
// Разворачиваем, чтобы получить правильный хронологический порядок
return array_reverse($raw_lines);
}
/**
* Внешние методы класса
*/
/**
* Метод, предназначенный для отображения всех записей Журнала событий (log.csv)
*
*/
function logList ()
{
global $AVE_Template;
$file_name = BASE_DIR . $this->_logdir;
$_count = 10000;
$_lines = [];
$raw_lines = $this->readLastLines($file_name, $_count);
foreach ($raw_lines as $line) {
$event = str_getcsv($line, ',', '"', '\\');
if (empty($event[0]) || count($event) < 3) {
continue;
}
$_lines[] = [
'log_time' => $event['0'] ?? '',
'log_ip' => $event['1'] ?? '',
'log_url' => $event['2'] ?? '',
'log_user_id' => $event['3'] ?? '',
'log_user_name' => $event['4'] ?? '',
'log_text' => $event['5'] ?? '',
'log_type' => $event['6'] ?? '',
'log_rubric' => $event['7'] ?? ''
];
}
$AVE_Template->assign('logs', $_lines);
$AVE_Template->assign('content', $AVE_Template->fetch('logs/logs.tpl'));
}
/**
* Метод, предназначенный для отображения всех записей Журнала событий 404 (404.csv)
*
*/
function List404()
{
global $AVE_Template;
$file_name = BASE_DIR . $this->_404dir;
$_count = 10000;
$_lines = [];
$raw_lines = $this->readLastLines($file_name, $_count);
foreach ($raw_lines as $line) {
$event = str_getcsv($line, ',', '"', '\\');
if (empty($event[0]) || count($event) < 3) {
continue;
}
$_lines[] = [
'log_time' => $event['0'] ?? '',
'log_ip' => $event['1'] ?? '',
'log_query' => $event['2'] ?? '',
'log_user_agent' => $event['3'] ?? '',
'log_user_referer' => $event['4'] ?? '',
'log_request_uri' => $event['5'] ?? ''
];
}
// Передаем данные в шаблон для вывода и отображаем страницу
$AVE_Template->assign('logs', $_lines);
$AVE_Template->assign('content', $AVE_Template->fetch('logs/404.tpl'));
}
/**
* Метод, предназначенный для отображения всех записей Журнала событий SQL (sql.csv)
*
*/
function ListSql()
{
global $AVE_Template;
$file_name = BASE_DIR . $this->_sqldir;
$_count = 10000;
$_lines = [];
$raw_lines = $this->readLastLines($file_name, $_count);
foreach ($raw_lines as $line) {
$event = str_getcsv($line);
if (empty($event[0]) || count($event) < 3) {
continue;
}
$_lines[] = [
'log_time' => $event['0'] ?? '',
'log_ip' => $event['1'] ?? '',
'log_url' => $event['2'] ?? '',
'log_user_id' => $event['3'] ?? '',
'log_user_name' => $event['4'] ?? '',
'log_text' => isset($event['5']) ? unserialize(base64_decode($event['5'])) : ''
];
}
$AVE_Template->assign('logs', $_lines);
$AVE_Template->assign('content', $AVE_Template->fetch('logs/sql.tpl'));
}
/**
* Метод, предназначенный для удаление записей Журнала событий
*
*/
function logDelete()
{
global $AVE_Template;
$logfile = BASE_DIR . $this->_logdir;
if(file_exists($logfile))
unlink($logfile);
// Сохраняем системное сообщение в журнал
reportLog($AVE_Template->get_config_vars('LOGS_CLEAN'));
header('Location:index.php?do=logs&cp=' . SESSION);
exit;
}
/**
* Метод, предназначенный для удаление записей Журнала событий 404
*
*/
function DeleteSql()
{
global $AVE_Template;
$logfile = BASE_DIR . $this->_sqldir;
if(file_exists($logfile))
unlink($logfile);
// Сохраняем системное сообщение в журнал
reportLog($AVE_Template->get_config_vars('LOGS_SQL_CLEAN'));
header('Location:index.php?do=logs&action=logsql&cp=' . SESSION);
exit;
}
/**
* Метод, предназначенный для удаление записей Журнала событий 404
*
*/
function Delete404()
{
global $AVE_Template;
$logfile = BASE_DIR . $this->_404dir;
if(file_exists($logfile))
unlink($logfile);
// Сохраняем системное сообщение в журнал
reportLog($AVE_Template->get_config_vars('LOGS_404_CLEAN'));
header('Location:index.php?do=logs&action=log404&cp=' . SESSION);
exit;
}
/**
* Метод, предназначенный для экспорта системных сообщений
*
*/
function logExport()
{
global $AVE_Template;
$file_name = BASE_DIR . $this->_logdir;
$dateName = 'system_log_' . date('dmyhis', time()) . '.csv';
// Определяем заголовки документа
header('Content-Encoding: windows-1251');
header('Content-type: text/csv; charset=windows-1251');
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Content-Disposition: attachment; filename="' . $dateName . '"');
header('Content-Length: ' . filesize($file_name));
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
// Выводим данные
readfile($file_name);
// Сохраняем системное сообщение в журнал
reportLog($AVE_Template->get_config_vars('LOGS_EXPORT'));
exit;
}
/**
* Метод, предназначенный для экспорта сообщений 404
*
*/
function Export404()
{
global $AVE_Template;
$file_name = BASE_DIR . $this->_404dir;
$dateName = 'system_log_' . date('dmyhis', time()) . '.csv';
// Определяем заголовки документа
header('Content-Encoding: windows-1251');
header('Content-type: text/csv; charset=windows-1251');
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Content-Disposition: attachment; filename="' . $dateName . '"');
header('Content-Length: ' . filesize($file_name));
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
// Выводим данные
readfile($file_name);
// Сохраняем системное сообщение в журнал
reportLog($AVE_Template->get_config_vars('LOGS_EXPORT'));
exit;
}
/**
* Метод, предназначенный для экспорта сообщений MySql
*
*/
function ExportSql()
{
global $AVE_Template;
$file_name = BASE_DIR . $this->_sqldir;
$dateName = 'system_log_' . date('dmyhis', time()) . '.csv';
// Определяем заголовки документа
header('Content-Encoding: windows-1251');
header('Content-type: text/csv; charset=windows-1251');
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Content-Disposition: attachment; filename="' . $dateName . '"');
header('Content-Length: ' . filesize($file_name));
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
// Выводим данные
readfile($file_name);
// Сохраняем системное сообщение в журнал
reportLog($AVE_Template->get_config_vars('LOGS_EXPORT'));
exit;
}
}
?>