File.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace think\log\driver;
  12. use think\Container;
  13. /**
  14. * 本地化调试输出到文件
  15. */
  16. class File
  17. {
  18. protected $config = [
  19. 'time_format' => ' c ',
  20. 'single' => false,
  21. 'file_size' => 2097152,
  22. 'path' => '',
  23. 'apart_level' => [],
  24. ];
  25. protected $writed = [];
  26. // 实例化并传入参数
  27. public function __construct($config = [])
  28. {
  29. if (is_array($config)) {
  30. $this->config = array_merge($this->config, $config);
  31. }
  32. if (empty($this->config['path'])) {
  33. $this->config['path'] = Container::get('app')->getRuntimePath() . 'log/';
  34. }
  35. }
  36. /**
  37. * 日志写入接口
  38. * @access public
  39. * @param array $log 日志信息
  40. * @return bool
  41. */
  42. public function save(array $log = [])
  43. {
  44. if ($this->config['single']) {
  45. $name = is_string($single) ? $single : 'single';
  46. $destination = $this->config['path'] . $name . '.log';
  47. } else {
  48. $cli = PHP_SAPI == 'cli' ? '_cli' : '';
  49. $destination = $this->config['path'] . date('Ym') . '/' . date('d') . $cli . '.log';
  50. }
  51. $path = dirname($destination);
  52. !is_dir($path) && mkdir($path, 0755, true);
  53. $info = '';
  54. foreach ($log as $type => $val) {
  55. $level = '';
  56. foreach ($val as $msg) {
  57. if (!is_string($msg)) {
  58. $msg = var_export($msg, true);
  59. }
  60. $level .= '[ ' . $type . ' ] ' . $msg . "\r\n";
  61. }
  62. if (in_array($type, $this->config['apart_level'])) {
  63. // 独立记录的日志级别
  64. if ($this->config['single']) {
  65. $filename = $path . '/' . $name . '_' . $type . '.log';
  66. } else {
  67. $filename = $path . '/' . date('d') . '_' . $type . $cli . '.log';
  68. }
  69. $this->write($level, $filename, true);
  70. } else {
  71. $info .= $level;
  72. }
  73. }
  74. if ($info) {
  75. return $this->write($info, $destination);
  76. }
  77. return true;
  78. }
  79. /**
  80. * 日志写入
  81. * @access protected
  82. * @param array $message 日志信息
  83. * @param string $destination 日志文件
  84. * @param bool $apart 是否独立文件写入
  85. * @return bool
  86. */
  87. protected function write($message, $destination, $apart = false)
  88. {
  89. // 检测日志文件大小,超过配置大小则备份日志文件重新生成
  90. if (is_file($destination) && floor($this->config['file_size']) <= filesize($destination)) {
  91. try {
  92. rename($destination, dirname($destination) . '/' . time() . '-' . basename($destination));
  93. } catch (\Exception $e) {
  94. }
  95. $this->writed[$destination] = false;
  96. }
  97. if (empty($this->writed[$destination]) && PHP_SAPI != 'cli') {
  98. if (Container::get('app')->isDebug() && !$apart) {
  99. // 获取基本信息
  100. $current_uri = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  101. $runtime = round(microtime(true) - Container::get('app')->getBeginTime(), 10);
  102. $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';
  103. $time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]';
  104. $memory_use = number_format((memory_get_usage() - Container::get('app')->getBeginMem()) / 1024, 2);
  105. $memory_str = ' [内存消耗:' . $memory_use . 'kb]';
  106. $file_load = ' [文件加载:' . count(get_included_files()) . ']';
  107. $message = '[ info ] ' . $current_uri . $time_str . $memory_str . $file_load . "\r\n" . $message;
  108. }
  109. $now = date($this->config['time_format']);
  110. $ip = Container::get('request')->ip();
  111. $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'CLI';
  112. $uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
  113. $message = "---------------------------------------------------------------\r\n[{$now}] {$ip} {$method} {$uri}\r\n" . $message;
  114. $this->writed[$destination] = true;
  115. }
  116. if (PHP_SAPI == 'cli') {
  117. $now = date($this->config['time_format']);
  118. $message = "[{$now}]" . $message;
  119. }
  120. return error_log($message, 3, $destination);
  121. }
  122. }