Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
kt-keystone
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Matrix
kt-keystone
Commits
cc739885
提交
cc739885
authored
7月 21, 2022
作者:
黄承天
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix(log):日志模块有关日志生成的初始功能完成:AOP自动拦截保存日志/调用方法保存日志
上级
b0dbdee9
显示空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
470 行增加
和
0 行删除
+470
-0
pom.xml
kt-log/pom.xml
+48
-0
LogApplication.java
kt-log/src/main/java/org/matrix/log/LogApplication.java
+15
-0
ForLog.java
kt-log/src/main/java/org/matrix/log/annotation/ForLog.java
+11
-0
Log.java
kt-log/src/main/java/org/matrix/log/entity/Log.java
+51
-0
Operate.java
kt-log/src/main/java/org/matrix/log/enums/Operate.java
+20
-0
LogCreator.java
kt-log/src/main/java/org/matrix/log/service/LogCreator.java
+259
-0
application.yml
kt-log/src/main/resources/application.yml
+28
-0
LogApplicationTests.java
kt-log/src/test/java/org/matrix/log/LogApplicationTests.java
+37
-0
pom.xml
pom.xml
+1
-0
没有找到文件。
kt-log/pom.xml
0 → 100644
浏览文件 @
cc739885
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<artifactId>
keystone
</artifactId>
<groupId>
org.matrix
</groupId>
<version>
1.0-SNAPSHOT
</version>
</parent>
<artifactId>
kt-log
</artifactId>
<packaging>
jar
</packaging>
<dependencies>
<dependency>
<groupId>
org.matrix
</groupId>
<artifactId>
kt-base
</artifactId>
</dependency>
<dependency>
<groupId>
org.matrix
</groupId>
<artifactId>
kt-user
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-maven-plugin
</artifactId>
</plugin>
</plugins>
</build>
</project>
kt-log/src/main/java/org/matrix/log/LogApplication.java
0 → 100644
浏览文件 @
cc739885
package
org
.
matrix
.
log
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.context.annotation.ComponentScan
;
@SpringBootApplication
@ComponentScan
(
basePackages
=
{
"org.matrix.local"
,
"org.matrix.remote"
,
"org.matrix"
})
public
class
LogApplication
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
LogApplication
.
class
,
args
);
}
}
kt-log/src/main/java/org/matrix/log/annotation/ForLog.java
0 → 100644
浏览文件 @
cc739885
package
org
.
matrix
.
log
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Target
(
ElementType
.
TYPE
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ForLog
{
}
kt-log/src/main/java/org/matrix/log/entity/Log.java
0 → 100644
浏览文件 @
cc739885
package
org
.
matrix
.
log
.
entity
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
lombok.experimental.Accessors
;
import
org.springframework.data.mongodb.core.mapping.Document
;
import
java.util.Date
;
import
java.util.List
;
/**
* @author C
* 日志实体类
* 使用MongoDB存储
*/
@Accessors
(
chain
=
true
)
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel
(
value
=
"Log对象"
,
description
=
"日志"
)
@Document
public
class
Log
{
@ApiModelProperty
(
value
=
"主键"
)
private
Long
id
;
@ApiModelProperty
(
value
=
"所属项目id"
,
position
=
1
)
private
Long
projectId
;
@ApiModelProperty
(
value
=
"所属用户id"
,
position
=
2
)
private
Long
userId
;
@ApiModelProperty
(
value
=
"所属数据id"
,
position
=
3
)
private
Long
dataId
;
@ApiModelProperty
(
value
=
"所属数据类型 等同于其java类型"
,
position
=
4
)
private
String
dataType
;
@ApiModelProperty
(
value
=
"唯一标识id"
,
position
=
5
)
private
Long
uniqueId
;
@ApiModelProperty
(
value
=
"时间"
,
position
=
6
)
private
Date
time
;
@ApiModelProperty
(
value
=
"日志内容"
,
position
=
7
)
private
List
<
String
>
contents
;
}
kt-log/src/main/java/org/matrix/log/enums/Operate.java
0 → 100644
浏览文件 @
cc739885
package
org
.
matrix
.
log
.
enums
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
@Getter
@AllArgsConstructor
public
enum
Operate
{
INSERT
(
"INSERT"
,
"数据保存"
),
UPDATE
(
"UPDATE"
,
"数据更新"
),
DELETE
(
"DELETE"
,
"数据删除"
);
private
String
name
;
private
String
text
;
}
kt-log/src/main/java/org/matrix/log/service/LogCreator.java
0 → 100644
浏览文件 @
cc739885
package
org
.
matrix
.
log
.
service
;
import
com.beust.jcommander.internal.Lists
;
import
lombok.extern.slf4j.Slf4j
;
import
org.aspectj.lang.JoinPoint
;
import
org.aspectj.lang.annotation.After
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.matrix.entity.BaseEntity
;
import
org.matrix.local.service.impl.UserService
;
import
org.matrix.log.annotation.ForLog
;
import
org.matrix.log.entity.Log
;
import
org.matrix.log.enums.Operate
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.mongodb.core.MongoTemplate
;
import
org.springframework.data.mongodb.core.query.Criteria
;
import
org.springframework.data.mongodb.core.query.Query
;
import
org.springframework.data.mongodb.core.query.Update
;
import
org.springframework.stereotype.Service
;
import
sun.reflect.generics.tree.ClassSignature
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Objects
;
/**
* @author C
* Log日志制造者
* 有关日志的所有生成方式都在此实现
* 包括:AOP/API
*/
@Slf4j
@Aspect
@Service
public
class
LogCreator
{
@Autowired
private
MongoTemplate
mongoTemplate
;
/**
* 保存一条日志
*
* @param uniqueId 唯一标识id 用于区分该条日志内容属于哪次执行操作
* @param projectId 所属项目id
* @param dataId 所属数据id
* @param dataType 所属数据类型
* @param content 日志内容
*/
public
void
saveForTest
(
Long
uniqueId
,
Long
projectId
,
Long
dataId
,
String
dataType
,
String
content
)
{
Query
query
=
Query
.
query
(
Criteria
.
where
(
"uniqueId"
).
is
(
uniqueId
))
.
addCriteria
(
Criteria
.
where
(
"projectId"
).
is
(
projectId
))
.
addCriteria
(
Criteria
.
where
(
"dataId"
).
is
(
dataId
))
.
addCriteria
(
Criteria
.
where
(
"dataType"
).
is
(
dataType
));
Log
original
=
mongoTemplate
.
findOne
(
query
,
Log
.
class
);
if
(
Objects
.
nonNull
(
original
))
{
List
<
String
>
contents
=
original
.
getContents
();
contents
.
add
(
content
);
mongoTemplate
.
upsert
(
query
,
Update
.
update
(
"contents"
,
contents
),
Log
.
class
);
}
else
{
Log
log
=
log
(
uniqueId
,
projectId
,
dataId
,
dataType
,
content
);
mongoTemplate
.
insert
(
log
);
}
}
//--------------------------------------|AOP|---------------------------------------------------
@After
(
"execution(* com.baomidou.mybatisplus.core.mapper.BaseMapper.insert(Object))"
)
private
void
insert
(
JoinPoint
joinPoint
)
{
boolean
isForLog
=
isForLog
(
actualClassType
(
joinPoint
));
if
(
isForLog
)
{
Log
log
=
log
(
joinPoint
,
Operate
.
INSERT
);
mongoTemplate
.
insert
(
log
);
}
}
@After
(
"execution(* com.baomidou.mybatisplus.core.mapper.BaseMapper.deleteById(Object))"
)
private
void
deleteById
(
JoinPoint
joinPoint
)
{
boolean
isForLog
=
isForLog
(
actualClassType
(
joinPoint
));
if
(
isForLog
)
{
Log
log
=
log
(
joinPoint
,
Operate
.
DELETE
);
mongoTemplate
.
insert
(
log
);
}
}
@After
(
"execution(* com.baomidou.mybatisplus.core.mapper.BaseMapper.updateById(Object))"
)
private
void
updateById
(
JoinPoint
joinPoint
)
{
boolean
isForLog
=
isForLog
(
actualClassType
(
joinPoint
));
if
(
isForLog
)
{
Log
log
=
log
(
joinPoint
,
Operate
.
UPDATE
);
mongoTemplate
.
insert
(
log
);
}
}
//------------------------------------|PRIVATE|-------------------------------------------------
/**
* 转换Log对象
*
* @param joinPoint 切点对象
* @param operate 操作类型枚举
* @return Log对象
*/
private
Log
log
(
JoinPoint
joinPoint
,
Operate
operate
)
{
Object
data
=
joinPoint
.
getArgs
()[
0
];
Long
userId
=
UserService
.
findNowUserId
();
Long
projectId
=
getDataProjectId
(
data
);
Long
dataId
=
getDataId
(
data
);
String
dataType
=
actualClassType
(
joinPoint
);
List
<
String
>
contents
=
Lists
.
newArrayList
(
buildContents
(
data
,
operate
));
return
new
Log
()
.
setId
(
dataId
)
.
setTime
(
new
Date
())
.
setUserId
(
userId
)
.
setProjectId
(
projectId
)
.
setDataId
(
dataId
)
.
setDataType
(
dataType
)
.
setContents
(
contents
);
}
/**
* 转换Log对象
*
* @param data log所属对象 例如被保存的User对象/被执行的Case对象
* @param content log内容
* @return Log对象
*/
private
Log
log
(
Object
data
,
String
content
)
{
Long
userId
=
UserService
.
findNowUserId
();
Long
projectId
=
getDataProjectId
(
data
);
Long
dataId
=
getDataId
(
data
);
String
dataType
=
data
.
getClass
().
getTypeName
();
return
new
Log
()
.
setId
(
dataId
)
.
setTime
(
new
Date
())
.
setUserId
(
userId
)
.
setProjectId
(
projectId
)
.
setDataId
(
dataId
)
.
setDataType
(
dataType
)
.
setContents
(
Lists
.
newArrayList
(
content
));
}
/**
* 转换Log对象
*
* @param uniqueId 唯一标识id 用于区分该条日志内容属于哪次执行操作
* @param projectId 所属项目id
* @param dataId 所属数据id
* @param dataType 所属数据类型
* @return Log对象
*/
private
Log
log
(
Long
uniqueId
,
Long
projectId
,
Long
dataId
,
String
dataType
,
String
content
)
{
Long
userId
=
UserService
.
findNowUserId
();
return
new
Log
()
.
setId
(
dataId
)
.
setTime
(
new
Date
())
.
setUserId
(
userId
)
.
setProjectId
(
projectId
)
.
setUniqueId
(
uniqueId
)
.
setDataId
(
dataId
)
.
setDataType
(
dataType
)
.
setContents
(
Lists
.
newArrayList
(
content
));
}
/**
* 获取切点所属类的泛型名称
*
* @param joinPoint 切点对象
* @return 泛型名称
* 例如:
* 切点类是BaseMapper<User>
* 则返回org.matrix.local.entity.User
*/
private
String
actualClassType
(
JoinPoint
joinPoint
)
{
//获取切点的标志
ClassSignature
signature
=
(
ClassSignature
)
joinPoint
.
getSignature
();
//获取切点的参数(数组)
Type
[]
genericInterfaces
=
signature
.
getClass
().
getGenericInterfaces
();
//取第1个为例
ParameterizedType
genericParameterType
=
(
ParameterizedType
)
genericInterfaces
[
0
];
//获取到泛型(数组)
Type
[]
actualTypeArguments
=
genericParameterType
.
getActualTypeArguments
();
return
actualTypeArguments
[
0
].
getTypeName
();
}
/**
* 该数据类型是否需要记日志
* 并非所有类型都需要被记日志
* 例如一些最下级的数据类型
*
* @param type 具体数据类型字符串 例如:org.matrix.local.entity.User
* @return bool结果
*/
private
boolean
isForLog
(
String
type
)
{
try
{
Class
<?>
clz
=
Class
.
forName
(
type
);
return
clz
.
isAnnotationPresent
(
ForLog
.
class
);
}
catch
(
ClassNotFoundException
e
)
{
log
.
warn
(
e
.
getMessage
());
return
false
;
}
}
private
final
SimpleDateFormat
simpleDateFormat
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
/**
* 制造一条日志内容字符串
*/
private
String
buildContents
(
Object
data
,
Operate
operate
)
{
String
format
=
"%s %s [%s] "
;
String
type
=
data
.
getClass
().
getName
();
String
time
=
simpleDateFormat
.
format
(
new
Date
());
return
String
.
format
(
format
,
time
,
operate
.
getName
(),
type
,
operate
.
getText
());
}
/**
* 获取对象的projectId
*
* @param data 对象
* @return 对象的projectId
*/
private
Long
getDataProjectId
(
Object
data
)
{
try
{
Class
<?>
dataClass
=
data
.
getClass
();
Field
projectIdField
=
dataClass
.
getDeclaredField
(
"projectId"
);
projectIdField
.
setAccessible
(
true
);
return
(
Long
)
projectIdField
.
get
(
data
);
}
catch
(
Exception
ignored
)
{
return
0L
;
}
}
/**
* 获取对象的id
*
* @param data 对象
* @return 对象的id
*/
private
Long
getDataId
(
Object
data
)
{
if
(
data
instanceof
Long
)
{
return
(
Long
)
data
;
}
else
if
(
data
instanceof
BaseEntity
)
{
BaseEntity
baseEntity
=
(
BaseEntity
)
data
;
return
baseEntity
.
getId
();
}
else
{
try
{
Class
<?>
dataClass
=
data
.
getClass
();
Field
idField
=
dataClass
.
getDeclaredField
(
"id"
);
idField
.
setAccessible
(
true
);
return
(
Long
)
idField
.
get
(
data
);
}
catch
(
Exception
ignored
)
{
return
0L
;
}
}
}
}
kt-log/src/main/resources/application.yml
0 → 100644
浏览文件 @
cc739885
server
:
port
:
8765
spring
:
application
:
name
:
keystone
data
:
mongodb
:
uri
:
mongodb://192.168.100.247:27017/key_stone
datasource
:
dynamic
:
primary
:
master
strict
:
true
datasource
:
master
:
driverClassName
:
com.mysql.cj.jdbc.Driver
url
:
jdbc:mysql://192.168.100.247:3306/key_stone?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username
:
root
password
:
123456
zentao
:
driverClassName
:
com.mysql.cj.jdbc.Driver
url
:
jdbc:mysql://192.168.100.247:3306/zentao?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC&&zeroDateTimeBehavior=convertToNull
username
:
root
password
:
123456
mybatis-plus
:
type-enums-package
:
org.matrix.enums
baseJsPath
:
syntaxCheck.js
kt-log/src/test/java/org/matrix/log/LogApplicationTests.java
0 → 100644
浏览文件 @
cc739885
package
org
.
matrix
.
log
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
org.junit.jupiter.api.Test
;
import
org.matrix.local.entity.User
;
import
org.matrix.local.mapper.UserMapper
;
import
org.matrix.local.service.impl.UserService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
import
java.util.Arrays
;
@SpringBootTest
class
LogApplicationTests
{
@Autowired
UserService
userService
;
@Test
void
contextLoads
()
{
userService
.
create
(
new
User
().
setAccount
(
"test"
).
setName
(
"test"
).
setPassword
(
"test"
));
}
public
static
void
main
(
String
[]
args
)
{
Type
[]
genericInterfaces
=
UserMapper
.
class
.
getGenericInterfaces
();
//取第1个为例
ParameterizedType
genericParameterType
=
(
ParameterizedType
)
genericInterfaces
[
0
];
//获取到泛型(数组)
Type
[]
actualTypeArguments
=
genericParameterType
.
getActualTypeArguments
();
System
.
out
.
println
(
actualTypeArguments
[
0
].
getClass
().
getName
());
System
.
out
.
println
(
actualTypeArguments
[
0
].
getTypeName
());
}
}
pom.xml
浏览文件 @
cc739885
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
<module>
kt-user
</module>
<module>
kt-user
</module>
<module>
kt-database
</module>
<module>
kt-database
</module>
<module>
kt-pub-service
</module>
<module>
kt-pub-service
</module>
<module>
kt-log
</module>
</modules>
</modules>
<properties>
<properties>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论