123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- <?php
- /**
- * Created by hnh.
- * Email: 1123416584@qq.com
- * Blog: blog.hnh117.com
- */
- namespace app\admin\library;
- class Log
- {
- protected $dir = null;
- protected $config = null;
- protected $error = null;
- // 过虑条件
- protected $filter = [];
- // 分隔符
- protected $separator = '---------------------------------------------------------------';
- public function __construct()
- {
- $config = config('log');
- $dir = $config['path'];
- $this->config = $config;
- $this->dir = rtrim($dir, DIRECTORY_SEPARATOR);
- }
- /**
- * 删除日志根据ID
- * @param $file_path 日志文件路径
- * @param $ids 要删除的ID
- * @return bool 成功返回true,失败返回false
- */
- public function deleteForId($file_path, $ids)
- {
- $ids = is_array($ids) ? $ids : compact('ids');
- $logArry = $this->getLogs($file_path, []);
- foreach ($ids as $id) {
- $index = $id - 1;
- if (isset($logArry[$index])) {
- unset($logArry[$index]);
- }
- }
- $logStr = '';
- foreach ($logArry as $item) {
- $logStr .= $this->separator.$item['content'];
- }
- $path = $this->complementLogPath($file_path);
- file_put_contents($path, $logStr);
- return true;
- }
- /**
- * 获取日志信息
- */
- public function getInfo($file_path)
- {
- $path = $this->complementLogPath($file_path);
- if (false === $path) {
- return false;
- }
- $info['size'] = format_bytes(filesize($path));
- $info['update_time'] = date('Y-m-d H:i:s', filemtime($path));
- return $info;
- }
- /**
- * 根据文件相对路径补全路径,自动做安全判断
- *
- * @param $file
- * @return bool|string
- */
- public function complementLogPath($file)
- {
- $path = $this->dir . $file;
- if (strpos($file, '.') === 0 || false !== strpos($file, '..') || is_dir($path)) {
- return false;
- }
- return $path;
- }
- /**
- * 获取日志
- */
- public function getLogs($file_path, $filter)
- {
- $this->filter = $filter;
- $path = $this->complementLogPath($file_path);
- if (false === $path) {
- return false;
- }
- $strlogs = file_get_contents($path);
- $arr = explode($this->separator, $strlogs);
- unset($arr[0]);
- $row = [];
- $levels = [
- 'ERROR' => '[ error ]',
- 'NOTICE' => '[ notice ]',
- 'INFO' => '[ info ]',
- 'DEBUG' => '[ debug ]',
- 'SQL' => '[ sql ]',
- 'LOG' => '[ log ]',
- ];
- foreach ($arr as $k => $v) {
- $regex = '/\[\s(\d+-\d+-\d+T\d+:\d+:\d+).{6}\s\]\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s([A-Z]{3,8})\s(.+)/';
- preg_match($regex, $v, $matches);
- $item['id'] = $k;
- $item['time'] = $matches[1];
- $item['ip'] = $matches[2];
- $item['method'] = $matches[3];
- $item['url'] = $matches[4];
- $item['content'] = trim($v);
- $content = str_replace($matches[0], '', $v);
- foreach ($levels as $k => $v) {
- if (false !== strpos($content, $v)) {
- $item['level'] = $k;
- break;
- }
- }
- $this->filter($row, $item);
- }
- $order = isset($_GET['order']) ? $_GET['order'] : 'asc';
- if ($order == 'desc') {
- $row = array_reverse($row);
- }
- return $row;
- }
- /**
- * 过虑筛选选
- *
- * @param $row
- * @param $item
- * @return bool
- */
- public function filter(&$row, $item)
- {
- $filter = $this->filter;
- if (empty($filter)) {
- $row[] = $item;
- return true;
- }
- if (isset($filter['level']) && $filter['level'] != strtolower($item['level'])) {
- return false;
- }
- if (isset($filter['method']) && $filter['method'] != strtolower($item['method'])) {
- return false;
- }
- if (isset($filter['url']) && !strpos($item['url'], $filter['url'])) {
- return false;
- }
- if (isset($filter['time'])) {
- $itemTimeInt = strtotime($item['time']);
- $timeArr = explode(' - ', $filter['time']);
- array_walk($timeArr, function (&$v) {
- $v = strtotime($v);
- });
- if ($timeArr[0] > $itemTimeInt || $timeArr[1] < $itemTimeInt) {
- return false;
- }
- }
- $row[] = $item;
- return true;
- }
- /**
- * 获取日志目录
- *
- * @return array|bool
- */
- public function getDirectory()
- {
- $directory = $this->getSelectedDirectory();
- return $directory;
- }
- /**
- * 获取选中最新日志的文件目录
- *
- * @return mixed
- */
- public function getSelectedDirectory()
- {
- $directory = $this->directory($this->dir);
- $directory = array_filter($directory, function ($item) {
- return !empty($item['children']);
- });
- $directory = array_merge($directory);
- return $this->setSelected($directory);
- }
- /**
- * (简单)自动选中最新日志
- *
- * @param $directory $array 日志目录数组
- * @return mixed
- */
- public function setSelected($directory)
- {
- $last = count($directory) - 1;
- if (empty($directory[$last])) {
- return false;
- }
- if ($directory[$last]['type'] == 'folder') {
- if ($directory[$last]['children'] != []) {
- $directory[$last]['children'] = $this->setSelected($directory[$last]['children']);
- }
- } else {
- $directory[$last]['state'] = ['selected' => true];
- }
- return $directory;
- }
- /**
- * 递归获取目录
- *
- * @param $dir
- * @return array|bool
- */
- public function directory($dir)
- {
- $dir = rtrim($dir, DIRECTORY_SEPARATOR);
- if (false === is_dir($dir)) {
- return false;
- }
- $fiels = scandir($dir);
- $directory = [];
- foreach ($fiels as $k => $v) {
- if ($v == '.' || $v == '..') {
- continue;
- }
- $path = $dir . DIRECTORY_SEPARATOR . $v;
- $id = str_replace($this->dir, '', $path);
- if (is_dir($path)) {
- $directory[] = [
- 'id' => $id,
- 'text' => $v,
- 'type' => 'folder',
- 'children' => $this->directory($path),
- ];
- } else {
- $directory[] = [
- 'id' => $id,
- 'text' => $v,
- 'type' => 'file',
- ];
- }
- }
- return $directory;
- }
- // 是否可以使用
- public function isAllow()
- {
- return $this->config['type'] == 'File' ? true : $this->setError('目前仅支持 File 日志驱动。');
- }
- public function setError($err)
- {
- $this->error = $err;
- return false;
- }
- public function getError()
- {
- return $this->error;
- }
- }
|