mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°5993 - Add purge mechanism to log system (#447)
* N°5993 - Add purge mechanism to log system * Update core/config.class.inc.php Co-authored-by: Molkobain <lajarige.guillaume@free.fr> * Update core/log.class.inc.php Co-authored-by: Molkobain <lajarige.guillaume@free.fr> * Update core/log.class.inc.php Co-authored-by: Molkobain <lajarige.guillaume@free.fr> * Update core/log.class.inc.php Co-authored-by: Molkobain <lajarige.guillaume@free.fr> * Update core/log.class.inc.php Co-authored-by: Molkobain <lajarige.guillaume@free.fr> * Namespace the log purge config parameters --------- Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
This commit is contained in:
@@ -113,70 +113,86 @@ class Config
|
||||
* @since 2.7.0 export_pdf_font param
|
||||
*/
|
||||
protected $m_aSettings = [
|
||||
'log_level_min' => [
|
||||
'type' => 'array',
|
||||
'description' => 'Optional min log level, per channel.',
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'log_level_min' => [
|
||||
'type' => 'array',
|
||||
'description' => 'Optional min log level, per channel.',
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'log_level_min.write_in_db' => [
|
||||
'type' => 'array',
|
||||
'description' => 'Optional min log level IN DB, per channel.',
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'log_level_min.write_in_db' => [
|
||||
'type' => 'array',
|
||||
'description' => 'Optional min log level IN DB, per channel.',
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'event_service.debug.filter_events' => [
|
||||
'type' => 'array',
|
||||
'description' => 'List of events name to filter Event Service debug messages',
|
||||
'default' => [],
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'log_purge.enabled' => [
|
||||
'type' => 'bool',
|
||||
'description' => 'Optional purge activation.',
|
||||
'default' => false,
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'log_purge.max_keep_days' => [
|
||||
'type' => 'integer',
|
||||
'description' => 'Optional purge number of days to keep logs.',
|
||||
'default' => 365,
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'event_service.debug.filter_events' => [
|
||||
'type' => 'array',
|
||||
'description' => 'List of events name to filter Event Service debug messages',
|
||||
'default' => [],
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'event_service.debug.filter_sources' => [
|
||||
'type' => 'array',
|
||||
'description' => 'List of event sources to filter Event Service debug messages',
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'type' => 'array',
|
||||
'description' => 'List of event sources to filter Event Service debug messages',
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'app_env_label' => [
|
||||
'type' => 'string',
|
||||
'description' => 'Label displayed to describe the current application environment, defaults to the environment name (e.g. "production")',
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'app_env_label' => [
|
||||
'type' => 'string',
|
||||
'description' => 'Label displayed to describe the current application environment, defaults to the environment name (e.g. "production")',
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'app_root_url' => [
|
||||
'type' => 'string',
|
||||
'description' => 'Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server\'s name)',
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'app_root_url' => [
|
||||
'type' => 'string',
|
||||
'description' => 'Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server\'s name)',
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => true,
|
||||
],
|
||||
'app_icon_url' => [
|
||||
'type' => 'string',
|
||||
'description' => 'Hyperlink to redirect the user when clicking on the application icon (in the main window, or login/logoff pages)',
|
||||
'default' => 'http://www.combodo.com/itop',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'app_icon_url' => [
|
||||
'type' => 'string',
|
||||
'description' => 'Hyperlink to redirect the user when clicking on the application icon (in the main window, or login/logoff pages)',
|
||||
'default' => 'http://www.combodo.com/itop',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'db_host' => [
|
||||
'type' => 'string',
|
||||
'default' => null,
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'db_host' => [
|
||||
'type' => 'string',
|
||||
'default' => null,
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => true,
|
||||
],
|
||||
'db_user' => [
|
||||
'db_user' => [
|
||||
'type' => 'string',
|
||||
'default' => null,
|
||||
'value' => '',
|
||||
|
||||
@@ -612,12 +612,12 @@ abstract class LogAPI
|
||||
{
|
||||
public const CHANNEL_DEFAULT = '';
|
||||
|
||||
public const LEVEL_ERROR = 'Error';
|
||||
public const LEVEL_ERROR = 'Error';
|
||||
public const LEVEL_WARNING = 'Warning';
|
||||
public const LEVEL_INFO = 'Info';
|
||||
public const LEVEL_OK = 'Ok';
|
||||
public const LEVEL_DEBUG = 'Debug';
|
||||
public const LEVEL_TRACE = 'Trace';
|
||||
public const LEVEL_INFO = 'Info';
|
||||
public const LEVEL_OK = 'Ok';
|
||||
public const LEVEL_DEBUG = 'Debug';
|
||||
public const LEVEL_TRACE = 'Trace';
|
||||
|
||||
/**
|
||||
* @see GetMinLogLevel
|
||||
@@ -645,7 +645,22 @@ abstract class LogAPI
|
||||
);
|
||||
|
||||
public const ENUM_CONFIG_PARAM_FILE = 'log_level_min';
|
||||
public const ENUM_CONFIG_PARAM_DB = 'log_level_min.write_in_db';
|
||||
public const ENUM_CONFIG_PARAM_DB = 'log_level_min.write_in_db';
|
||||
|
||||
|
||||
/**
|
||||
* Parameter to enable log purge.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_CONFIG_PARAM_PURGE_ENABLED = 'log_purge.enabled';
|
||||
|
||||
/**
|
||||
* Parameter to define day we want to keep old log files.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_CONFIG_PARAM_PURGE_MAX_KEEP_DAYS = 'log_purge.max_keep_days';
|
||||
|
||||
/**
|
||||
* @var \Config attribute allowing to mock config in the tests
|
||||
@@ -1336,8 +1351,7 @@ class LogFileRotationProcess implements iScheduledProcess
|
||||
{
|
||||
$sLogFileNameBuilder = $this->GetLogFileNameBuilderClassName();
|
||||
|
||||
foreach (self::LOGFILES_TO_ROTATE as $sLogFileName)
|
||||
{
|
||||
foreach (self::LOGFILES_TO_ROTATE as $sLogFileName) {
|
||||
$sLogFileFullPath = APPROOT
|
||||
.DIRECTORY_SEPARATOR.'log'
|
||||
.DIRECTORY_SEPARATOR.$sLogFileName;
|
||||
@@ -1347,6 +1361,77 @@ class LogFileRotationProcess implements iScheduledProcess
|
||||
$oLogFileNameBuilder->ResetLastModifiedDateForFile();
|
||||
$oLogFileNameBuilder->CheckAndRotateLogFile();
|
||||
}
|
||||
|
||||
// Purge logs if purge enabled
|
||||
if (MetaModel::GetConfig()->Get(LogAPI::ENUM_CONFIG_PARAM_PURGE_ENABLED)) {
|
||||
$this->PurgeLogs();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PurgeLogs.
|
||||
*
|
||||
* Purge test last modification time of file in log folder and delete
|
||||
* files that haven't modifications since {@see \LogAPI::ENUM_CONFIG_PARAM_PURGE_MAX_KEEP_DAYS}
|
||||
*
|
||||
* @return array process feedback
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public function PurgeLogs(): array
|
||||
{
|
||||
// result
|
||||
$aFilesResult = array();
|
||||
|
||||
// Max keep days
|
||||
$iMaxDays = MetaModel::GetConfig()->Get(LogAPI::ENUM_CONFIG_PARAM_PURGE_MAX_KEEP_DAYS);
|
||||
|
||||
// Files iterator (*.*)
|
||||
$oIterator = new \GlobIterator(APPROOT.'log'.DIRECTORY_SEPARATOR.'/*.*');
|
||||
$aLogFiles = iterator_to_array($oIterator);
|
||||
|
||||
// Reference date
|
||||
$oDateNow = new DateTime('now');
|
||||
|
||||
// Iterate throw files...
|
||||
foreach ($aLogFiles as $oLogFile) {
|
||||
|
||||
// File real path
|
||||
$sFileRealPath = $oLogFile->getRealPath();
|
||||
|
||||
// Compute number of days since last modification
|
||||
$oDateFileLastModification = new DateTime();
|
||||
$oDateFileLastModification->setTimestamp($oLogFile->getMTime());
|
||||
$iDays = intval($oDateFileLastModification->diff($oDateNow)->format('%a'));
|
||||
|
||||
// File process status
|
||||
$aFileResult = [
|
||||
'file_name' => $sFileRealPath,
|
||||
'days_since_last_modification' => $iDays,
|
||||
'deleted' => false,
|
||||
'error' => null,
|
||||
];
|
||||
|
||||
// Delete file older than max last modified in days
|
||||
if ($iDays > $iMaxDays) {
|
||||
|
||||
// unlink file
|
||||
if (!is_writable($sFileRealPath)) {
|
||||
$aFileResult['error'] = Dict::S('itop-log-mgmt:UI:Error:file_read_only');
|
||||
} // unlink OK
|
||||
else if (unlink($sFileRealPath)) {
|
||||
$aFileResult['deleted'] = true;
|
||||
} // unlink KO
|
||||
else {
|
||||
$aFileResult['error'] = Dict::S('itop-log-mgmt:UI:Error:unknown_error');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// append result
|
||||
$aFilesResult[] = $aFileResult;
|
||||
}
|
||||
|
||||
return $aFilesResult;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1354,12 +1439,10 @@ class LogFileRotationProcess implements iScheduledProcess
|
||||
*/
|
||||
public function GetNextOccurrence()
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
$sLogFileNameBuilder = $this->GetLogFileNameBuilderClassName();
|
||||
}
|
||||
catch (ProcessException $e)
|
||||
{
|
||||
catch (ProcessException $e) {
|
||||
return new DateTime('3000-01-01');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user