Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
wangxiaolu-sfa-common-log
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
sfa
wangxiaolu-sfa-common-log
Commits
0c0c61bb
提交
0c0c61bb
authored
10月 09, 2024
作者:
李秋林
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
初始化代码库
上级
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
489 行增加
和
0 行删除
+489
-0
pom.xml
pom.xml
+31
-0
Log.java
src/main/java/com/sfa/common/log/annotation/Log.java
+51
-0
LogAspect.java
src/main/java/com/sfa/common/log/aspect/LogAspect.java
+249
-0
BusinessStatus.java
src/main/java/com/sfa/common/log/enums/BusinessStatus.java
+20
-0
BusinessType.java
src/main/java/com/sfa/common/log/enums/BusinessType.java
+59
-0
OperatorType.java
src/main/java/com/sfa/common/log/enums/OperatorType.java
+24
-0
PropertyPreExcludeFilter.java
...a/com/sfa/common/log/filter/PropertyPreExcludeFilter.java
+24
-0
AsyncLogService.java
...main/java/com/sfa/common/log/service/AsyncLogService.java
+29
-0
org.springframework.boot.autoconfigure.AutoConfiguration.imports
...ingframework.boot.autoconfigure.AutoConfiguration.imports
+2
-0
没有找到文件。
pom.xml
0 → 100644
浏览文件 @
0c0c61bb
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns=
"http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<parent>
<groupId>
com.wangxiaolu.sfa
</groupId>
<artifactId>
wangxiaolu-sfa-parent
</artifactId>
<version>
0.0.1
</version>
<relativePath/>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<name>
wangxiaolu-sfa-common-log
</name>
<artifactId>
wangxiaolu-sfa-common-log
</artifactId>
<version>
0.0.1
</version>
<description>
wangxiaolu-sfa-common-log日志记录
</description>
<dependencies>
<!-- RuoYi Common Security -->
<dependency>
<groupId>
com.wangxiaolu.sfa
</groupId>
<artifactId>
wangxiaolu-sfa-common-security
</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
src/main/java/com/sfa/common/log/annotation/Log.java
0 → 100644
浏览文件 @
0c0c61bb
package
com
.
sfa
.
common
.
log
.
annotation
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
com.sfa.common.log.enums.BusinessType
;
import
com.sfa.common.log.enums.OperatorType
;
/**
* 自定义操作日志记录注解
*
* @author ruoyi
*
*/
@Target
({
ElementType
.
PARAMETER
,
ElementType
.
METHOD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
public
@interface
Log
{
/**
* 模块
*/
public
String
title
()
default
""
;
/**
* 功能
*/
public
BusinessType
businessType
()
default
BusinessType
.
OTHER
;
/**
* 操作人类别
*/
public
OperatorType
operatorType
()
default
OperatorType
.
MANAGE
;
/**
* 是否保存请求的参数
*/
public
boolean
isSaveRequestData
()
default
true
;
/**
* 是否保存响应的参数
*/
public
boolean
isSaveResponseData
()
default
true
;
/**
* 排除指定的请求参数
*/
public
String
[]
excludeParamNames
()
default
{};
}
src/main/java/com/sfa/common/log/aspect/LogAspect.java
0 → 100644
浏览文件 @
0c0c61bb
package
com
.
sfa
.
common
.
log
.
aspect
;
import
java.util.Collection
;
import
java.util.Map
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.apache.commons.lang3.ArrayUtils
;
import
org.aspectj.lang.JoinPoint
;
import
org.aspectj.lang.annotation.AfterReturning
;
import
org.aspectj.lang.annotation.AfterThrowing
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.annotation.Before
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.core.NamedThreadLocal
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.stereotype.Component
;
import
org.springframework.validation.BindingResult
;
import
org.springframework.web.multipart.MultipartFile
;
import
com.alibaba.fastjson2.JSON
;
import
com.sfa.common.core.utils.ServletUtils
;
import
com.sfa.common.core.utils.StringUtils
;
import
com.sfa.common.core.utils.ip.IpUtils
;
import
com.sfa.common.log.annotation.Log
;
import
com.sfa.common.log.enums.BusinessStatus
;
import
com.sfa.common.log.filter.PropertyPreExcludeFilter
;
import
com.sfa.common.log.service.AsyncLogService
;
import
com.sfa.common.security.utils.SecurityUtils
;
import
com.sfa.system.api.domain.SysOperLog
;
/**
* 操作日志记录处理
*
* @author ruoyi
*/
@Aspect
@Component
public
class
LogAspect
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
LogAspect
.
class
);
/** 排除敏感属性字段 */
public
static
final
String
[]
EXCLUDE_PROPERTIES
=
{
"password"
,
"oldPassword"
,
"newPassword"
,
"confirmPassword"
};
/** 计算操作消耗时间 */
private
static
final
ThreadLocal
<
Long
>
TIME_THREADLOCAL
=
new
NamedThreadLocal
<
Long
>(
"Cost Time"
);
@Autowired
private
AsyncLogService
asyncLogService
;
/**
* 处理请求前执行
*/
@Before
(
value
=
"@annotation(controllerLog)"
)
public
void
boBefore
(
JoinPoint
joinPoint
,
Log
controllerLog
)
{
TIME_THREADLOCAL
.
set
(
System
.
currentTimeMillis
());
}
/**
* 处理完请求后执行
*
* @param joinPoint 切点
*/
@AfterReturning
(
pointcut
=
"@annotation(controllerLog)"
,
returning
=
"jsonResult"
)
public
void
doAfterReturning
(
JoinPoint
joinPoint
,
Log
controllerLog
,
Object
jsonResult
)
{
handleLog
(
joinPoint
,
controllerLog
,
null
,
jsonResult
);
}
/**
* 拦截异常操作
*
* @param joinPoint 切点
* @param e 异常
*/
@AfterThrowing
(
value
=
"@annotation(controllerLog)"
,
throwing
=
"e"
)
public
void
doAfterThrowing
(
JoinPoint
joinPoint
,
Log
controllerLog
,
Exception
e
)
{
handleLog
(
joinPoint
,
controllerLog
,
e
,
null
);
}
protected
void
handleLog
(
final
JoinPoint
joinPoint
,
Log
controllerLog
,
final
Exception
e
,
Object
jsonResult
)
{
try
{
// *========数据库日志=========*//
SysOperLog
operLog
=
new
SysOperLog
();
operLog
.
setStatus
(
BusinessStatus
.
SUCCESS
.
ordinal
());
// 请求的地址
String
ip
=
IpUtils
.
getIpAddr
();
operLog
.
setOperIp
(
ip
);
operLog
.
setOperUrl
(
StringUtils
.
substring
(
ServletUtils
.
getRequest
().
getRequestURI
(),
0
,
255
));
String
username
=
SecurityUtils
.
getUsername
();
if
(
StringUtils
.
isNotBlank
(
username
))
{
operLog
.
setOperName
(
username
);
}
if
(
e
!=
null
)
{
operLog
.
setStatus
(
BusinessStatus
.
FAIL
.
ordinal
());
operLog
.
setErrorMsg
(
StringUtils
.
substring
(
e
.
getMessage
(),
0
,
2000
));
}
// 设置方法名称
String
className
=
joinPoint
.
getTarget
().
getClass
().
getName
();
String
methodName
=
joinPoint
.
getSignature
().
getName
();
operLog
.
setMethod
(
className
+
"."
+
methodName
+
"()"
);
// 设置请求方式
operLog
.
setRequestMethod
(
ServletUtils
.
getRequest
().
getMethod
());
// 处理设置注解上的参数
getControllerMethodDescription
(
joinPoint
,
controllerLog
,
operLog
,
jsonResult
);
// 设置消耗时间
operLog
.
setCostTime
(
System
.
currentTimeMillis
()
-
TIME_THREADLOCAL
.
get
());
// 保存数据库
asyncLogService
.
saveSysLog
(
operLog
);
}
catch
(
Exception
exp
)
{
// 记录本地异常日志
log
.
error
(
"异常信息:{}"
,
exp
.
getMessage
());
exp
.
printStackTrace
();
}
finally
{
TIME_THREADLOCAL
.
remove
();
}
}
/**
* 获取注解中对方法的描述信息 用于Controller层注解
*
* @param log 日志
* @param operLog 操作日志
* @throws Exception
*/
public
void
getControllerMethodDescription
(
JoinPoint
joinPoint
,
Log
log
,
SysOperLog
operLog
,
Object
jsonResult
)
throws
Exception
{
// 设置action动作
operLog
.
setBusinessType
(
log
.
businessType
().
ordinal
());
// 设置标题
operLog
.
setTitle
(
log
.
title
());
// 设置操作人类别
operLog
.
setOperatorType
(
log
.
operatorType
().
ordinal
());
// 是否需要保存request,参数和值
if
(
log
.
isSaveRequestData
())
{
// 获取参数的信息,传入到数据库中。
setRequestValue
(
joinPoint
,
operLog
,
log
.
excludeParamNames
());
}
// 是否需要保存response,参数和值
if
(
log
.
isSaveResponseData
()
&&
StringUtils
.
isNotNull
(
jsonResult
))
{
operLog
.
setJsonResult
(
StringUtils
.
substring
(
JSON
.
toJSONString
(
jsonResult
),
0
,
2000
));
}
}
/**
* 获取请求的参数,放到log中
*
* @param operLog 操作日志
* @throws Exception 异常
*/
private
void
setRequestValue
(
JoinPoint
joinPoint
,
SysOperLog
operLog
,
String
[]
excludeParamNames
)
throws
Exception
{
String
requestMethod
=
operLog
.
getRequestMethod
();
Map
<?,
?>
paramsMap
=
ServletUtils
.
getParamMap
(
ServletUtils
.
getRequest
());
if
(
StringUtils
.
isEmpty
(
paramsMap
)
&&
(
HttpMethod
.
PUT
.
name
().
equals
(
requestMethod
)
||
HttpMethod
.
POST
.
name
().
equals
(
requestMethod
)))
{
String
params
=
argsArrayToString
(
joinPoint
.
getArgs
(),
excludeParamNames
);
operLog
.
setOperParam
(
StringUtils
.
substring
(
params
,
0
,
2000
));
}
else
{
operLog
.
setOperParam
(
StringUtils
.
substring
(
JSON
.
toJSONString
(
paramsMap
,
excludePropertyPreFilter
(
excludeParamNames
)),
0
,
2000
));
}
}
/**
* 参数拼装
*/
private
String
argsArrayToString
(
Object
[]
paramsArray
,
String
[]
excludeParamNames
)
{
String
params
=
""
;
if
(
paramsArray
!=
null
&&
paramsArray
.
length
>
0
)
{
for
(
Object
o
:
paramsArray
)
{
if
(
StringUtils
.
isNotNull
(
o
)
&&
!
isFilterObject
(
o
))
{
try
{
String
jsonObj
=
JSON
.
toJSONString
(
o
,
excludePropertyPreFilter
(
excludeParamNames
));
params
+=
jsonObj
.
toString
()
+
" "
;
}
catch
(
Exception
e
)
{
}
}
}
}
return
params
.
trim
();
}
/**
* 忽略敏感属性
*/
public
PropertyPreExcludeFilter
excludePropertyPreFilter
(
String
[]
excludeParamNames
)
{
return
new
PropertyPreExcludeFilter
().
addExcludes
(
ArrayUtils
.
addAll
(
EXCLUDE_PROPERTIES
,
excludeParamNames
));
}
/**
* 判断是否需要过滤的对象。
*
* @param o 对象信息。
* @return 如果是需要过滤的对象,则返回true;否则返回false。
*/
@SuppressWarnings
(
"rawtypes"
)
public
boolean
isFilterObject
(
final
Object
o
)
{
Class
<?>
clazz
=
o
.
getClass
();
if
(
clazz
.
isArray
())
{
return
clazz
.
getComponentType
().
isAssignableFrom
(
MultipartFile
.
class
);
}
else
if
(
Collection
.
class
.
isAssignableFrom
(
clazz
))
{
Collection
collection
=
(
Collection
)
o
;
for
(
Object
value
:
collection
)
{
return
value
instanceof
MultipartFile
;
}
}
else
if
(
Map
.
class
.
isAssignableFrom
(
clazz
))
{
Map
map
=
(
Map
)
o
;
for
(
Object
value
:
map
.
entrySet
())
{
Map
.
Entry
entry
=
(
Map
.
Entry
)
value
;
return
entry
.
getValue
()
instanceof
MultipartFile
;
}
}
return
o
instanceof
MultipartFile
||
o
instanceof
HttpServletRequest
||
o
instanceof
HttpServletResponse
||
o
instanceof
BindingResult
;
}
}
src/main/java/com/sfa/common/log/enums/BusinessStatus.java
0 → 100644
浏览文件 @
0c0c61bb
package
com
.
sfa
.
common
.
log
.
enums
;
/**
* 操作状态
*
* @author ruoyi
*
*/
public
enum
BusinessStatus
{
/**
* 成功
*/
SUCCESS
,
/**
* 失败
*/
FAIL
,
}
src/main/java/com/sfa/common/log/enums/BusinessType.java
0 → 100644
浏览文件 @
0c0c61bb
package
com
.
sfa
.
common
.
log
.
enums
;
/**
* 业务操作类型
*
* @author ruoyi
*/
public
enum
BusinessType
{
/**
* 其它
*/
OTHER
,
/**
* 新增
*/
INSERT
,
/**
* 修改
*/
UPDATE
,
/**
* 删除
*/
DELETE
,
/**
* 授权
*/
GRANT
,
/**
* 导出
*/
EXPORT
,
/**
* 导入
*/
IMPORT
,
/**
* 强退
*/
FORCE
,
/**
* 生成代码
*/
GENCODE
,
/**
* 清空数据
*/
CLEAN
,
}
src/main/java/com/sfa/common/log/enums/OperatorType.java
0 → 100644
浏览文件 @
0c0c61bb
package
com
.
sfa
.
common
.
log
.
enums
;
/**
* 操作人类别
*
* @author ruoyi
*/
public
enum
OperatorType
{
/**
* 其它
*/
OTHER
,
/**
* 后台用户
*/
MANAGE
,
/**
* 手机端用户
*/
MOBILE
}
src/main/java/com/sfa/common/log/filter/PropertyPreExcludeFilter.java
0 → 100644
浏览文件 @
0c0c61bb
package
com
.
sfa
.
common
.
log
.
filter
;
import
com.alibaba.fastjson2.filter.SimplePropertyPreFilter
;
/**
* 排除JSON敏感属性
*
* @author ruoyi
*/
public
class
PropertyPreExcludeFilter
extends
SimplePropertyPreFilter
{
public
PropertyPreExcludeFilter
()
{
}
public
PropertyPreExcludeFilter
addExcludes
(
String
...
filters
)
{
for
(
int
i
=
0
;
i
<
filters
.
length
;
i
++)
{
this
.
getExcludes
().
add
(
filters
[
i
]);
}
return
this
;
}
}
src/main/java/com/sfa/common/log/service/AsyncLogService.java
0 → 100644
浏览文件 @
0c0c61bb
package
com
.
sfa
.
common
.
log
.
service
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Service
;
import
com.sfa.common.core.constant.SecurityConstants
;
import
com.sfa.system.api.RemoteLogService
;
import
com.sfa.system.api.domain.SysOperLog
;
/**
* 异步调用日志服务
*
* @author ruoyi
*/
@Service
public
class
AsyncLogService
{
@Autowired
private
RemoteLogService
remoteLogService
;
/**
* 保存系统日志记录
*/
@Async
public
void
saveSysLog
(
SysOperLog
sysOperLog
)
throws
Exception
{
remoteLogService
.
saveLog
(
sysOperLog
,
SecurityConstants
.
INNER
);
}
}
src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
0 → 100644
浏览文件 @
0c0c61bb
com.sfa.common.log.service.AsyncLogService
com.sfa.common.log.aspect.LogAspect
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论