Logger.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <?php
  2. namespace Heanup\Frame;
  3. /**
  4. * 简单日志记录
  5. */
  6. class Logger
  7. {
  8. private static $logPath = '/data/wwwlogs/';
  9. private static $logLevel = LOG_ERR;
  10. private static $maps = array(
  11. LOG_DEBUG => 'debug',
  12. LOG_INFO => 'info',
  13. LOG_NOTICE => 'notice',
  14. LOG_WARNING => 'warning',
  15. LOG_ERR => 'err',
  16. LOG_CRIT => 'crit',
  17. LOG_ALERT => 'alert',
  18. LOG_EMERG => 'emerg'
  19. );
  20. /**
  21. * 获取单例
  22. *
  23. * @return Logger
  24. */
  25. public static function getInstance()
  26. {
  27. static $instance = null;
  28. if (is_null($instance)) {
  29. $instance = new Logger();
  30. }
  31. return $instance;
  32. }
  33. /**
  34. * 设置日志记录错误等级
  35. *
  36. * @param int $level
  37. * @return Logger
  38. */
  39. public static function setLogLevel($level = LOG_DEBUG)
  40. {
  41. self::$logLevel = intval($level);
  42. return self::getInstance();
  43. }
  44. /**
  45. * 设置日志记录路径
  46. *
  47. * @param
  48. * $path
  49. * @return Logger
  50. */
  51. public static function setLogPath($path)
  52. {
  53. $path = trim($path);
  54. if (!empty($path) and is_writable($path)) {
  55. self::$logPath = $path;
  56. }
  57. return self::getInstance();
  58. }
  59. public static function debug($message = '', $filename = null)
  60. {
  61. return self::log($message, $filename, LOG_DEBUG);
  62. }
  63. public static function info($message = '', $filename = null)
  64. {
  65. return self::log($message, $filename, LOG_INFO);
  66. }
  67. public static function notice($message = '', $filename = null)
  68. {
  69. return self::log($message, $filename, LOG_NOTICE);
  70. }
  71. public static function warning($message = '', $filename = null)
  72. {
  73. return self::log($message, $filename, LOG_WARNING);
  74. }
  75. public static function error($message = '', $filename = null)
  76. {
  77. return self::log($message, $filename, LOG_ERR);
  78. }
  79. public static function crit($message = '', $filename = null)
  80. {
  81. return self::log($message, $filename, LOG_CRIT);
  82. }
  83. public static function alert($message = '', $filename = null)
  84. {
  85. return self::log($message, $filename, LOG_ALERT);
  86. }
  87. public static function emerg($message = '', $filename = null)
  88. {
  89. return self::log($message, $filename, LOG_EMERG);
  90. }
  91. public static function log($message = '', $filename = null, $logType = LOG_DEBUG)
  92. {
  93. // 达不到错误记录级别的不与记录,主要是线上环境忽略debug信息
  94. if ($logType > self::getLogLevel()) {
  95. return false;
  96. }
  97. self::file($message, $filename, $logType);
  98. return true;
  99. }
  100. /**
  101. * 自定义记录日志
  102. *
  103. * @param null $email
  104. * @param string $message
  105. * @param string $filename
  106. * @return bool
  107. */
  108. public static function setLog($email = NULL, $message = "", $filename = "")
  109. {
  110. if (empty($message) || empty($filename))
  111. return false;
  112. $filename = self::getLogPath($filename);
  113. $message = "[" . date('Y-m-d H:i:s') . "]" . "-[IP:" . self::getClientIp() . "]" . "-[http://" . self::getServerIp() . $_SERVER['REQUEST_URI'] . "]" . ($email ? "-[EMAIL:$email]" : "") . "-[操作:$message]" . "\n";
  114. return error_log($message, 3, $filename);
  115. }
  116. /**
  117. * 自定义记录日志
  118. *
  119. * @param string $message
  120. * @param string $filename
  121. * @return bool
  122. */
  123. public static function logApi($message = "", $filename = "")
  124. {
  125. if (empty($message) || empty($filename))
  126. return false;
  127. $filename = self::getLogPath($filename);
  128. $message = "[" . date('Y-m-d H:i:s') . "]" . "-[IP:" . self::getClientIp() . "]" . "-[http://" . self::getServerIp() . $_SERVER['REQUEST_URI'] . "]" . '[post:' . http_build_query($_POST) . ']' . '[get:' . http_build_query($_GET) . ']' . "-[msg:$message]" . "\n";
  129. return error_log($message, 3, $filename);
  130. }
  131. /**
  132. * 记录大数据的日志
  133. *
  134. * @param
  135. * $message
  136. * @param
  137. * $filename
  138. * @return bool
  139. */
  140. public static function bigLog($data)
  141. {
  142. if (empty($data))
  143. return false;
  144. $filename = self::getBigdataLogPath();
  145. $message = json_encode($data) . "\r\n";
  146. return error_log($message, 3, $filename);
  147. }
  148. /**
  149. * 记录简单的日志内容
  150. *
  151. * @param
  152. * $message
  153. * @param
  154. * $filename
  155. * @return bool
  156. */
  157. public static function singleLog($data, $filename)
  158. {
  159. if (is_array($data)) {
  160. $msg = http_build_query($data);
  161. } else {
  162. $msg = $data;
  163. }
  164. $filename = self::getLogPath($filename);
  165. $message = "[" . date('Y-m-d H:i:s') . "][" . $_SERVER['REQUEST_URI'] . "]-[IP:" . self::getClientIp() . "][data:" . $msg . "]\r\n";
  166. return error_log($message, 3, $filename);
  167. }
  168. /**
  169. * 使用文件记录推送日志
  170. *
  171. * @param string $message
  172. * @param string $filename
  173. * @param int $logType
  174. * @return bool
  175. */
  176. private static function file($message = '', $filename = null, $logType = LOG_INFO)
  177. {
  178. if (!$filename) {
  179. $logType = intval($logType);
  180. $filename = self::$maps[$logType];
  181. }
  182. $filename = self::getLogPath($filename);
  183. $message = self::formatFields($message);
  184. return error_log($message, 3, $filename);
  185. }
  186. /**
  187. * 格式日志记录
  188. *
  189. * @param string $message
  190. * @return string
  191. */
  192. private static function formatFields($message)
  193. {
  194. if ($message instanceof \Exception) {
  195. $trace = $message->getTrace();
  196. $trace = $trace[1];
  197. $trace = ' ;trace => ' . json_encode($trace);
  198. $message = $message->getCode() . ' => ' . $message->getMessage() . $trace;
  199. } elseif ($message) {
  200. $message = (is_string($message) || is_numeric($message)) ? $message : json_encode($message);
  201. } else {
  202. $message = ' - ';
  203. }
  204. $data = array();
  205. $data['time'] = date('Y-m-d H:i:s');
  206. $data['message'] = trim($message);
  207. $data['client_ip'] = self::getClientIp();
  208. $string = '[' . implode("] [", $data) . ']' . "\n";
  209. return $string;
  210. }
  211. /**
  212. * 获取错误等级
  213. *
  214. * @return int
  215. */
  216. private static function getLogLevel()
  217. {
  218. return self::$logLevel;
  219. }
  220. /**
  221. * 获取日志路径,如果不存在或者不可写则使用tmp路径
  222. *
  223. * @param
  224. * $filename
  225. * @return string
  226. */
  227. private static function getLogPath($filename)
  228. {
  229. static $path = '';
  230. if (!$path) {
  231. if ((!file_exists(self::$logPath))) {
  232. @mkdir(self::$logPath, 0777, true);
  233. }
  234. $path = is_writable(self::$logPath) ? self::$logPath : sys_get_temp_dir();
  235. $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . date('Ym') . DIRECTORY_SEPARATOR . date('d') . DIRECTORY_SEPARATOR;
  236. if (!is_writable($path)) {
  237. if (!file_exists($path)) {
  238. mkdir($path, 0777, true);
  239. }
  240. }
  241. }
  242. $filename = strtolower(strtr($filename, array(
  243. ' ' => '',
  244. DIRECTORY_SEPARATOR => ''
  245. )));
  246. $filename = $path . $filename . '.log';
  247. return $filename;
  248. }
  249. /**
  250. * 获取日志路径,如果不存在或者不可写则使用tmp路径
  251. *
  252. * @param
  253. * $filename
  254. * @return string
  255. */
  256. private static function getBigdataLogPath()
  257. {
  258. $path = '/www/privdata/api.makeup.meitu.com/bigdata/' . date('Ymd') . DIRECTORY_SEPARATOR;
  259. if ((!file_exists($path))) {
  260. mkdir($path, 0777, true);
  261. }
  262. $filename = date("H") . '_' . self::getServerIp();
  263. $filename = $path . $filename . '.log';
  264. return $filename;
  265. }
  266. /**
  267. * 获取客户端Ip
  268. *
  269. * @return string|int
  270. */
  271. private static function getClientIp()
  272. {
  273. static $ip;
  274. if ($ip) {
  275. return $ip;
  276. }
  277. if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
  278. $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
  279. } elseif (isset($_SERVER["HTTP_CLIENT_IP"])) {
  280. $ip = $_SERVER["HTTP_CLIENT_IP"];
  281. } elseif (isset($_SERVER["HTTP_CLIENTIP"])) {
  282. $ip = $_SERVER["HTTP_CLIENTIP"];
  283. } elseif (isset($_SERVER["HTTP_X_REAL_IP"])) {
  284. $ip = $_SERVER["HTTP_X_REAL_IP"];
  285. } elseif (isset($_SERVER["REMOTE_ADDR"])) {
  286. $ip = $_SERVER["REMOTE_ADDR"];
  287. } else {
  288. $ip = '127.0.0.1';
  289. }
  290. $pos = strpos($ip, '|');
  291. if ($pos) {
  292. $ip = substr($ip, 0, $pos);
  293. }
  294. $ip = trim($ip);
  295. return $ip;
  296. }
  297. /**
  298. * 获取服务器IP
  299. *
  300. * @return string
  301. */
  302. private static function getServerIp()
  303. {
  304. static $ip;
  305. if ($ip) {
  306. return $ip;
  307. }
  308. if (isset($_SERVER['SERVER_ADDR'])) {
  309. $ip = $_SERVER['SERVER_ADDR'];
  310. } else {
  311. $cmd = "/sbin/ifconfig|grep 'inet addr'|awk '{print $2}'|awk -F':' '{print $2}'|awk '$1 !~ /127.0.0.1/{print}'|tail -n 1";
  312. $handle = popen($cmd, 'r');
  313. $ip = trim(fread($handle, 1024));
  314. pclose($handle);
  315. }
  316. return $ip;
  317. }
  318. }