【程序目录】修改了日志格式,增加了日志配置,增加了公共中间件,增加了业务成功和失败的日志,增加了http响应事件监听。

This commit is contained in:
leekay0218 2022-03-31 19:45:03 +08:00
parent ebc1e4b135
commit a919f029e2
8 changed files with 196 additions and 37 deletions

View File

@ -19,6 +19,7 @@ use think\exception\DbException;
use think\exception\Handle;
use think\exception\ValidateException;
use think\facade\Env;
use think\facade\Log;
use think\Response;
use Throwable;
@ -27,26 +28,42 @@ class AdminApiExceptionHandle extends Handle
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
public function report(Throwable $exception):void
{
// 使用内置的方式记录异常日志
parent::report($exception);
$data = [
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'message' => $this->getMessage($exception),
'code' => $this->getCode($exception),
];
//日志内容
$log = [
request()->adminId(), //管理员ID
request()->ip(), //客户ip
ceil(msectime() - (request()->time(true) * 1000)), //耗时(毫秒)
request()->rule()->getMethod(), //请求类型
str_replace("/", "", request()->rootUrl()), //应用
request()->baseUrl(), //路由
json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //请求参数
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //报错数据
];
Log::write(implode("|", $log), "error");
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
public function render($request, Throwable $e):Response
{
$massageData = Env::get('app_debug', false) ? [
'file' => $e->getFile(),
@ -58,7 +75,7 @@ class AdminApiExceptionHandle extends Handle
if ($e instanceof DbException) {
return app('json')->fail('数据获取失败', $massageData);
} elseif ($e instanceof AuthException || $e instanceof ValidateException || $e instanceof ApiException) {
return app('json')->make($e->getCode() ?: 400, $e->getMessage());
return app('json')->make($e->getCode() ? : 400, $e->getMessage());
} elseif ($e instanceof AdminException) {
return app('json')->fail($e->getMessage(), $massageData);
} else {

View File

@ -17,6 +17,7 @@ use crmeb\exceptions\AuthException;
use think\exception\DbException;
use think\exception\Handle;
use think\facade\Env;
use think\facade\Log;
use think\Response;
use Throwable;
use think\exception\ValidateException;
@ -26,26 +27,42 @@ class ApiExceptionHandle extends Handle
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
public function report(Throwable $exception):void
{
// 使用内置的方式记录异常日志
parent::report($exception);
$data = [
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'message' => $this->getMessage($exception),
'code' => $this->getCode($exception),
];
//日志内容
$log = [
request()->uid(), //用户ID
request()->ip(), //客户ip
ceil(msectime() - (request()->time(true) * 1000)), //耗时(毫秒)
request()->rule()->getMethod(), //请求类型
str_replace("/", "", request()->rootUrl()), //应用
request()->baseUrl(), //路由
json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //请求参数
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //报错数据
];
Log::write(implode("|", $log), "error");
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
public function render($request, Throwable $e):Response
{
// 添加自定义异常处理机制
if ($e instanceof DbException) {
@ -54,7 +71,7 @@ class ApiExceptionHandle extends Handle
'message' => $e->getMessage(),
'line' => $e->getLine(),
]);
} else if ($e instanceof AuthException || $e instanceof ApiException || $e instanceof ValidateException) {
} elseif ($e instanceof AuthException || $e instanceof ApiException || $e instanceof ValidateException) {
return app('json')->fail($e->getMessage());
} else {
return app('json')->fail('很抱歉!系统开小差了', Env::get('app_debug', false) ? [

View File

@ -19,7 +19,7 @@ return [
'listen' => [
'AppInit' => [],
'HttpRun' => [],
'HttpEnd' => [],
'HttpEnd' => [\app\listener\http\HttpEnd::class],
'LogLevel' => [],
'LogWrite' => [],
'StoreProductOrderDeliveryAfter' => [], // OrderSubscribe 送货 发送模板消息 admin模块 order.StoreOrder控制器/order.combinationOrder控制器

View File

@ -0,0 +1,38 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\http\middleware;
use app\Request;
use crmeb\interfaces\MiddlewareInterface;
/**
* Class BaseMiddleware
* @package app\api\middleware
*/
class BaseMiddleware implements MiddlewareInterface
{
public function handle(Request $request, \Closure $next, bool $force = true)
{
if (!Request::hasMacro('uid')) {
Request::macro('uid', function(){ return 0; });
}
if (!Request::hasMacro('adminId')) {
Request::macro('adminId', function(){ return 0; });
}
if (!Request::hasMacro('kefuId')) {
Request::macro('kefuId', function(){ return 0; });
}
return $next($request);
}
}

View File

@ -16,6 +16,7 @@ use crmeb\exceptions\AuthException;
use think\exception\Handle;
use think\exception\ValidateException;
use think\facade\Config;
use think\facade\Log;
use think\Response;
use Throwable;
@ -23,26 +24,42 @@ class KefuApiExceptionHandle extends Handle
{
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
public function report(Throwable $exception):void
{
// 使用内置的方式记录异常日志
parent::report($exception);
$data = [
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'message' => $this->getMessage($exception),
'code' => $this->getCode($exception),
];
//日志内容
$log = [
request()->kefuId(), //客服ID
request()->ip(), //客户ip
ceil(msectime() - (request()->time(true) * 1000)), //耗时(毫秒)
request()->rule()->getMethod(), //请求类型
str_replace("/", "", request()->rootUrl()), //应用
request()->baseUrl(), //路由
json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //请求参数
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //报错数据
];
Log::write(implode("|", $log), "error");
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
public function render($request, Throwable $e):Response
{
$massageData = Config::get('app_debug', false) ? [
'file' => $e->getFile(),
@ -54,7 +71,7 @@ class KefuApiExceptionHandle extends Handle
if ($e instanceof DbException) {
return app('json')->fail('数据获取失败', $massageData);
} elseif ($e instanceof ValidateException || $e instanceof AuthException) {
return app('json')->make($e->getCode() ?: 400, $e->getMessage());
return app('json')->make($e->getCode() ? : 400, $e->getMessage());
} else {
return app('json')->code(200)->make(400, $e->getMessage(), $massageData);
}

View File

@ -0,0 +1,63 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\listener\http;
use think\facade\Log;
use think\Response;
/**
* 订单创建事件
* Class Create
* @package app\listener\http
*/
class HttpEnd
{
public function handle(Response $response):void
{
//业务成功和失败分开存储
$status = isset($response->getData()["status"]) ? $response->getData()["status"] : 0;
if ($status == 200) {
//业务成功日志开关
if (config("log.success_close")) return;
$type = "success";
} else {
//业务失败日志开关
if (config("log.fail_close")) return;
$type = "fail";
}
//当前用户身份标识
if (!empty(request()->uid())) {
$uid = request()->uid();
} elseif (!empty(request()->adminId())) {
$uid = request()->adminId();
} elseif (!empty(request()->kefuId())) {
$uid = request()->kefuId();
} else {
$uid = 0;
}
//日志内容
$log = [
$uid, //用户ID
request()->ip(), //客户ip
ceil(msectime() - (request()->time(true) * 1000)), //耗时(毫秒)
request()->rule()->getMethod(), //请求类型
str_replace("/", "", request()->rootUrl()), //应用
request()->baseUrl(), //路由
json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //请求参数
json_encode($response->getData(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //响应数据
];
Log::write(implode("|", $log), $type);
}
}

View File

@ -14,9 +14,11 @@ return [
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
\think\middleware\SessionInit::class,
\think\middleware\SessionInit::class,
//多语言初始化
\think\middleware\LoadLangPack::class,
\think\middleware\LoadLangPack::class,
// 页面Trace调试
// \think\middleware\TraceDebug::class,
//初始化基础中间件
\app\http\middleware\BaseMiddleware::class,
];

View File

@ -15,27 +15,32 @@ use think\facade\Env;
// +----------------------------------------------------------------------
return [
// 默认日志记录通道
'default' => Env::get('log.channel', 'file'),
'default' => Env::get('log.channel', 'file'),
// 日志记录级别
'level' => ['error','warning'],
'level' => ['error', 'warning', 'fail', 'success'],
// 日志类型记录的通道 ['error'=>'email',...]
'type_channel' => [],
// 是否关闭日志写入
'close' => false,
'close' => false,
//是否关闭业务成功日志
'success_close' => false,
//是否关闭业务失败日志
'fail_close' => false,
// 日志通道列表
'channels' => [
'channels' => [
'file' => [
// 日志记录方式
'type' => 'File',
'type' => 'File',
// 日志保存目录
'path' => app()->getRuntimePath() . 'log' . DIRECTORY_SEPARATOR,
'path' => app()->getRuntimePath() . 'log' . DIRECTORY_SEPARATOR,
// 单文件日志写入
'single' => false,
'single' => false,
// 独立日志级别
'apart_level' => [],
'apart_level' => ['error', 'fail', 'success'],
// 最大日志文件数量
'max_files' => 0,
'max_files' => 0,
'time_format' => 'Y-m-d H:i:s',
'format' => '%s|%s|%s'
],
// 其它日志通道配置
],