feat: Log Util

This commit is contained in:
2024-10-27 21:54:35 +08:00
parent a60c6ea29e
commit 5285dd6972
12 changed files with 320 additions and 13 deletions

View File

@@ -3,7 +3,7 @@
namespace App\Aspect\Admin;
use App\Exception\AdminException;
use App\Service\Admin\User\LoginService;
use App\Service\Admin\Login\LoginService;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
@@ -17,7 +17,7 @@ class AdminLoginLogAspect extends AbstractAspect
* @var array|\class-string[]
*/
public array $classes = [
// LoginService::class,
LoginService::class,
];
/**

View File

@@ -0,0 +1,91 @@
<?php
namespace App\Aspect\Admin;
use App\Exception\AdminException;
use App\Lib\Log;
use Hyperf\Context\Context;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Hyperf\Di\Exception\Exception;
use Hyperf\HttpServer\Contract\RequestInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
#[Aspect]
class AdminOperationAspect extends AbstractAspect
{
/**
* 需要切入的类
* @var array|\class-string[]
*/
public array $classes = [
'App\\Service\\Admin\\User\\*Service',
];
/**
* 需要切入的注解
* @var array
*/
public array $annotations = [];
public function __construct(
protected Log $log,
protected RequestInterface $request,
){}
/**
* @param ProceedingJoinPoint $proceedingJoinPoint
* @return mixed
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface|Exception
*/
public function process(ProceedingJoinPoint $proceedingJoinPoint): mixed
{
// 鉴权
$this->checkAuthentication();
// 写操作日志
$this->writeOperationLog();
// 在调用前进行处理
return $proceedingJoinPoint->process();
}
/**
* @return void
*/
private function checkAuthentication(): void
{
$adminId = Context::get('admin_id');
$roleId = Context::get('role_id');
//如果没有id 说明没有登录 抛出异常
if (empty($adminId) || empty($roleId)) {
throw new AdminException('请先登录');
}
//超级管理员不需要鉴权
if ($roleId == 1) return;
//todo 其他角色需要鉴权
}
/**
* 写入请求日志
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function writeOperationLog(): void
{
$post = $this->request->all();
$logParam = !$post ? '{}' : json_encode($post);
$userId = Context::get('user_id',0);
$header = json_encode($this->request->getHeaders());
// 写静态日志
$this->log->requestAdminLog("\nadmin==path:{$this->request->getPathInfo()}\nuserId:$userId\nrequestData:$logParam\nheader:$header");
}
}

View File

@@ -6,7 +6,7 @@ namespace App\Controller\Admin;
use App\Controller\AbstractController;
use App\Request\Admin\LoginRequest;
use App\Service\Admin\User\LoginService;
use App\Service\Admin\Login\LoginService;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Validation\Annotation\Scene;

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace App\Exception\Handler;
use App\Lib\Log;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
@@ -20,14 +21,18 @@ use Throwable;
class AppExceptionHandler extends ExceptionHandler
{
public function __construct(protected StdoutLoggerInterface $logger)
public function __construct(protected StdoutLoggerInterface $logger,protected Log $log)
{
}
public function handle(Throwable $throwable, ResponseInterface $response)
{
$this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile()));
$this->logger->error($throwable->getTraceAsString());
// $this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile()));
// $this->logger->error($throwable->getTraceAsString());
$this->log->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile()));
$this->log->error($throwable->getTraceAsString());
return $response->withHeader('Server', 'Hyperf')->withStatus(500)->withBody(new SwooleStream('Internal Server Error.'));
}

130
app/Lib/Log.php Normal file
View File

@@ -0,0 +1,130 @@
<?php
namespace App\Lib;
use Hyperf\Context\ApplicationContext;
use Hyperf\Logger\LoggerFactory;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
class Log
{
/**
* 获取日志类
* @param string $name
* @param string $group
* @return LoggerInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function getLogger(string $name = 'app',string $group = 'app')
{
return ApplicationContext::getContainer()->get(LoggerFactory::class)->get($name, $group);
}
/**
* info级别日志
* @param $msg
* @param array $content
* @param string $name
* @param string $group
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
function info($msg, array $content = [],string $name = 'info',string $group = 'app'): void
{
$this->getLogger($name,$group)->info($msg,$content);
}
/**
* debug级别日志
* @param $msg
* @param array $content
* @param string $name
* @param string $group
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
function debug($msg, array $content = [],string $name = 'debug',string $group = 'error'): void
{
$this->getLogger($name,$group)->debug($msg,$content);
}
/**
* notice级别的日志
* @param $msg
* @param array $content
* @param string $name
* @param string $group
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
function notice($msg, array $content = [],string $name = 'notice',string $group = 'app'): void
{
$this->getLogger($name,$group)->notice($msg,$content);
}
/**
* error级别的日志
* @param $msg
* @param array $content
* @param string $name
* @param string $group
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
function error($msg, array $content = [],string $name = 'error',string $group = 'error'): void
{
$this->getLogger($name,$group)->error($msg,$content);
}
/**
* admin 请求日志
* @param $msg
* @param string $name
* @param string $group
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
function requestAdminLog($msg, string $name = 'info', string $group = 'request-admin'): void
{
$this->getLogger($name,$group)->info($msg);
}
/**
* api 请求日志
* @param $msg
* @param string $name
* @param string $group
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
function requestApiLog($msg, string $name = 'info', string $group = 'request-api'): void
{
$this->getLogger($name,$group)->info($msg);
}
/**
* 用户级别的日志
* @param int $userId
* @param string $msg
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
function userLog(int $userId, string $msg = ''): void
{
$traces = debug_backtrace();
$class = $traces[1] ? $traces[1]['class'] : '';
$func = $traces[1] ? $traces[1]['function'] : '';
$this->info("$class::$func==$userId==" . (is_string($msg) ? $msg : json_encode($msg)));
}
}

View File

@@ -13,6 +13,7 @@ use Hyperf\DbConnection\Model\Model;
* @property string $remark
* @property int $status
* @property string $create_time
* @property string $update_time
*/
class AdminRole extends Model
{

View File

@@ -21,6 +21,7 @@ use Hyperf\DbConnection\Model\Model;
* @property int $is_del
* @property int $role_id
* @property string $create_time
* @property string $update_time
*/
class AdminUser extends Model
{
@@ -43,7 +44,7 @@ class AdminUser extends Model
const CREATED_AT = 'create_time';
const UPDATED_AT = null;
const UPDATED_AT = 'update_time';
/**
* @param $account

View File

@@ -8,7 +8,7 @@
declare(strict_types=1);
namespace App\Service\Admin\User;
namespace App\Service\Admin\Login;
use App\Cache\Redis\Admin\UserCache;
use App\Constants\Admin\UserCode;
@@ -18,7 +18,6 @@ use App\Extend\SystemUtil;
use App\Lib\Crypto\CryptoFactory;
use App\Model\AdminUser;
use App\Service\Admin\BaseService;
use Exception;
use Hyperf\Di\Annotation\Inject;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

View File

@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace App\Service\Admin\User;
use App\Exception\AdminException;
use App\Lib\Log;
use App\Model\AdminRole;
use App\Service\Admin\BaseService;
use Exception;
@@ -25,7 +26,11 @@ class RoleService extends BaseService
#[Inject]
protected AdminRole $adminRoleModel;
private string $field = 'id as role_id, name, remark, status, created_at, updated_at';
/**
* 查询字段
* @var array|string[]
*/
private array $field = ['id as role_id', 'name', 'remark', 'status', 'create_time'];
/**
* 列表

View File

@@ -10,4 +10,5 @@ declare(strict_types=1);
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
return [
App\Aspect\Admin\AdminOperationAspect::class,
];

View File

@@ -27,4 +27,76 @@ return [
],
],
],
'app' => [
'handler' => [
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
'filename' => BASE_PATH . '/runtime/logs/info/hyperf.log',
'level' => Monolog\Logger::DEBUG,
],
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'constructor' => [
'format' => null,
'dateFormat' => null,
'allowInlineLineBreaks' => true,
'ignoreEmptyContextAndExtra' => true,
],
],
],
'error' => [
'handler' => [
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
'filename' => BASE_PATH . '/runtime/logs/error/hyperf-error.log',
'level' => Monolog\Logger::DEBUG,
],
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'constructor' => [
'format' => null,
'dateFormat' => null,
'allowInlineLineBreaks' => true,
'ignoreEmptyContextAndExtra' => true,
],
],
],
'request-admin' => [
'handler' => [
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
'filename' => BASE_PATH . '/runtime/logs/request/hyperf-admin.log',
'level' => Monolog\Logger::DEBUG,
],
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'constructor' => [
'format' => null,
'dateFormat' => null,
'allowInlineLineBreaks' => true,
'ignoreEmptyContextAndExtra' => true,
],
],
],
'request-api' => [
'handler' => [
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
'filename' => BASE_PATH . '/runtime/logs/request/hyperf-api.log',
'level' => Monolog\Logger::DEBUG,
],
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'constructor' => [
'format' => null,
'dateFormat' => null,
'allowInlineLineBreaks' => true,
'ignoreEmptyContextAndExtra' => true,
],
],
],
];

View File

@@ -20,7 +20,8 @@ CREATE TABLE `app_admin_user` (
`last_login_time` datetime NOT NULL COMMENT '最后登录时间',
`is_del` tinyint(1) NOT NULL DEFAULT '1' COMMENT '用户状态 1 正常 2 删除 涉及到后台操作日志表',
`role_id` tinyint(1) NOT NULL DEFAULT '0' COMMENT '角色',
`create_time` datetime NOT NULL COMMENT '创建时间',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='后台用户表';
@@ -32,6 +33,7 @@ CREATE TABLE `app_admin_role` (
`remark` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '备注',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1=正常 2=禁用',
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;