openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

Logger.class.php (4710B)


      1 <?php
      2 
      3 namespace logger;
      4 
      5 use Exception;
      6 use util\json\JSON;
      7 use util\Text;
      8 
      9 /**
     10  * Writing log messages into a log file.
     11  *
     12  * @author Jan Dankert
     13  */
     14 class Logger
     15 {
     16 	const LEVEL_TRACE = 5;
     17 	const LEVEL_DEBUG = 4;
     18 	const LEVEL_INFO  = 3;
     19 	const LEVEL_WARN  = 2;
     20 	const LEVEL_ERROR = 1;
     21 
     22 	const OUTPUT_PLAIN = 1;
     23 	const OUTPUT_JSON  = 2;
     24 
     25 	const LOG_TO_FILE      = 1;
     26 	const LOG_TO_STDOUT    = 2;
     27 	const LOG_TO_STDERR    = 4;
     28 	const LOG_TO_ERROR_LOG = 8;
     29 
     30 
     31 	public static $level = self::LEVEL_ERROR;
     32 	public static $filename = null;
     33 	public static $logto    = self::LOG_TO_ERROR_LOG;
     34 
     35 	public static $messageFormat = ['time','level','host','text'];
     36 	public static $dateFormat = 'r';
     37 	public static $nsLookup = false;
     38 	/**
     39 	 * @var null | callable
     40 	 */
     41 	public static $messageCallback = null;
     42 	public static $outputType = self::OUTPUT_PLAIN;
     43 
     44 	public static function init()
     45 	{
     46 	}
     47 
     48 
     49 	/**
     50 	 * Writes a trace message to log
     51 	 *
     52 	 * @param string|Exception message text
     53 	 */
     54 	public static function trace($message)
     55 	{
     56 		Logger::doLog(self::LEVEL_TRACE, $message);
     57 	}
     58 
     59 
     60 	/**
     61 	 * Is trace enabled?
     62 	 * @return bool
     63 	 */
     64 	public static function isTraceEnabled() {
     65 		return Logger::$level >= self::LEVEL_TRACE;
     66 	}
     67 
     68 	/**
     69 	 * Writes a debug message to log
     70 	 *
     71 	 * @param string|Exception message text
     72 	 */
     73 	public static function debug($message)
     74 	{
     75 		Logger::doLog(self::LEVEL_DEBUG, $message);
     76 	}
     77 
     78 
     79 	/**
     80 	 * Writes a information message to log
     81 	 *
     82 	 * @param string|Exception message text
     83 	 */
     84 	public static function info($message)
     85 	{
     86 		Logger::doLog(self::LEVEL_INFO, $message);
     87 	}
     88 
     89 
     90 	/**
     91 	 * Writes a warning message to log
     92 	 *
     93 	 * @param string|Exception message text
     94 	 */
     95 	public static function warn($message)
     96 	{
     97 		Logger::doLog(self::LEVEL_WARN, $message);
     98 	}
     99 
    100 
    101 	/**
    102 	 * Writes an error message to log
    103 	 *
    104 	 * @param string|Exception message text
    105 	 */
    106 	public static function error($message)
    107 	{
    108 		Logger::doLog(self::LEVEL_ERROR, $message);
    109 	}
    110 
    111 
    112 	/**
    113 	 * Writes a mesage into the log file
    114 	 *
    115 	 * @param string facility of log entry
    116 	 * @param string|Throwable message text
    117 	 */
    118 	private static function doLog($facility, $message)
    119 	{
    120 		if   ( Logger::$level < $facility )
    121 			return; // log level not reached.
    122 
    123 		if ($facility == self::LEVEL_ERROR)
    124 			$levelName = 'ERROR';
    125 		elseif ($facility == self::LEVEL_WARN)
    126 			$levelName = 'WARN';
    127 		elseif ($facility == self::LEVEL_INFO)
    128 			$levelName = 'INFO';
    129 		elseif ($facility == self::LEVEL_DEBUG)
    130 			$levelName = 'DEBUG';
    131 		elseif ($facility == self::LEVEL_TRACE)
    132 			$levelName = 'TRACE';
    133 		else
    134 			$levelName = '';
    135 
    136 		if ($message instanceof Exception)
    137 			$message = $message->getMessage()."\n".$message->__toString();
    138 
    139 		$values = array_map( function($key) use ($message, $levelName) {
    140 			switch( $key ) {
    141 				case 'host':
    142 					if (Logger::$nsLookup)
    143 						return gethostbyaddr(getenv('REMOTE_ADDR'));
    144 					else
    145 						return getenv('REMOTE_ADDR');
    146 
    147 				case 'level':
    148 					return str_pad($levelName, 5);
    149 				case 'agent':
    150 					return getenv('HTTP_USER_AGENT');
    151 				case 'time':
    152 					return date(Logger::$dateFormat);
    153 				case 'text':
    154 					return $message;
    155 
    156 				default:
    157 					if   ( Logger::$messageCallback )
    158 						return call_user_func(Logger::$messageCallback,$key);
    159 					return '';
    160 			}
    161 		}, array_combine(Logger::$messageFormat,Logger::$messageFormat) );
    162 
    163 		switch( self::$outputType ) {
    164 			case self::OUTPUT_PLAIN:
    165 			default:
    166 
    167 				$text = '';
    168 				foreach( $values as $value ) {
    169 					if   ( ! $value )
    170 						$value = '-';
    171 
    172 					if   ( $text )
    173 						$text = $text . ' ';
    174 
    175 					$text .= '"'.str_replace('"','\"',$value).'"';
    176 				}
    177 
    178 				// Mehrzeilige Meldungen werden um 1 Spalte eingerueckt, um sie maschinell
    179 				// erkennen und auswerten zu koennen.
    180 				$text = str_replace("\n", "\n ", $text);
    181 				break;
    182 
    183 			case self::OUTPUT_JSON:
    184 				$text = JSON::encode( $values );
    185 				$text = str_replace("\n", "", $text);
    186 				break;
    187 		}
    188 
    189 		$text .= "\n";
    190 
    191 		if ( Logger::$logto & self::LOG_TO_FILE ) {
    192 
    193 			// Is the file writable?
    194 			// Exception: Streams (like php://stdout) are never 'writable' :/
    195 			if ( Logger::$filename && is_writable( Logger::$filename ) ) {
    196 				// Writing to the logfile
    197 				$result = file_put_contents( Logger::$filename,$text, FILE_APPEND );
    198 
    199 				if   ( $result === FALSE )
    200 					error_log('could not write to logfile ' . Logger::$filename );
    201 			} else {
    202 				error_log('logfile ' . Logger::$filename . ' is not writable');
    203 			}
    204 		}
    205 
    206 		if ( Logger::$logto & self::LOG_TO_ERROR_LOG ) {
    207 			error_log( $text );
    208 		}
    209 		if ( Logger::$logto & self::LOG_TO_STDERR ) {
    210 			file_put_contents( 'php://stderr', $text, FILE_APPEND );
    211 		}
    212 		if ( Logger::$logto & self::LOG_TO_STDOUT ) {
    213 			file_put_contents( 'php://stdout', $text, FILE_APPEND );
    214 		}
    215 
    216 	}
    217 
    218 }