Overview

Namespaces

  • Alpha
    • Controller
      • Front
    • Exception
    • Model
      • Type
    • Task
    • Util
      • Backup
      • Cache
      • Code
        • Highlight
        • Metric
      • Config
      • Convertor
      • Email
      • Extension
      • Feed
      • File
      • Graph
      • Helper
      • Http
        • Filter
        • Session
      • Image
      • Logging
      • Search
      • Security
    • View
      • Renderer
        • Html
        • Json
      • Widget

Classes

  • KPI
  • Logger
  • LogProviderFactory
  • LogProviderFile

Interfaces

  • LogProviderInterface
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: namespace Alpha\Util\Logging;
  4: 
  5: use Alpha\Util\Config\ConfigProvider;
  6: use Alpha\Exception\PHPException;
  7: use Alpha\Util\File\FileUtils;
  8: 
  9: /**
 10:  * Generic log file class to encapsulate common file I/O and rendering calls.
 11:  *
 12:  * @since 1.0
 13:  *
 14:  * @author John Collins <dev@alphaframework.org>
 15:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
 16:  * @copyright Copyright (c) 2016, John Collins (founder of Alpha Framework).
 17:  * All rights reserved.
 18:  *
 19:  * <pre>
 20:  * Redistribution and use in source and binary forms, with or
 21:  * without modification, are permitted provided that the
 22:  * following conditions are met:
 23:  *
 24:  * * Redistributions of source code must retain the above
 25:  *   copyright notice, this list of conditions and the
 26:  *   following disclaimer.
 27:  * * Redistributions in binary form must reproduce the above
 28:  *   copyright notice, this list of conditions and the
 29:  *   following disclaimer in the documentation and/or other
 30:  *   materials provided with the distribution.
 31:  * * Neither the name of the Alpha Framework nor the names
 32:  *   of its contributors may be used to endorse or promote
 33:  *   products derived from this software without specific
 34:  *   prior written permission.
 35:  *
 36:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 37:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 38:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 39:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 40:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 41:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 42:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 43:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 44:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 45:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 46:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 47:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 48:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 49:  * </pre>
 50:  */
 51: class LogProviderFile implements LogProviderInterface
 52: {
 53:     /**
 54:      * The log file path.
 55:      *
 56:      * @var string
 57:      *
 58:      * @since 1.0
 59:      */
 60:     private $path;
 61: 
 62:     /**
 63:      * The maximum size of the log file in megabytes before a backup is created and a
 64:      * new file is created, default is 5.
 65:      *
 66:      * @var int
 67:      *
 68:      * @since 1.0
 69:      */
 70:     private $maxSize = 5;
 71: 
 72:     /**
 73:      * Set the file path.
 74:      *
 75:      * @param string $path
 76:      *
 77:      * @since 2.0
 78:      */
 79:     public function setPath($path)
 80:     {
 81:         $this->path = $path;
 82:     }
 83: 
 84:     /**
 85:      * Set the max log size in megabytes.
 86:      *
 87:      * @param int $maxSize
 88:      *
 89:      * @since 1.0
 90:      */
 91:     public function setMaxSize($maxSize)
 92:     {
 93:         $this->maxSize = $maxSize;
 94:     }
 95: 
 96:     /**
 97:      * {@inheritdoc}
 98:      */
 99:     public function writeLine($line)
100:     {
101:         $config = ConfigProvider::getInstance();
102: 
103:         if ($this->path != '') {
104:             try {
105:                 $fp = fopen($this->path, 'a+');
106:                 fputcsv($fp, $line, ',', '"', '\\');
107: 
108:                 if ($this->checkFileSize() >= $this->maxSize) {
109:                     $this->backupFile();
110:                 }
111:             } catch (\Exception $e) {
112:                 try {
113:                     $logsDir = $config->get('app.file.store.dir').'logs';
114: 
115:                     if (!file_exists($logsDir)) {
116:                         if (!mkdir($logsDir, 0766)) {
117:                             throw new PHPException('Could not create the directory ['.$logsDir.']');
118:                         }
119:                     }
120: 
121:                     $fp = fopen($this->path, 'a+');
122:                     if (!fputcsv($fp, $line, ',', '"', '\\')) {
123:                         throw new PHPException('Could not write to the CSV file ['.$this->path.']');
124:                     }
125: 
126:                     if ($this->checkFileSize() >= $this->maxSize) {
127:                         $this->backupFile();
128:                     }
129:                 } catch (\Exception $e) {
130:                     echo 'Unable to write to the log file ['.$this->path.'], error ['.$e->getMessage().']';
131:                     exit;
132:                 }
133:             }
134:         }
135:     }
136: 
137:     /**
138:      * Returns the size in megabytes of the log file on disc.
139:      *
140:      * @return float
141:      *
142:      * @since 1.0
143:      */
144:     private function checkFileSize()
145:     {
146:         clearstatcache();
147:         $size = filesize($this->path);
148: 
149:         return ($size / 1024) /1024;
150:     }
151: 
152:     /**
153:      * Creates a backup of the log file, which has the same file name and location as the
154:      * current file plus a timestamp appended.
155:      *
156:      * @since 1.0
157:      */
158:     private function backupFile()
159:     {
160:         // generate the name of the backup file name to contain a timestampe
161:         $backName = str_replace('.log', '-backup-'.date('y-m-d').'.log', $this->path);
162: 
163:         // renames the logfile as the value of $backName
164:         rename($this->path, $backName);
165: 
166:         FileUtils::zip($backName, $backName.'.zip');
167:         unlink($backName);
168: 
169:         // creates a new log file, and sets it's permission for writing!
170:         $fp = fopen($this->path, 'a+'); // remember set directory permissons to allow creation!
171:         fclose($fp);
172:         //s ets the new permission to rw+:rw+:rw+
173:         chmod($this->path, 0666);
174:     }
175: 
176:     /**
177:      * {@inheritdoc}
178:      */
179:     public function renderLog($cols)
180:     {
181:         // render the start of the table
182:         $body = '<table class="table">';
183:         $body .= '<tr>';
184:         foreach ($cols as $heading) {
185:             $body .= '<th>'.$heading.'</th>';
186:         }
187:         $body .= '</tr>';
188: 
189:         $fp = fopen($this->path, 'r');
190: 
191:         while (($line = fgetcsv($fp)) !== false) {
192:             $body .= '<tr>';
193: 
194:             for ($col = 0; $col < count($line); ++$col) {
195: 
196:                 // if it is an error log, render the error types field in different colours
197:                 if ($col == 1 && $cols[1] == 'Level') {
198:                     switch ($line[$col]) {
199:                         case 'DEBUG':
200:                             $body .= '<td class="debug">'.htmlentities($line[$col], ENT_COMPAT, 'utf-8').'</td>';
201:                         break;
202:                         case 'INFO':
203:                             $body .= '<td class="info">'.htmlentities($line[$col], ENT_COMPAT, 'utf-8').'</td>';
204:                         break;
205:                         case 'WARN':
206:                             $body .= '<td class="warn">'.htmlentities($line[$col], ENT_COMPAT, 'utf-8').'</td>';
207:                         break;
208:                         case 'ERROR':
209:                             $body .= '<td class="error">'.htmlentities($line[$col], ENT_COMPAT, 'utf-8').'</td>';
210:                         break;
211:                         case 'FATAL':
212:                             $body .= '<td class="fatal">'.htmlentities($line[$col], ENT_COMPAT, 'utf-8').'</td>';
213:                         break;
214:                         case 'SQL':
215:                             $body .= '<td class="sql">'.htmlentities($line[$col], ENT_COMPAT, 'utf-8').'</td>';
216:                         break;
217:                         default:
218:                             $body .= '<td>'.htmlentities($line[$col], ENT_COMPAT, 'utf-8').'</td>';
219:                         break;
220:                     }
221:                 } else {
222:                     if ($cols[$col] == 'Message') {
223:                         $body .= '<td><pre>'.htmlentities($line[$col], ENT_COMPAT, 'utf-8').'</pre></td>';
224:                     } else {
225:                         $body .= '<td>'.htmlentities($line[$col], ENT_COMPAT, 'utf-8').'</td>';
226:                     }
227:                 }
228:             }
229: 
230:             $body .= '</tr>';
231:         }
232: 
233:         $body .= '</table>';
234: 
235:         return $body;
236:     }
237: }
238: 
Alpha Framework 2.0.4 API Documentation API documentation generated by ApiGen 2.8.0