Logger.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  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 string $message
  104. * @param string $filename
  105. * @return bool
  106. */
  107. public static function setLog($message = "", $filename = APP_DIR."/error.log"): bool
  108. {
  109. if (empty($message) || empty($filename))
  110. return false;
  111. $filename = self::getLogPath($filename);
  112. $message = "[" . date('Y-m-d H:i:s') . "]" . "-[IP:" . self::getClientIp() . "]" . "-[http://" . self::getServerIp() . $_SERVER['REQUEST_URI'] . "]" . "-[操作:$message]" . "\n";
  113. return error_log($message, 3, $filename);
  114. }
  115. /**
  116. * 自定义记录日志
  117. *
  118. * @param string $message
  119. * @param string $filename
  120. * @return bool
  121. */
  122. public static function logApi($message = "", $filename = "")
  123. {
  124. if (empty($message) || empty($filename))
  125. return false;
  126. $filename = self::getLogPath($filename);
  127. $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";
  128. return error_log($message, 3, $filename);
  129. }
  130. /**
  131. * 记录大数据的日志
  132. *
  133. * @param
  134. * $message
  135. * @param
  136. * $filename
  137. * @return bool
  138. */
  139. public static function bigLog($data)
  140. {
  141. if (empty($data))
  142. return false;
  143. $filename = self::getBigdataLogPath();
  144. $message = json_encode($data) . "\r\n";
  145. return error_log($message, 3, $filename);
  146. }
  147. /**
  148. * 记录简单的日志内容
  149. *
  150. * @param
  151. * $message
  152. * @param
  153. * $filename
  154. * @return bool
  155. */
  156. public static function singleLog($data, $filename)
  157. {
  158. if (is_array($data)) {
  159. $msg = http_build_query($data);
  160. } else {
  161. $msg = $data;
  162. }
  163. $filename = self::getLogPath($filename);
  164. $message = "[" . date('Y-m-d H:i:s') . "][" . $_SERVER['REQUEST_URI'] . "]-[IP:" . self::getClientIp() . "][data:" . $msg . "]\r\n";
  165. return error_log($message, 3, $filename);
  166. }
  167. /**
  168. * 使用文件记录推送日志
  169. *
  170. * @param string $message
  171. * @param string $filename
  172. * @param int $logType
  173. * @return bool
  174. */
  175. private static function file($message = '', $filename = null, $logType = LOG_INFO)
  176. {
  177. if (!$filename) {
  178. $logType = intval($logType);
  179. $filename = self::$maps[$logType];
  180. }
  181. $filename = self::getLogPath($filename);
  182. $message = self::formatFields($message);
  183. return error_log($message, 3, $filename);
  184. }
  185. /**
  186. * 格式日志记录
  187. *
  188. * @param string $message
  189. * @return string
  190. */
  191. private static function formatFields($message)
  192. {
  193. if ($message instanceof \Exception) {
  194. $trace = $message->getTrace();
  195. $trace = $trace[1];
  196. $trace = ' ;trace => ' . json_encode($trace);
  197. $message = $message->getCode() . ' => ' . $message->getMessage() . $trace;
  198. } elseif ($message) {
  199. $message = (is_string($message) || is_numeric($message)) ? $message : json_encode($message);
  200. } else {
  201. $message = ' - ';
  202. }
  203. $data = array();
  204. $data['time'] = date('Y-m-d H:i:s');
  205. $data['message'] = trim($message);
  206. $data['client_ip'] = self::getClientIp();
  207. $string = '[' . implode("] [", $data) . ']' . "\n";
  208. return $string;
  209. }
  210. /**
  211. * 获取错误等级
  212. *
  213. * @return int
  214. */
  215. private static function getLogLevel()
  216. {
  217. return self::$logLevel;
  218. }
  219. /**
  220. * 获取日志路径,如果不存在或者不可写则使用tmp路径
  221. *
  222. * @param
  223. * $filename
  224. * @return string
  225. */
  226. private static function getLogPath($filename)
  227. {
  228. static $path = '';
  229. if (!$path) {
  230. if ((!file_exists(self::$logPath))) {
  231. @mkdir(self::$logPath, 0777, true);
  232. }
  233. $path = is_writable(self::$logPath) ? self::$logPath : sys_get_temp_dir();
  234. $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . date('Ym') . DIRECTORY_SEPARATOR . date('d') . DIRECTORY_SEPARATOR;
  235. if (!is_writable($path)) {
  236. if (!file_exists($path)) {
  237. mkdir($path, 0777, true);
  238. }
  239. }
  240. }
  241. $filename = strtolower(strtr($filename, array(
  242. ' ' => '',
  243. DIRECTORY_SEPARATOR => ''
  244. )));
  245. $filename = $path . $filename . '.log';
  246. return $filename;
  247. }
  248. /**
  249. * 获取日志路径,如果不存在或者不可写则使用tmp路径
  250. *
  251. * @param
  252. * $filename
  253. * @return string
  254. */
  255. private static function getBigdataLogPath()
  256. {
  257. $path = '/www/privdata/api.makeup.meitu.com/bigdata/' . date('Ymd') . DIRECTORY_SEPARATOR;
  258. if ((!file_exists($path))) {
  259. mkdir($path, 0777, true);
  260. }
  261. $filename = date("H") . '_' . self::getServerIp();
  262. $filename = $path . $filename . '.log';
  263. return $filename;
  264. }
  265. /**
  266. * 获取客户端Ip
  267. *
  268. * @return string|int
  269. */
  270. private static function getClientIp()
  271. {
  272. static $ip;
  273. if ($ip) {
  274. return $ip;
  275. }
  276. if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
  277. $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
  278. } elseif (isset($_SERVER["HTTP_CLIENT_IP"])) {
  279. $ip = $_SERVER["HTTP_CLIENT_IP"];
  280. } elseif (isset($_SERVER["HTTP_CLIENTIP"])) {
  281. $ip = $_SERVER["HTTP_CLIENTIP"];
  282. } elseif (isset($_SERVER["HTTP_X_REAL_IP"])) {
  283. $ip = $_SERVER["HTTP_X_REAL_IP"];
  284. } elseif (isset($_SERVER["REMOTE_ADDR"])) {
  285. $ip = $_SERVER["REMOTE_ADDR"];
  286. } else {
  287. $ip = '127.0.0.1';
  288. }
  289. $pos = strpos($ip, '|');
  290. if ($pos) {
  291. $ip = substr($ip, 0, $pos);
  292. }
  293. $ip = trim($ip);
  294. return $ip;
  295. }
  296. /**
  297. * 获取服务器IP
  298. *
  299. * @return string
  300. */
  301. private static function getServerIp()
  302. {
  303. static $ip;
  304. if ($ip) {
  305. return $ip;
  306. }
  307. if (isset($_SERVER['SERVER_ADDR'])) {
  308. $ip = $_SERVER['SERVER_ADDR'];
  309. } else {
  310. $cmd = "/sbin/ifconfig|grep 'inet addr'|awk '{print $2}'|awk -F':' '{print $2}'|awk '$1 !~ /127.0.0.1/{print}'|tail -n 1";
  311. $handle = popen($cmd, 'r');
  312. $ip = trim(fread($handle, 1024));
  313. pclose($handle);
  314. }
  315. return $ip;
  316. }
  317. }