Logger.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. <?php
  2. namespace PhpLife\Frame;
  3. /**
  4. * 简单日志记录
  5. */
  6. class Logger
  7. {
  8. private static $logPath = '/www/privdata/api.makeup.meitu.com/log/';
  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
  104. * $message
  105. * @param
  106. * $filename
  107. * @return bool
  108. */
  109. public static function setLog($email = NULL, $message = "", $filename = "")
  110. {
  111. if (empty($message) || empty($filename))
  112. return false;
  113. $filename = self::getLogPath($filename);
  114. $message = "[" . date('Y-m-d H:i:s') . "]" . "-[IP:" . self::getClientIp() . "]" . "-[http://" . self::getServerIp() . $_SERVER['REQUEST_URI'] . "]" . ($email ? "-[EMAIL:$email]" : "") . "-[操作:$message]" . "\n";
  115. return error_log($message, 3, $filename);
  116. }
  117. /**
  118. * 自定义记录日志
  119. *
  120. * @param
  121. * $message
  122. * @param
  123. * $filename
  124. * @return bool
  125. */
  126. public static function logApi($message = "", $filename = "")
  127. {
  128. if (empty($message) || empty($filename))
  129. return false;
  130. $filename = self::getLogPath($filename);
  131. $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";
  132. return error_log($message, 3, $filename);
  133. }
  134. /**
  135. * 记录大数据的日志
  136. *
  137. * @param
  138. * $message
  139. * @param
  140. * $filename
  141. * @return bool
  142. */
  143. public static function bigLog($data)
  144. {
  145. if (empty($data))
  146. return false;
  147. $filename = self::getBigdataLogPath();
  148. $message = json_encode($data)."\r\n";
  149. return error_log($message, 3, $filename);
  150. }
  151. /**
  152. * 记录简单的日志内容
  153. *
  154. * @param
  155. * $message
  156. * @param
  157. * $filename
  158. * @return bool
  159. */
  160. public static function singleLog($data,$filename)
  161. {
  162. if (is_array($data)){
  163. $msg=http_build_query($data);
  164. }else {
  165. $msg=$data;
  166. }
  167. $filename = self::getLogPath($filename);
  168. $message = "[" . date('Y-m-d H:i:s') . "][".$_SERVER['REQUEST_URI'] . "]-[IP:" . self::getClientIp() . "][data:".$msg."]\r\n";
  169. return error_log($message, 3, $filename);
  170. }
  171. /**
  172. * 使用文件记录推送日志
  173. *
  174. * @param string $message
  175. * @param string $filename
  176. * @param int $logType
  177. * @return bool
  178. */
  179. private static function file($message = '', $filename = null, $logType = LOG_INFO)
  180. {
  181. if (! $filename) {
  182. $logType = intval($logType);
  183. $filename = self::$maps[$logType];
  184. }
  185. $filename = self::getLogPath($filename);
  186. $message = self::formatFields($message);
  187. return error_log($message, 3, $filename);
  188. }
  189. /**
  190. * 格式日志记录
  191. *
  192. * @param string $message
  193. * @return string
  194. */
  195. private static function formatFields($message)
  196. {
  197. if ($message instanceof \Exception) {
  198. $trace = $message->getTrace();
  199. $trace = $trace[1];
  200. $trace = ' ;trace => ' . json_encode($trace);
  201. $message = $message->getCode() . ' => ' . $message->getMessage() . $trace;
  202. } elseif ($message) {
  203. $message = (is_string($message) || is_numeric($message)) ? $message : json_encode($message);
  204. } else {
  205. $message = ' - ';
  206. }
  207. $cli = '';
  208. if (empty($_SERVER['argv'])) {
  209. $cli = "curl 'http://" . self::getServerIp() . $_SERVER['REQUEST_URI'] . "'";
  210. // 解析头信息
  211. $headers = self::getHeaders();
  212. if ($headers) {
  213. foreach ($headers as $k => $v) {
  214. $cli .= " -H '$k:$v'";
  215. }
  216. }
  217. if ($_POST) {
  218. $cli .= " -d '" . http_build_query($_POST) . "'";
  219. }
  220. if ($_COOKIE) {
  221. $cookie = array();
  222. foreach ($_COOKIE as $k => $v) {
  223. $cookie[] = $k . '=' . $v;
  224. }
  225. $cookie = implode(';', $cookie);
  226. $cli .= " -b '" . $cookie . "'";
  227. }
  228. } else {
  229. $cli = 'php ' . $_SERVER['PWD'] . DIRECTORY_SEPARATOR . implode(" ", $_SERVER['argv']);
  230. }
  231. $data = array();
  232. $data['time'] = date('Y-m-d H:i:s');
  233. $data['message'] = trim($message);
  234. $data['client_ip'] = self::getClientIp();
  235. $data['cli'] = $cli;
  236. $string = '[' . implode("] [", $data) . ']' . "\n";
  237. return $string;
  238. }
  239. /**
  240. * 获取错误等级
  241. *
  242. * @return int
  243. */
  244. private static function getLogLevel()
  245. {
  246. return self::$logLevel;
  247. }
  248. /**
  249. * 获取日志路径,如果不存在或者不可写则使用tmp路径
  250. *
  251. * @param
  252. * $filename
  253. * @return string
  254. */
  255. private static function getLogPath($filename)
  256. {
  257. static $path = '';
  258. if (! $path) {
  259. if ((! file_exists(self::$logPath))) {
  260. mkdir(self::$logPath, 0777, true);
  261. }
  262. $path = is_writable(self::$logPath) ? self::$logPath : sys_get_temp_dir();
  263. $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . date('Ym') . DIRECTORY_SEPARATOR . date('d') . DIRECTORY_SEPARATOR;
  264. if (! is_writable($path)) {
  265. if (! file_exists($path)) {
  266. mkdir($path, 0777, true);
  267. }
  268. }
  269. }
  270. $filename = strtolower(strtr($filename, array(
  271. ' ' => '',
  272. DIRECTORY_SEPARATOR => ''
  273. )));
  274. $filename = $path . $filename . '.log';
  275. return $filename;
  276. }
  277. /**
  278. * 获取日志路径,如果不存在或者不可写则使用tmp路径
  279. *
  280. * @param
  281. * $filename
  282. * @return string
  283. */
  284. private static function getBigdataLogPath()
  285. {
  286. $path = '/www/privdata/api.makeup.meitu.com/bigdata/'.date('Ymd') . DIRECTORY_SEPARATOR ;
  287. if ((! file_exists($path))) {
  288. mkdir($path, 0777, true);
  289. }
  290. $filename = date("H").'_'.self::getServerIp();
  291. $filename = $path . $filename . '.log';
  292. return $filename;
  293. }
  294. /**
  295. * 获取HTTP_HOST
  296. *
  297. * @return mixed
  298. */
  299. private static function getHost()
  300. {
  301. static $host;
  302. if (! $host) {
  303. if (isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST']) {
  304. $host = $_SERVER['HTTP_HOST'];
  305. } else {
  306. $host = 'script';
  307. }
  308. }
  309. return $host;
  310. }
  311. /**
  312. * 获取客户端Ip
  313. *
  314. * @return string|int
  315. */
  316. private static function getClientIp()
  317. {
  318. static $ip;
  319. if ($ip) {
  320. return $ip;
  321. }
  322. if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
  323. $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
  324. } elseif (isset($_SERVER["HTTP_CLIENT_IP"])) {
  325. $ip = $_SERVER["HTTP_CLIENT_IP"];
  326. } elseif (isset($_SERVER["HTTP_CLIENTIP"])) {
  327. $ip = $_SERVER["HTTP_CLIENTIP"];
  328. } elseif (isset($_SERVER["HTTP_X_REAL_IP"])) {
  329. $ip = $_SERVER["HTTP_X_REAL_IP"];
  330. } elseif (isset($_SERVER["REMOTE_ADDR"])) {
  331. $ip = $_SERVER["REMOTE_ADDR"];
  332. } else {
  333. $ip = '127.0.0.1';
  334. }
  335. $pos = strpos($ip, '|');
  336. if ($pos) {
  337. $ip = substr($ip, 0, $pos);
  338. }
  339. $ip = trim($ip);
  340. return $ip;
  341. }
  342. /**
  343. * 获取服务器IP
  344. *
  345. * @return string
  346. */
  347. private static function getServerIp()
  348. {
  349. static $ip;
  350. if ($ip) {
  351. return $ip;
  352. }
  353. if (isset($_SERVER['SERVER_ADDR'])) {
  354. $ip = $_SERVER['SERVER_ADDR'];
  355. } else {
  356. $cmd = "/sbin/ifconfig|grep 'inet addr'|awk '{print $2}'|awk -F':' '{print $2}'|awk '$1 !~ /127.0.0.1/{print}'|tail -n 1";
  357. $handle = popen($cmd, 'r');
  358. $ip = trim(fread($handle, 1024));
  359. pclose($handle);
  360. }
  361. return $ip;
  362. }
  363. /**
  364. * 获取Header信息
  365. *
  366. * @return mixed
  367. */
  368. private static function getHeaders()
  369. {
  370. return array();
  371. static $headers = array();
  372. if ($headers) {
  373. return $headers;
  374. }
  375. foreach ($_SERVER as $key => $value) {
  376. if (substr($key, 0, 5) != 'HTTP_') {
  377. continue;
  378. }
  379. $header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
  380. $headers[$header] = $value;
  381. }
  382. return $headers;
  383. }
  384. }