0byt3m1n1
Path:
/
data
/
applications
/
aps.bak
/
sugarcrm
/
6.5.16-25
/
standard
/
htdocs
/
include
/
SugarLogger
/
[
Home
]
File: SugarLogger.php
<?php if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); /********************************************************************************* * SugarCRM Community Edition is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo. If the display of the logo is not reasonably feasible for * technical reasons, the Appropriate Legal Notices must display the words * "Powered by SugarCRM". ********************************************************************************/ /********************************************************************************* * Description: Defines the English language pack for the base application. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. * All Rights Reserved. * Contributor(s): ______________________________________.. ********************************************************************************/ require_once('include/SugarLogger/LoggerManager.php'); require_once('include/SugarLogger/LoggerTemplate.php'); /** * Default SugarCRM Logger * @api */ class SugarLogger implements LoggerTemplate { /** * properties for the SugarLogger */ protected $logfile = 'sugarcrm'; protected $ext = '.log'; protected $dateFormat = '%c'; protected $logSize = '10MB'; protected $maxLogs = 10; protected $filesuffix = ""; protected $date_suffix = ""; protected $log_dir = '.'; protected $full_log_file; /** * used for config screen */ public static $filename_suffix = array( //bug#50265: Added none option for previous version users "" => "None", "%m_%Y" => "Month_Year", "%d_%m" => "Day_Month", "%m_%d_%y" => "Month_Day_Year", ); /** * Let's us know if we've initialized the logger file */ protected $initialized = false; /** * Logger file handle */ protected $fp = false; public function __get( $key ) { return $this->$key; } /** * Used by the diagnostic tools to get SugarLogger log file information */ public function getLogFileNameWithPath() { return $this->full_log_file; } /** * Used by the diagnostic tools to get SugarLogger log file information */ public function getLogFileName() { return ltrim($this->full_log_file, "./"); } /** * Constructor * * Reads the config file for logger settings */ public function __construct() { $config = SugarConfig::getInstance(); $this->ext = $config->get('logger.file.ext', $this->ext); $this->logfile = $config->get('logger.file.name', $this->logfile); $this->dateFormat = $config->get('logger.file.dateFormat', $this->dateFormat); $this->logSize = $config->get('logger.file.maxSize', $this->logSize); $this->maxLogs = $config->get('logger.file.maxLogs', $this->maxLogs); $this->filesuffix = $config->get('logger.file.suffix', $this->filesuffix); $log_dir = $config->get('log_dir' , $this->log_dir); $this->log_dir = $log_dir . (empty($log_dir)?'':'/'); unset($config); $this->_doInitialization(); LoggerManager::setLogger('default','SugarLogger'); } /** * Handles the SugarLogger initialization */ protected function _doInitialization() { if( $this->filesuffix && array_key_exists($this->filesuffix, self::$filename_suffix) ) { //if the global config contains date-format suffix, it will create suffix by parsing datetime $this->date_suffix = "_" . date(str_replace("%", "", $this->filesuffix)); } $this->full_log_file = $this->log_dir . $this->logfile . $this->date_suffix . $this->ext; $this->initialized = $this->_fileCanBeCreatedAndWrittenTo(); $this->rollLog(); } /** * Checks to see if the SugarLogger file can be created and written to */ protected function _fileCanBeCreatedAndWrittenTo() { $this->_attemptToCreateIfNecessary(); return file_exists($this->full_log_file) && is_writable($this->full_log_file); } /** * Creates the SugarLogger file if it doesn't exist */ protected function _attemptToCreateIfNecessary() { if (file_exists($this->full_log_file)) { return; } @touch($this->full_log_file); } /** * see LoggerTemplate::log() */ public function log( $level, $message ) { if (!$this->initialized) { return; } //lets get the current user id or default to -none- if it is not set yet $userID = (!empty($GLOBALS['current_user']->id))?$GLOBALS['current_user']->id:'-none-'; //if we haven't opened a file pointer yet let's do that if (! $this->fp)$this->fp = fopen ($this->full_log_file , 'a' ); // change to a string if there is just one entry if ( is_array($message) && count($message) == 1 ) $message = array_shift($message); // change to a human-readable array output if it's any other array if ( is_array($message) ) $message = print_r($message,true); //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 fwrite($this->fp, strftime($this->dateFormat) . ' [' . getmypid () . '][' . $userID . '][' . strtoupper($level) . '] ' . $message . "\n" ); } /** * rolls the logger file to start using a new file */ protected function rollLog( $force = false ) { if (!$this->initialized || empty($this->logSize)) { return; } // bug#50265: Parse the its unit string and get the size properly $units = array( 'b' => 1, //Bytes 'k' => 1024, //KBytes 'm' => 1024 * 1024, //MBytes 'g' => 1024 * 1024 * 1024, //GBytes ); if( preg_match('/^\s*([0-9]+\.[0-9]+|\.?[0-9]+)\s*(k|m|g|b)(b?ytes)?/i', $this->logSize, $match) ) { $rollAt = ( int ) $match[1] * $units[strtolower($match[2])]; } //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 if ( $force || ($rollAt && filesize ( $this->full_log_file ) >= $rollAt) ) { $temp = tempnam($this->log_dir, 'rot'); if ($temp) { // warning here is expected in case if log file is opened by another process on Windows // or rotation has been already started by another process if (@rename($this->full_log_file, $temp)) { // manually remove the obsolete part. Otherwise, rename() may fail on Windows (bug #22548) $obsolete_part = $this->getLogPartPath($this->maxLogs - 1); if (file_exists($obsolete_part)) { unlink($obsolete_part); } // now lets move the logs starting at the oldest and going to the newest for ($old = $this->maxLogs - 2; $old > 0; $old--) { $old_name = $this->getLogPartPath($old); if (file_exists($old_name)) { $new_name = $this->getLogPartPath($old + 1); rename($old_name, $new_name); } } $part1 = $this->getLogPartPath(1); rename($temp, $part1); } else { unlink($temp); } } } } /** * Returns path for the given log part * * @param int $i * @return string */ protected function getLogPartPath($i) { return $this->log_dir . $this->logfile . $this->date_suffix . '_' . $i . $this->ext; } /** * This is needed to prevent unserialize vulnerability */ public function __wakeup() { // clean all properties foreach(get_object_vars($this) as $k => $v) { $this->$k = null; } throw new Exception("Not a serializable object"); } /** * Destructor * * Closes the SugarLogger file handle */ public function __destruct() { if ($this->fp) { fclose($this->fp); $this->fp = FALSE; } } }