]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/SugarLogger/SugarLogger.php
Release 6.4.0
[Github/sugarcrm.git] / include / SugarLogger / SugarLogger.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38 /*********************************************************************************
39
40  * Description:  Defines the English language pack for the base application.
41  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
42  * All Rights Reserved.
43  * Contributor(s): ______________________________________..
44  ********************************************************************************/
45 require_once('include/SugarLogger/LoggerManager.php');
46 require_once('include/SugarLogger/LoggerTemplate.php');
47
48 /**
49  * Default SugarCRM Logger
50  * @api
51  */
52 class SugarLogger implements LoggerTemplate
53 {
54     /**
55      * properties for the SugarLogger
56      */
57         protected $logfile = 'sugarcrm';
58         protected $ext = '.log';
59         protected $dateFormat = '%c';
60         protected $logSize = '10MB';
61         protected $maxLogs = 10;
62         protected $filesuffix = "";
63         protected $log_dir = '.';
64
65
66         /**
67          * used for config screen
68          */
69         public static $filename_suffix = array(
70             "%m_%Y"    => "Month_Year",
71             "%w_%m"    => "Week_Month",
72             "%m_%d_%y" => "Month_Day_Year",
73             );
74
75         /**
76          * Let's us know if we've initialized the logger file
77          */
78     protected $initialized = false;
79
80     /**
81      * Logger file handle
82      */
83     protected $fp = false;
84
85     public function __get(
86         $key
87         )
88     {
89         return $this->$key;
90     }
91
92     /**
93      * Used by the diagnostic tools to get SugarLogger log file information
94      */
95     public function getLogFileNameWithPath()
96     {
97         return $this->full_log_file;
98     }
99
100     /**
101      * Used by the diagnostic tools to get SugarLogger log file information
102      */
103     public function getLogFileName()
104     {
105         return ltrim($this->full_log_file, "./");
106     }
107
108     /**
109      * Constructor
110      *
111      * Reads the config file for logger settings
112      */
113     public function __construct()
114     {
115         $config = SugarConfig::getInstance();
116         $this->ext = $config->get('logger.file.ext', $this->ext);
117         $this->logfile = $config->get('logger.file.name', $this->logfile);
118         $this->dateFormat = $config->get('logger.file.dateFormat', $this->dateFormat);
119         $this->logSize = $config->get('logger.file.maxSize', $this->logSize);
120         $this->maxLogs = $config->get('logger.file.maxLogs', $this->maxLogs);
121         $this->filesuffix = $config->get('logger.file.suffix', $this->filesuffix);
122         $log_dir = $config->get('log_dir' , $this->log_dir);
123         $this->log_dir = $log_dir . (empty($log_dir)?'':'/');
124         unset($config);
125         $this->_doInitialization();
126         LoggerManager::setLogger('default','SugarLogger');
127         }
128
129         /**
130          * Handles the SugarLogger initialization
131          */
132     protected function _doInitialization()
133     {
134         $this->full_log_file = $this->log_dir . $this->logfile . $this->ext;
135         $this->initialized = $this->_fileCanBeCreatedAndWrittenTo();
136         $this->rollLog();
137     }
138
139     /**
140          * Checks to see if the SugarLogger file can be created and written to
141          */
142     protected function _fileCanBeCreatedAndWrittenTo()
143     {
144         $this->_attemptToCreateIfNecessary();
145         return file_exists($this->full_log_file) && is_writable($this->full_log_file);
146     }
147
148     /**
149          * Creates the SugarLogger file if it doesn't exist
150          */
151     protected function _attemptToCreateIfNecessary()
152     {
153         if (file_exists($this->full_log_file)) {
154             return;
155         }
156         @touch($this->full_log_file);
157     }
158
159     /**
160      * see LoggerTemplate::log()
161      */
162         public function log(
163             $level,
164             $message
165             )
166         {
167         if (!$this->initialized) {
168             return;
169         }
170                 //lets get the current user id or default to -none- if it is not set yet
171                 $userID = (!empty($GLOBALS['current_user']->id))?$GLOBALS['current_user']->id:'-none-';
172
173                 //if we haven't opened a file pointer yet let's do that
174                 if (! $this->fp)$this->fp = fopen ($this->full_log_file , 'a' );
175
176
177                 // change to a string if there is just one entry
178             if ( is_array($message) && count($message) == 1 )
179                 $message = array_shift($message);
180             // change to a human-readable array output if it's any other array
181             if ( is_array($message) )
182                     $message = print_r($message,true);
183
184                 //write out to the file including the time in the dateFormat the process id , the user id , and the log level as well as the message
185                 fwrite($this->fp,
186                     strftime($this->dateFormat) . ' [' . getmypid () . '][' . $userID . '][' . strtoupper($level) . '] ' . $message . "\n"
187                     );
188         }
189
190         /**
191          * rolls the logger file to start using a new file
192          */
193         protected function rollLog(
194             $force = false
195             )
196         {
197         if (!$this->initialized || empty($this->logSize)) {
198             return;
199         }
200                 // lets get the number of megs we are allowed to have in the file
201                 $megs = substr ( $this->logSize, 0, strlen ( $this->logSize ) - 2 );
202                 //convert it to bytes
203                 $rollAt = ( int ) $megs * 1024 * 1024;
204                 //check if our log file is greater than that or if we are forcing the log to roll
205                 if ($force || filesize ( $this->full_log_file ) >= $rollAt) {
206                         //now lets move the logs starting at the oldest and going to the newest
207                         for($i = $this->maxLogs - 2; $i > 0; $i --) {
208                                 if (file_exists ( $this->log_dir . $this->logfile . $i . $this->ext )) {
209                                         $to = $i + 1;
210                                         $old_name = $this->log_dir . $this->logfile . $i . $this->ext;
211                                         $new_name = $this->log_dir . $this->logfile . $to . $this->ext;
212                                         //nsingh- Bug 22548  Win systems fail if new file name already exists. The fix below checks for that.
213                                         //if/else branch is necessary as suggested by someone on php-doc ( see rename function ).
214                                         sugar_rename($old_name, $new_name);
215
216                                         //rename ( $this->logfile . $i . $this->ext, $this->logfile . $to . $this->ext );
217                                 }
218                         }
219                         //now lets move the current .log file
220                         sugar_rename ($this->full_log_file, $this->log_dir . $this->logfile . '1' . $this->ext);
221
222                 }
223         }
224
225     /**
226          * This is needed to prevent unserialize vulnerability
227      */
228     public function __wakeup()
229     {
230         // clean all properties
231         foreach(get_object_vars($this) as $k => $v) {
232             $this->$k = null;
233         }
234         throw new Exception("Not a serializable object");
235     }
236
237         /**
238          * Destructor
239          *
240          * Closes the SugarLogger file handle
241      */
242         public function __destruct()
243         {
244                 if ($this->fp)
245                         fclose($this->fp);
246         }
247 }