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