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-2012 SugarCRM Inc.
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.
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
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
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.
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.
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 ********************************************************************************/
38 /*********************************************************************************
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');
49 * Default SugarCRM Logger
52 class SugarLogger implements LoggerTemplate
55 * properties for the SugarLogger
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 $date_suffix = "";
64 protected $log_dir = '.';
68 * used for config screen
70 public static $filename_suffix = array(
71 //bug#50265: Added none option for previous version users
73 "%m_%Y" => "Month_Year",
74 "%d_%m" => "Day_Month",
75 "%m_%d_%y" => "Month_Day_Year",
79 * Let's us know if we've initialized the logger file
81 protected $initialized = false;
86 protected $fp = false;
88 public function __get(
96 * Used by the diagnostic tools to get SugarLogger log file information
98 public function getLogFileNameWithPath()
100 return $this->full_log_file;
104 * Used by the diagnostic tools to get SugarLogger log file information
106 public function getLogFileName()
108 return ltrim($this->full_log_file, "./");
114 * Reads the config file for logger settings
116 public function __construct()
118 $config = SugarConfig::getInstance();
119 $this->ext = $config->get('logger.file.ext', $this->ext);
120 $this->logfile = $config->get('logger.file.name', $this->logfile);
121 $this->dateFormat = $config->get('logger.file.dateFormat', $this->dateFormat);
122 $this->logSize = $config->get('logger.file.maxSize', $this->logSize);
123 $this->maxLogs = $config->get('logger.file.maxLogs', $this->maxLogs);
124 $this->filesuffix = $config->get('logger.file.suffix', $this->filesuffix);
125 $log_dir = $config->get('log_dir' , $this->log_dir);
126 $this->log_dir = $log_dir . (empty($log_dir)?'':'/');
128 $this->_doInitialization();
129 LoggerManager::setLogger('default','SugarLogger');
133 * Handles the SugarLogger initialization
135 protected function _doInitialization()
138 if( $this->filesuffix && array_key_exists($this->filesuffix, self::$filename_suffix) )
139 { //if the global config contains date-format suffix, it will create suffix by parsing datetime
140 $this->date_suffix = "_" . date(str_replace("%", "", $this->filesuffix));
142 $this->full_log_file = $this->log_dir . $this->logfile . $this->date_suffix . $this->ext;
143 $this->initialized = $this->_fileCanBeCreatedAndWrittenTo();
148 * Checks to see if the SugarLogger file can be created and written to
150 protected function _fileCanBeCreatedAndWrittenTo()
152 $this->_attemptToCreateIfNecessary();
153 return file_exists($this->full_log_file) && is_writable($this->full_log_file);
157 * Creates the SugarLogger file if it doesn't exist
159 protected function _attemptToCreateIfNecessary()
161 if (file_exists($this->full_log_file)) {
164 @touch($this->full_log_file);
168 * see LoggerTemplate::log()
175 if (!$this->initialized) {
178 //lets get the current user id or default to -none- if it is not set yet
179 $userID = (!empty($GLOBALS['current_user']->id))?$GLOBALS['current_user']->id:'-none-';
181 //if we haven't opened a file pointer yet let's do that
182 if (! $this->fp)$this->fp = fopen ($this->full_log_file , 'a' );
185 // change to a string if there is just one entry
186 if ( is_array($message) && count($message) == 1 )
187 $message = array_shift($message);
188 // change to a human-readable array output if it's any other array
189 if ( is_array($message) )
190 $message = print_r($message,true);
192 //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
194 strftime($this->dateFormat) . ' [' . getmypid () . '][' . $userID . '][' . strtoupper($level) . '] ' . $message . "\n"
199 * rolls the logger file to start using a new file
201 protected function rollLog(
205 if (!$this->initialized || empty($this->logSize)) {
208 // bug#50265: Parse the its unit string and get the size properly
211 'k' => 1024, //KBytes
212 'm' => 1024 * 1024, //MBytes
213 'g' => 1024 * 1024 * 1024, //GBytes
215 if( preg_match('/^\s*([0-9]+\.[0-9]+|\.?[0-9]+)\s*(k|m|g|b)(b?ytes)?/i', $this->logSize, $match) ) {
216 $rollAt = ( int ) $match[1] * $units[strtolower($match[2])];
218 //check if our log file is greater than that or if we are forcing the log to roll if and only if roll size assigned the value correctly
219 if ( $force || ($rollAt && filesize ( $this->full_log_file ) >= $rollAt) ) {
220 //now lets move the logs starting at the oldest and going to the newest
221 for($i = $this->maxLogs - 2; $i > 0; $i --) {
222 if (file_exists ( $this->log_dir . $this->logfile . $this->date_suffix . '_'. $i . $this->ext )) {
224 $old_name = $this->log_dir . $this->logfile . $this->date_suffix . '_'. $i . $this->ext;
225 $new_name = $this->log_dir . $this->logfile . $this->date_suffix . '_'. $to . $this->ext;
226 //nsingh- Bug 22548 Win systems fail if new file name already exists. The fix below checks for that.
227 //if/else branch is necessary as suggested by someone on php-doc ( see rename function ).
228 sugar_rename($old_name, $new_name);
230 //rename ( $this->logfile . $i . $this->ext, $this->logfile . $to . $this->ext );
233 //now lets move the current .log file
234 sugar_rename ($this->full_log_file, $this->log_dir . $this->logfile . $this->date_suffix . '_1' . $this->ext);
240 * This is needed to prevent unserialize vulnerability
242 public function __wakeup()
244 // clean all properties
245 foreach(get_object_vars($this) as $k => $v) {
248 throw new Exception("Not a serializable object");
254 * Closes the SugarLogger file handle
256 public function __destruct()