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 }