Back to index

d-push  2.0
zlog.php
Go to the documentation of this file.
00001 <?php
00002 /***********************************************
00003 * File      :   zlog.php
00004 * Project   :   Z-Push
00005 * Descr     :   Debug and logging
00006 *
00007 * Created   :   01.10.2007
00008 *
00009 * Copyright 2007 - 2011 Zarafa Deutschland GmbH
00010 *
00011 * This program is free software: you can redistribute it and/or modify
00012 * it under the terms of the GNU Affero General Public License, version 3,
00013 * as published by the Free Software Foundation with the following additional
00014 * term according to sec. 7:
00015 *
00016 * According to sec. 7 of the GNU Affero General Public License, version 3,
00017 * the terms of the AGPL are supplemented with the following terms:
00018 *
00019 * "Zarafa" is a registered trademark of Zarafa B.V.
00020 * "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
00021 * The licensing of the Program under the AGPL does not imply a trademark license.
00022 * Therefore any rights, title and interest in our trademarks remain entirely with us.
00023 *
00024 * However, if you propagate an unmodified version of the Program you are
00025 * allowed to use the term "Z-Push" to indicate that you distribute the Program.
00026 * Furthermore you may use our trademarks where it is necessary to indicate
00027 * the intended purpose of a product or service provided you use it in accordance
00028 * with honest practices in industrial or commercial matters.
00029 * If you want to propagate modified versions of the Program under the name "Z-Push",
00030 * you may only do so if you have a written permission by Zarafa Deutschland GmbH
00031 * (to acquire a permission please contact Zarafa at trademark@zarafa.com).
00032 *
00033 * This program is distributed in the hope that it will be useful,
00034 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00035 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00036 * GNU Affero General Public License for more details.
00037 *
00038 * You should have received a copy of the GNU Affero General Public License
00039 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00040 *
00041 * Consult LICENSE file for details
00042 ************************************************/
00043 
00044 class ZLog {
00045     static private $devid = '';
00046     static private $user = '';
00047     static private $authUser = false;
00048     static private $pidstr;
00049     static private $wbxmlDebug = '';
00050     static private $lastLogs = array();
00051 
00058     static public function Initialize() {
00059         global $specialLogUsers;
00060 
00061         // define some constants for the logging
00062         if (!defined('LOGUSERLEVEL'))
00063             define('LOGUSERLEVEL', LOGLEVEL_OFF);
00064 
00065         if (!defined('LOGLEVEL'))
00066             define('LOGLEVEL', LOGLEVEL_OFF);
00067 
00068         list($user,) = Utils::SplitDomainUser(Request::GetGETUser());
00069         if (!defined('WBXML_DEBUG') && $user) {
00070             // define the WBXML_DEBUG mode on user basis depending on the configurations
00071             if (LOGLEVEL >= LOGLEVEL_WBXML || (LOGUSERLEVEL >= LOGLEVEL_WBXML && in_array($user, $specialLogUsers)))
00072                 define('WBXML_DEBUG', true);
00073             else
00074                 define('WBXML_DEBUG', false);
00075         }
00076 
00077         if ($user)
00078             self::$user = '['. $user .'] ';
00079         else
00080             self::$user = '';
00081 
00082         // log the device id if the global loglevel is set to log devid or the user is in  and has the right log level
00083         if (Request::GetDeviceID() != "" && (LOGLEVEL >= LOGLEVEL_DEVICEID || (LOGUSERLEVEL >= LOGLEVEL_DEVICEID && in_array($user, $specialLogUsers))))
00084             self::$devid = '['. Request::GetDeviceID() .'] ';
00085         else
00086             self::$devid = '';
00087 
00088         return true;
00089     }
00090 
00100     static public function Write($loglevel, $message) {
00101         self::$lastLogs[$loglevel] = $message;
00102         $data = self::buildLogString($loglevel) . $message . "\n";
00103 
00104         if ($loglevel <= LOGLEVEL) {
00105             @file_put_contents(LOGFILE, $data, FILE_APPEND);
00106         }
00107 
00108         if ($loglevel <= LOGUSERLEVEL && self::logToUserFile()) {
00109             // padd level for better reading
00110             $data = str_replace(self::getLogLevelString($loglevel), self::getLogLevelString($loglevel,true), $data);
00111             // only use plain old a-z characters for the generic log file
00112             @file_put_contents(LOGFILEDIR . self::logToUserFile() . ".log", $data, FILE_APPEND);
00113         }
00114 
00115         if (($loglevel & LOGLEVEL_FATAL) || ($loglevel & LOGLEVEL_ERROR)) {
00116             @file_put_contents(LOGERRORFILE, $data, FILE_APPEND);
00117         }
00118 
00119         if ($loglevel & LOGLEVEL_WBXMLSTACK) {
00120             self::$wbxmlDebug .= $message. "\n";
00121         }
00122     }
00123 
00130     static public function GetWBXMLDebugInfo() {
00131         return trim(self::$wbxmlDebug);
00132     }
00133 
00142     static public function GetLastMessage($loglevel) {
00143         return (isset(self::$lastLogs[$loglevel]))?self::$lastLogs[$loglevel]:false;
00144     }
00145 
00156     static private function logToUserFile() {
00157         global $specialLogUsers;
00158 
00159         if (self::$authUser === false) {
00160             if (RequestProcessor::isUserAuthenticated()) {
00161                 $authuser = Request::GetAuthUser();
00162                 if ($authuser && in_array($authuser, $specialLogUsers))
00163                     self::$authUser = preg_replace('/[^a-z0-9]/', '_', strtolower($authuser));
00164             }
00165         }
00166         return self::$authUser;
00167     }
00168 
00175     static private function buildLogString($loglevel) {
00176         if (!isset(self::$pidstr))
00177             self::$pidstr = '[' . str_pad(@getmypid(),5," ",STR_PAD_LEFT) . '] ';
00178 
00179         if (!isset(self::$user))
00180             self::$user = '';
00181 
00182         if (!isset(self::$devid))
00183             self::$devid = '';
00184 
00185         return Utils::GetFormattedTime() ." ". self::$pidstr . self::$user . self::getLogLevelString($loglevel, (LOGLEVEL > LOGLEVEL_INFO)) ." ". self::$devid;
00186     }
00187 
00198     static private function getLogLevelString($loglevel, $pad = false) {
00199         if ($pad) $s = " ";
00200         else      $s = "";
00201         switch($loglevel) {
00202             case LOGLEVEL_OFF:   return ""; break;
00203             case LOGLEVEL_FATAL: return "[FATAL]"; break;
00204             case LOGLEVEL_ERROR: return "[ERROR]"; break;
00205             case LOGLEVEL_WARN:  return "[".$s."WARN]"; break;
00206             case LOGLEVEL_INFO:  return "[".$s."INFO]"; break;
00207             case LOGLEVEL_DEBUG: return "[DEBUG]"; break;
00208             case LOGLEVEL_WBXML: return "[WBXML]"; break;
00209             case LOGLEVEL_DEVICEID: return "[DEVICEID]"; break;
00210             case LOGLEVEL_WBXMLSTACK: return "[WBXMLSTACK]"; break;
00211         }
00212     }
00213 }
00214 
00219 // deprecated
00220 // backwards compatible
00221 function debugLog($message) {
00222     ZLog::Write(LOGLEVEL_DEBUG, $message);
00223 }
00224 
00225 // TODO review error handler
00226 function zarafa_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
00227     $bt = debug_backtrace();
00228     switch ($errno) {
00229         case 8192:      // E_DEPRECATED since PHP 5.3.0
00230             // do not handle this message
00231             break;
00232 
00233         case E_NOTICE:
00234         case E_WARNING:
00235             // TODO check if there is a better way to avoid these messages
00236             if (stripos($errfile,'interprocessdata') !== false && stripos($errstr,'shm_get_var()') !== false)
00237                 break;
00238             ZLog::Write(LOGLEVEL_WARN, "$errfile:$errline $errstr ($errno)");
00239             break;
00240 
00241         default:
00242             ZLog::Write(LOGLEVEL_ERROR, "trace error: $errfile:$errline $errstr ($errno) - backtrace: ". (count($bt)-1) . " steps");
00243             for($i = 1, $bt_length = count($bt); $i < $bt_length; $i++) {
00244                 $file = $line = "unknown";
00245                 if (isset($bt[$i]['file'])) $file = $bt[$i]['file'];
00246                 if (isset($bt[$i]['line'])) $line = $bt[$i]['line'];
00247                 ZLog::Write(LOGLEVEL_ERROR, "trace: $i:". $file . ":" . $line. " - " . ((isset($bt[$i]['class']))? $bt[$i]['class'] . $bt[$i]['type']:""). $bt[$i]['function']. "()");
00248             }
00249             //throw new Exception("An error occured.");
00250             break;
00251     }
00252 }
00253 
00254 error_reporting(E_ALL);
00255 set_error_handler("zarafa_error_handler");
00256 
00257 ?>