1. sfLogRotateTask.class.php
  2. /** * Rotates an application log files. * * @package symfony * @subpackage task * @author Fabien Potencier * @version SVN: $Id: sfLogRotateTask.class.php 24331 2009-11-24 13:15:01Z Kris.Wallsmith $ */
  3. class sfLogRotateTask extends sfBaseTask
  4. {
  5. /** the default period to rotate logs in days */
  6. const DEF_PERIOD = 7;
  7. /** the default number of log historys to store, one history is created for every period */
  8. const DEF_HISTORY = 10;
  9. /**
  10. * @see sfTask
  11. */
  12. protected function configure()
  13. {
  14. $this->addArguments(array(
  15. new sfCommandArgument('application', sfCommandArgument::REQUIRED, 'The application name'),
  16. new sfCommandArgument('env', sfCommandArgument::REQUIRED, 'The environment name'),
  17. ));
  18. $this->addOptions(array(
  19. new sfCommandOption('history', null, sfCommandOption::PARAMETER_REQUIRED, 'The maximum number of old log files to keep', self::DEF_HISTORY),
  20. new sfCommandOption('period', null, sfCommandOption::PARAMETER_REQUIRED, 'The period in days', self::DEF_PERIOD),
  21. ));
  22. $this->namespace = 'log';
  23. $this->name = 'rotate';
  24. $this->briefDescription = 'Rotates an application\'s log files';
  25. $this->detailedDescription = <<<EOF
  26. The [log:rotate|INFO] task rotates application log files for a given
  27. environment:
  28. [./symfony log:rotate frontend dev|INFO]
  29. You can specify a [period|COMMENT] or a [history|COMMENT] option:
  30. [./symfony log:rotate frontend dev --history=10 --period=7|INFO]
  31. EOF;
  32. }
  33. /**
  34. * @see sfTask
  35. */
  36. protected function execute($arguments = array(), $options = array())
  37. {
  38. $this->rotate($arguments['application'], $arguments['env'], $options['period'], $options['history'], true);
  39. }
  40. /**
  41. * Rotates log file.
  42. *
  43. * @param string $app Application name
  44. * @param string $env Enviroment name
  45. * @param string $period Period
  46. * @param string $history History
  47. * @param bool $override Override
  48. *
  49. * @author Joe Simms
  50. **/
  51. public function rotate($app, $env, $period = null, $history = null, $override = false)
  52. {
  53. $logfile = $app.'_'.$env;
  54. $logdir = sfConfig::get('sf_log_dir');
  55. // set history and period values if not passed to default values
  56. $period = isset($period) ? $period : self::DEF_PERIOD;
  57. $history = isset($history) ? $history : self::DEF_HISTORY;
  58. // get todays date
  59. $today = date('Ymd');
  60. // check history folder exists
  61. if (!is_dir($logdir.'/history'))
  62. {
  63. $this->getFilesystem()->mkdirs($logdir.'/history');
  64. }
  65. // determine date of last rotation
  66. $logs = sfFinder::type('file')->maxdepth(1)->name($logfile.'_*.log')->sort_by_name()->in($logdir.'/history');
  67. $recentlog = is_array($logs) ? array_pop($logs) : null;
  68. if ($recentlog)
  69. {
  70. // calculate date to rotate logs on
  71. $lastRotatedOn = filemtime($recentlog);
  72. $rotateOn = date('Ymd', strtotime('+ '.$period.' days', $lastRotatedOn));
  73. }
  74. else
  75. {
  76. // no rotation has occured yet
  77. $rotateOn = null;
  78. }
  79. $srcLog = $logdir.'/'.$logfile.'.log';
  80. $destLog = $logdir.'/history/'.$logfile.'_'.$today.'.log';
  81. // if rotate log on date doesn't exist, or that date is today, then rotate the log
  82. if (!$rotateOn || ($rotateOn == $today) || $override)
  83. {
  84. // create a lock file
  85. $lockFile = sfConfig::get('sf_data_dir').'/'.$app.'_'.$env.'-cli.lck';
  86. $this->getFilesystem()->touch($lockFile);
  87. // change mode so the web user can remove it if we die
  88. $this->getFilesystem()->chmod($lockFile, 0777);
  89. // if log file exists rotate it
  90. if (file_exists($srcLog))
  91. {
  92. // check if the log file has already been rotated today
  93. if (file_exists($destLog))
  94. {
  95. // append log to existing rotated log
  96. $handle = fopen($destLog, 'a');
  97. $append = file_get_contents($srcLog);
  98. $this->logSection('file+', $destLog);
  99. fwrite($handle, $append);
  100. }
  101. else
  102. {
  103. // copy log
  104. $this->getFilesystem()->copy($srcLog, $destLog);
  105. }
  106. // remove the log file
  107. $this->getFilesystem()->remove($srcLog);
  108. // get all log history files for this application and environment
  109. $newLogs = sfFinder::type('file')->maxdepth(1)->name($logfile.'_*.log')->sort_by_name()->in($logdir.'/history');
  110. // if the number of logs in history exceeds history then remove the oldest log
  111. if (count($newLogs) > $history)
  112. {
  113. $this->getFilesystem()->remove($newLogs[0]);
  114. }
  115. }
  116. // release lock
  117. $this->getFilesystem()->remove($lockFile);
  118. }
  119. }
  120. }

Debug toolbar