日志组件

This commit is contained in:
钱涛 2023-12-21 14:30:21 +08:00
parent b20a3ef103
commit 83a41da11d
19 changed files with 735 additions and 331 deletions

View File

@ -7,7 +7,7 @@ import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Component
public @interface ElogTable {
String module();

View File

@ -1,7 +1,5 @@
package com.engine.salary.elog.annotation;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
/**
@ -14,10 +12,10 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface LoggerTarget {
@AliasFor("module")
// @AliasFor("module")
String value() default "";
@AliasFor("value")
// @AliasFor("value")
String module() default "";
String function() default "common";

View File

@ -1,177 +1,177 @@
package com.engine.salary.elog.annotation.handle;
import com.weaver.common.async.producer.client.AsyncClient;
import com.weaver.common.distribution.genid.IdGenerator;
import com.weaver.common.elog.annotation.Elog;
import com.weaver.common.elog.annotation.ElogPrimaryKey;
import com.weaver.common.elog.dao.QueryCurretValusMapper;
import com.weaver.common.elog.dto.LoggerContext;
import com.weaver.common.elog.util.LoggerTemplate;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @ClassName: LoggerTargetHandler
* @Description 从Spring扫描到的类中获取到Elog自定义注解类设置function属性
* @Author tanghj
* @Date 2021/2/10 14:18
*/
@Aspect
@Component
public class ElogHandler {
@Autowired
ApplicationContext applicationContext;
@Autowired
protected AsyncClient asyncClient;
@Autowired
QueryCurretValusMapper queryCurretValusMapper;
/**
* 切面写入日志
*/
@Pointcut("@annotation(com.weaver.common.elog.annotation.Elog)" )
public void writeLog(){}
@Around("writeLog()")
public Object writeLog(ProceedingJoinPoint pjp){
Object[] args = pjp.getArgs();
Signature signature = pjp.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
Elog elog = method.getAnnotation(Elog.class);
String moduleName = elog.module();
String funtionName = elog.function();
String operateType = elog.operateType();
String operateTypeName = elog.operateTypeName();
boolean isLocal = elog.isLocal();
Annotation[][] annos = method.getParameterAnnotations();
Object id = null;
int keyPosition = -1;
int index = 0;
Class idClass = null;
// 获取主键id注解
for(Annotation[] anno : annos) {
if(anno.length > 0) {
for(Annotation annotation : anno) {
if(annotation instanceof ElogPrimaryKey) {
idClass = method.getParameters()[index].getType();
id = args[index];
if(StringUtils.isEmpty(id+"")) {
id = idClass.cast(IdGenerator.generate() + "");
}
keyPosition = index;
break;
}
}
}
index ++;
}
LoggerContext loggerContext = null;
// 获取日志实体类
for(Object arg: args) {
if(arg instanceof LoggerContext) {
loggerContext = (LoggerContext) arg;
break;
}
}
if(loggerContext == null) {
loggerContext = new LoggerContext();
}
// 日志实体类的初始化
// loggerContext.setOperateType("UPDATE");
loggerContext.setFunctionName(funtionName);
loggerContext.setModuleName(moduleName);
loggerContext.setOperateType(operateType);
loggerContext.setOperateTypeName(operateTypeName);
loggerContext.setDate(new Date());
loggerContext.setDevice("IOS");
String sql = elog.sql();
String infoMethod = elog.infoMethod();
boolean isSql = false;
boolean isMethod = false;
Object currentClass = null;
Method infoMtd = null;
if(StringUtils.isNotEmpty(id+"")) {
if(StringUtils.isNotEmpty(sql)) {
isSql = true;
Map oldValue = queryCurretValusMapper.queryValues(String.format(sql, id));
loggerContext.setOldValues(oldValue);
} else if(StringUtils.isNotEmpty(infoMethod)){
isMethod = true;
currentClass = applicationContext.getBean(pjp.getTarget().getClass());
// 获取方法
infoMtd = ReflectionUtils.findMethod(pjp.getTarget().getClass(),infoMethod, idClass);
// todo 为空的情况加异常提醒
// 反射执行方法
Object res= ReflectionUtils.invokeMethod(infoMtd,currentClass, id);
if(res != null) {
if(res instanceof List) {
loggerContext.setOldValueList((List) res);
} else {
loggerContext.setOldValues(res);
}
}
}
}
LoggerTemplate loggerTemplate = new LoggerTemplate();
loggerTemplate.setFunction(funtionName);
loggerTemplate.setModule(moduleName);
loggerTemplate.setAsyncClient(asyncClient);
Object result = null;
try {
args[keyPosition] = id;
result = pjp.proceed(args);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
if(isSql) {
Map oldValue = queryCurretValusMapper.queryValues(String.format(sql, id));
loggerContext.setNewValues(oldValue);
} else if(isMethod) {
Object res= ReflectionUtils.invokeMethod(infoMtd,currentClass, id);
if(res != null) {
if(res instanceof List) {
loggerContext.setNewValueList((List) res);
} else {
loggerContext.setNewValues(res);
}
}
}
if(isLocal)
loggerTemplate.write(loggerContext);
else
loggerTemplate.write(loggerContext,false);
return result;
}
}
//package com.engine.salary.elog.annotation.handle;
//
//import com.weaver.common.async.producer.client.AsyncClient;
//import com.weaver.common.distribution.genid.IdGenerator;
//import com.weaver.common.elog.annotation.Elog;
//import com.weaver.common.elog.annotation.ElogPrimaryKey;
//import com.weaver.common.elog.dao.QueryCurretValusMapper;
//import com.weaver.common.elog.dto.LoggerContext;
//import com.weaver.common.elog.util.LoggerTemplate;
//import org.apache.commons.lang3.StringUtils;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.Signature;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.ApplicationContext;
//import org.springframework.stereotype.Component;
//import org.springframework.util.ReflectionUtils;
//
//import java.lang.annotation.Annotation;
//import java.lang.reflect.Method;
//import java.util.Date;
//import java.util.List;
//import java.util.Map;
//
//
///**
// * @ClassName: LoggerTargetHandler
// * @Description 从Spring扫描到的类中获取到Elog自定义注解类设置function属性
// * @Author tanghj
// * @Date 2021/2/10 14:18
// */
//@Aspect
//
//public class ElogHandler {
//
// @Autowired
// ApplicationContext applicationContext;
//
// @Autowired
// protected AsyncClient asyncClient;
//
// @Autowired
// QueryCurretValusMapper queryCurretValusMapper;
//
// /**
// * 切面写入日志
// */
// @Pointcut("@annotation(com.weaver.common.elog.annotation.Elog)" )
// public void writeLog(){}
// @Around("writeLog()")
// public Object writeLog(ProceedingJoinPoint pjp){
// Object[] args = pjp.getArgs();
// Signature signature = pjp.getSignature();
// MethodSignature methodSignature = (MethodSignature) signature;
// Method method = methodSignature.getMethod();
//
// Elog elog = method.getAnnotation(Elog.class);
// String moduleName = elog.module();
// String funtionName = elog.function();
// String operateType = elog.operateType();
// String operateTypeName = elog.operateTypeName();
// boolean isLocal = elog.isLocal();
// Annotation[][] annos = method.getParameterAnnotations();
//
// Object id = null;
// int keyPosition = -1;
// int index = 0;
//
// Class idClass = null;
// // 获取主键id注解
// for(Annotation[] anno : annos) {
// if(anno.length > 0) {
// for(Annotation annotation : anno) {
// if(annotation instanceof ElogPrimaryKey) {
// idClass = method.getParameters()[index].getType();
// id = args[index];
// if(StringUtils.isEmpty(id+"")) {
// id = idClass.cast(IdGenerator.generate() + "");
// }
// keyPosition = index;
// break;
// }
// }
// }
// index ++;
// }
//
// LoggerContext loggerContext = null;
// // 获取日志实体类
// for(Object arg: args) {
// if(arg instanceof LoggerContext) {
// loggerContext = (LoggerContext) arg;
// break;
// }
// }
//
// if(loggerContext == null) {
// loggerContext = new LoggerContext();
// }
//
// // 日志实体类的初始化
// // loggerContext.setOperateType("UPDATE");
// loggerContext.setFunctionName(funtionName);
// loggerContext.setModuleName(moduleName);
// loggerContext.setOperateType(operateType);
// loggerContext.setOperateTypeName(operateTypeName);
// loggerContext.setDate(new Date());
// loggerContext.setDevice("IOS");
//
// String sql = elog.sql();
// String infoMethod = elog.infoMethod();
//
// boolean isSql = false;
// boolean isMethod = false;
// Object currentClass = null;
// Method infoMtd = null;
// if(StringUtils.isNotEmpty(id+"")) {
// if(StringUtils.isNotEmpty(sql)) {
// isSql = true;
// Map oldValue = queryCurretValusMapper.queryValues(String.format(sql, id));
// loggerContext.setOldValues(oldValue);
// } else if(StringUtils.isNotEmpty(infoMethod)){
// isMethod = true;
// currentClass = applicationContext.getBean(pjp.getTarget().getClass());
// // 获取方法
// infoMtd = ReflectionUtils.findMethod(pjp.getTarget().getClass(),infoMethod, idClass);
//
// // todo 为空的情况加异常提醒
// // 反射执行方法
// Object res= ReflectionUtils.invokeMethod(infoMtd,currentClass, id);
// if(res != null) {
// if(res instanceof List) {
// loggerContext.setOldValueList((List) res);
// } else {
// loggerContext.setOldValues(res);
// }
//
// }
// }
// }
//
// LoggerTemplate loggerTemplate = new LoggerTemplate();
// loggerTemplate.setFunction(funtionName);
// loggerTemplate.setModule(moduleName);
// loggerTemplate.setAsyncClient(asyncClient);
//
// Object result = null;
// try {
// args[keyPosition] = id;
// result = pjp.proceed(args);
// } catch (Throwable throwable) {
// throwable.printStackTrace();
// }
// if(isSql) {
// Map oldValue = queryCurretValusMapper.queryValues(String.format(sql, id));
// loggerContext.setNewValues(oldValue);
// } else if(isMethod) {
// Object res= ReflectionUtils.invokeMethod(infoMtd,currentClass, id);
// if(res != null) {
// if(res instanceof List) {
// loggerContext.setNewValueList((List) res);
// } else {
// loggerContext.setNewValues(res);
// }
// }
// }
// if(isLocal)
// loggerTemplate.write(loggerContext);
// else
// loggerTemplate.write(loggerContext,false);
// return result;
//
// }
//}

View File

@ -2,19 +2,14 @@ package com.engine.salary.elog.annotation.handle;
import com.engine.salary.elog.annotation.ElogField;
import com.engine.salary.elog.annotation.ElogTable;
import com.engine.salary.elog.dto.DateTypeEnum;
import com.engine.salary.elog.dto.TableColumnBean;
import com.engine.salary.elog.util.ElogUtils;
import com.weaver.common.elog.dao.TableCheckerMapper;
import com.weaver.common.elog.dto.DateTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
@ -29,14 +24,10 @@ import java.util.stream.Collectors;
public class ElogTableScanner {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource
private ApplicationContext applicationContext;
// private TableCheckerMapper tableCheckerMapper;
@Autowired
private TableCheckerMapper tableCheckerMapper;
@Override
public void run(String... args) throws Exception {
// @Override
public void run() throws Exception {
// todo 需要考虑集群下控制一台机器来跑
scanElogTable();
@ -45,9 +36,10 @@ public class ElogTableScanner {
private void scanElogTable() {
// todo 是否还需要扫描Elog因为可能不需要本地存储 ELogDetailTable
Map<String, Object> tableBeans = this.applicationContext.getBeansWithAnnotation(ElogTable.class);
Reflections reflections = new Reflections("com.example.controller");
Set<Class<?>> restController = reflections.getTypesAnnotatedWith(RestController.class);
// Map<String, Object> tableBeans = this.applicationContext.getBeansWithAnnotation(ElogTable.class);
Reflections reflections = new Reflections("com.engine.salary.elog");
Set<Class<?>> tableBeans = reflections.getTypesAnnotatedWith(ElogTable.class);
List<TableColumnBean> baseColumns = new ArrayList<>();
@ -67,18 +59,11 @@ public class ElogTableScanner {
}
private Map<String, List<TableColumnBean>> elogTableHandle(Map<String, Object> tableBeans, List<TableColumnBean> baseColumns) {
private Map<String, List<TableColumnBean>> elogTableHandle(Set<Class<?>> tableBeans, List<TableColumnBean> baseColumns) {
Map<String, List<TableColumnBean>> tableMap = new HashMap<>();
for (Map.Entry<String, Object> entry : tableBeans.entrySet()) {//遍历每个controller层
for (Class<?> aClass :tableBeans) {//遍历每个controller层
List<TableColumnBean> list = new ArrayList<>();
System.out.println(entry.getKey());//demo1Controller
Object value = entry.getValue();
Class<?> aClass = AopUtils.getTargetClass(value);//获取class
ElogTable elogTable = aClass.getAnnotation(ElogTable.class);
@ -101,7 +86,6 @@ public class ElogTableScanner {
list.add(tableColumnBean);
}
if(!ElogUtils.BASE_TABLE.equals(elogTable.module())) {
tableMap.put(ElogUtils.getTableName(elogTable.module(), elogTable.function()), list);
} else {
baseColumns.addAll(list);
@ -112,8 +96,8 @@ public class ElogTableScanner {
}
private void tableCheck(String tableName, List<TableColumnBean> columns) {
List<TableColumnBean> oldColumns = tableCheckerMapper.getTableStructure(tableName);
List<TableColumnBean> oldColumns = new ArrayList<>();
// List<TableColumnBean> oldColumns = tableCheckerMapper.getTableStructure(tableName);
// 表不存在
if(oldColumns == null || oldColumns.size() == 0) {
@ -147,7 +131,7 @@ public class ElogTableScanner {
sb.append(columns.stream().map( bean -> bean.toSql()).collect(Collectors.joining(",")));
sb.append(")");
logger.info("创建sql:{}",sb.toString());
tableCheckerMapper.createElogTable(sb.toString());
// tableCheckerMapper.createElogTable(sb.toString());
}
private void addColumn(String tableName, TableColumnBean tableColumnBean) {
@ -157,7 +141,7 @@ public class ElogTableScanner {
.append(" column ")
.append(tableColumnBean.toSql());
logger.info("新增字段sql:{}",sb.toString());
tableCheckerMapper.createElogTable(sb.toString());
// tableCheckerMapper.createElogTable(sb.toString());
}
private void modifyColumn(String tableName, TableColumnBean tableColumnBean) {
@ -167,6 +151,6 @@ public class ElogTableScanner {
.append(" column ")
.append(tableColumnBean.toSql());
logger.info("修改字段sql:{}",sb.toString());
tableCheckerMapper.createElogTable(sb.toString());
// tableCheckerMapper.createElogTable(sb.toString());
}
}

View File

@ -1,40 +1,38 @@
package com.engine.salary.elog.annotation.handle;
import com.weaver.common.elog.annotation.LoggerTarget;
import com.weaver.common.elog.util.LoggerTemplate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @ClassName: LoggerTargetHandler
* @Description 从Spring扫描到的类中获取到LoggerTarget自定义注解类设置function属性
* @Author tanghj
* @Date 2021/2/10 14:18
*/
@Component
public class LoggerTargetHandler implements CommandLineRunner {
@Autowired
ApplicationContext applicationContext;
@Override
public void run(String... args) throws Exception {
Map<String, Object> loggtemplateMap = applicationContext.getBeansWithAnnotation(LoggerTarget.class);
for(Object obj : loggtemplateMap.values()) {
if(obj instanceof LoggerTemplate) {
LoggerTarget loggerTarget = obj.getClass().getAnnotation(LoggerTarget.class);
((LoggerTemplate) obj).setFunction(loggerTarget.function());
((LoggerTemplate) obj).setModule(StringUtils.isNotEmpty(loggerTarget.value()) ? loggerTarget.value() : loggerTarget.module());
}
}
}
}
//package com.engine.salary.elog.annotation.handle;
//
//import com.weaver.common.elog.annotation.LoggerTarget;
//import com.weaver.common.elog.util.LoggerTemplate;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.CommandLineRunner;
//import org.springframework.context.ApplicationContext;
//import org.springframework.stereotype.Component;
//
//import java.util.Map;
//
//
///**
// * @ClassName: LoggerTargetHandler
// * @Description 从Spring扫描到的类中获取到LoggerTarget自定义注解类设置function属性
// * @Author tanghj
// * @Date 2021/2/10 14:18
// */
//
//public class LoggerTargetHandler {
//
// ApplicationContext applicationContext;
//
// @Override
// public void run(String... args) throws Exception {
// Map<String, Object> loggtemplateMap = applicationContext.getBeansWithAnnotation(LoggerTarget.class);
//
// for(Object obj : loggtemplateMap.values()) {
// if(obj instanceof LoggerTemplate) {
// LoggerTarget loggerTarget = obj.getClass().getAnnotation(LoggerTarget.class);
// ((LoggerTemplate) obj).setFunction(loggerTarget.function());
// ((LoggerTemplate) obj).setModule(StringUtils.isNotEmpty(loggerTarget.value()) ? loggerTarget.value() : loggerTarget.module());
// }
//
// }
// }
//}

View File

@ -0,0 +1,31 @@
package com.engine.salary.elog.async;
import com.alibaba.fastjson.JSON;
import com.engine.salary.elog.config.ELogTableChecker;
import com.engine.salary.elog.dto.LoggerContext;
import com.engine.salary.elog.service.LocalElogService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @ClassName: LoggerMessageListener
* @Description 本地日志存储消息队列监听类
* @Author tanghj
* @Date 2021/2/10 14:18
*/
public class LoggerMessageListener {
private final Log logger = LogFactory.getLog(getClass());
// @Autowired
LocalElogService localElogService = new LocalElogService();
// @Autowired
private ELogTableChecker eLogTableChecker = new ELogTableChecker();
public <T> String receive(LoggerContext<T> messageBean) {
logger.info("日志SDK消费到消息" + JSON.toJSONString(messageBean));
eLogTableChecker.check(messageBean);
localElogService.insertLocalElog(messageBean);
return "";
}
}

View File

@ -0,0 +1,25 @@
package com.engine.salary.elog.config;
import com.engine.salary.mapper.elog.TableCheckerMapper;
import com.engine.salary.util.db.MapperProxyFactory;
import java.util.HashMap;
import java.util.Map;
public class ELogCache {
private Map<String, Long> tableCache = new HashMap<>();
private TableCheckerMapper getTableCheckerMapper() {
return MapperProxyFactory.getProxy(TableCheckerMapper.class);
}
public Long getVersion(String mainTable) {
Long version = tableCache.get(mainTable);
if (version == null) {
version = getTableCheckerMapper().getVersion(mainTable);
tableCache.put(mainTable, version);
}
return version;
}
}

View File

@ -0,0 +1,44 @@
package com.engine.salary.elog.config;
import com.engine.salary.elog.dto.LoggerContext;
import com.engine.salary.mapper.elog.TableCheckerMapper;
import com.engine.salary.util.db.MapperProxyFactory;
import dm.jdbc.util.IdGenerator;
public class ELogTableChecker {
private static final long version = 0;
private ELogCache eLogCache = new ELogCache();
private TableCheckerMapper getTableCheckerMapper() {
return MapperProxyFactory.getProxy(TableCheckerMapper.class);
}
public <T> void check(LoggerContext<T> loggerContext) {
String module = loggerContext.getModuleName();
String function = loggerContext.getFunctionName();
String mainTable = String.format("%s_%slogs", module, function);
Long v = eLogCache.getVersion(mainTable);
boolean noTable = v == null;
if (noTable) {
this.initTable(mainTable);
v = version;
} else {
this.checkVersion(mainTable, v);
}
}
private void checkVersion(String mainTable, Long v) {
if (v == version) {
return;
}
}
private void initTable(String mainTable) {
getTableCheckerMapper().recordVersion(IdGenerator.generate(), mainTable, version);
getTableCheckerMapper().createMainTable(mainTable);
getTableCheckerMapper().createDetailTable(mainTable + "_detail");
}
}

View File

@ -0,0 +1,67 @@
//package com.engine.salary.elog.service;
//
//import org.springframework.beans.BeansException;
//import org.springframework.context.ApplicationContext;
//import org.springframework.context.ApplicationContextAware;
//import org.springframework.stereotype.Component;
//
///**
// * 获取Spring上下文
// *
// * @author tanghj
// * @date on 2020-10-19
// */
//
//public class ApplicationContextProvider implements ApplicationContextAware {
// /**
// * 上下文对象实例
// */
// private static ApplicationContext applicationContext;
//
// @Override
// public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// this.applicationContext = applicationContext;
// }
//
// /**
// * 获取applicationContext
// *
// * @return
// */
// public static ApplicationContext getApplicationContext() {
// return applicationContext;
// }
//
// /**
// * 通过name获取 Bean.
// *
// * @param name
// * @return
// */
// public static Object getBean(String name) {
// return getApplicationContext().getBean(name);
// }
//
// /**
// * 通过class获取Bean.
// *
// * @param clazz
// * @param <T>
// * @return
// */
// public static <T> T getBean(Class<T> clazz) {
// return getApplicationContext().getBean(clazz);
// }
//
// /**
// * 通过name,以及Clazz返回指定的Bean
// *
// * @param name
// * @param clazz
// * @param <T>
// * @return
// */
// public static <T> T getBean(String name, Class<T> clazz) {
// return getApplicationContext().getBean(name, clazz);
// }
//}

View File

@ -0,0 +1,74 @@
package com.engine.salary.elog.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.engine.salary.elog.dto.LoggerContext;
import com.engine.salary.elog.dto.LoggerDetailContext;
import com.engine.salary.mapper.elog.LocalElogDaoMapper;
import com.engine.salary.util.db.MapperProxyFactory;
import org.apache.commons.lang3.StringUtils;
import java.util.Set;
import java.util.UUID;
/**
* @ClassName: LocalElogService
* @Description TODO
* @Author tanghj
* @Date 2021/2/24 11:03
*/
public class LocalElogService {
private LocalElogDaoMapper getLocalElogDaoMapper() {
return MapperProxyFactory.getProxy(LocalElogDaoMapper.class);
}
public <T> int insertLocalElog(LoggerContext<T> context) {
if (StringUtils.isEmpty(context.getUuid())) {
context.setUuid(UUID.randomUUID().toString().replace("-", ""));
}
String cusColumns = "";
String cusValus = "";
if (context.getCustomInfo() != null) {
JSONObject custom = JSONObject.parseObject(JSON.toJSONString(context.getCustomInfo()));
for (String key : (Set<String>) custom.keySet()) {
cusColumns = cusColumns + ", " + key;
cusValus = cusValus + ",'" + custom.getString(key) + "'";
}
}
String params = context.getParams() == null ? null : JSONObject.toJSONString(context.getParams());
String tableName = context.getModuleName() + "_" + context.getFunctionName() + "logs";
getLocalElogDaoMapper().insertElogContext(context, params, cusColumns, cusValus, tableName);
if (context.getDetailContexts() != null) {
String detailTableName = context.getModuleName() + "_" + context.getFunctionName() + "logs_detail";
for (LoggerDetailContext detailContext : context.getDetailContexts()) {
insertElogDetail(detailContext, context.getUuid(), detailTableName);
}
}
return 1;
}
private <T> int insertElogDetail(LoggerDetailContext<T> loggerDetailContext, String mainId, String detailTableName) {
String cusColumns = "";
String cusValus = "";
if (loggerDetailContext.getCustomDetailInfo() != null) {
JSONObject custom = JSONObject.parseObject(JSON.toJSONString(loggerDetailContext.getCustomDetailInfo()));
for (String key : (Set<String>) custom.keySet()) {
cusColumns = cusColumns + ", " + key;
cusValus = cusValus + ",'" + custom.getString(key) + "'";
}
}
getLocalElogDaoMapper().insertElogDetail(loggerDetailContext, mainId, cusColumns, cusValus, detailTableName);
return 1;
}
}

View File

@ -1,14 +1,12 @@
package com.engine.salary.elog.util;
import com.alibaba.fastjson.JSONObject;
import com.weaver.common.async.bean.AsyncBean;
import com.weaver.common.async.producer.client.AsyncClient;
import com.weaver.common.elog.dto.LoggerContext;
import com.weaver.common.elog.dto.LoggerDetailContext;
import com.weaver.common.elog.dto.TableChangeBean;
import com.engine.salary.elog.async.LoggerMessageListener;
import com.engine.salary.elog.dto.LoggerContext;
import com.engine.salary.elog.dto.LoggerDetailContext;
import com.engine.salary.elog.dto.TableChangeBean;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Autowired;
import java.lang.reflect.Field;
import java.util.*;
@ -28,30 +26,25 @@ public class LoggerTemplate {
protected String localQueue;
@Autowired
protected AsyncClient asyncClient;
/**
* 写入日志消息队列
*
* @param context 日志实体
*/
public void write(LoggerContext context){
public void write(LoggerContext context) {
this.write(context, true);
}
/**
* 写入日志消息队列
*
* @param context 日志实体
* @param isLocal true 存储本地 false不存储本地
*/
public void write(LoggerContext context, boolean isLocal){
AsyncBean<LoggerContext> asyncBean = new AsyncBean<>();
public void write(LoggerContext context, boolean isLocal) {
handleContext(context);
asyncBean.setMessage(context);
asyncBean.setQueue(logCenterQueue);
asyncClient.send(asyncBean);
if(isLocal) {
asyncBean.setQueue(localQueue);
asyncClient.send(asyncBean);
if (isLocal) {
new LoggerMessageListener().receive(context);
}
}
@ -63,66 +56,66 @@ public class LoggerTemplate {
List<LoggerDetailContext> valueChangeList = new ArrayList<>();
int showOrder = 0;
if(changeBeans != null)
for(TableChangeBean changeBean : changeBeans) {
if(changeBean != null && (changeBean.getNewValue() != null || changeBean.getOldValue() != null)) {
ApiModel apiModel = null;
JSONObject newJo = new JSONObject();
JSONObject oldJo = new JSONObject();
JSONObject valueChange = JSONObject.parseObject(JSONObject.toJSONString(changeBean));
if(changeBean.getNewValue() != null) {
apiModel = changeBean.getNewValue().getClass().getAnnotation(ApiModel.class);
newJo = valueChange.getJSONObject("newValue");
} else {
apiModel = changeBean.getOldValue().getClass().getAnnotation(ApiModel.class);
}
if(changeBean.getOldValue() != null) {
oldJo = valueChange.getJSONObject("oldValue");
}
if(apiModel != null) {
Field[] fields = changeBean.getNewValue().getClass().getDeclaredFields();
for(Field field : fields) {
ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
LoggerDetailContext valueChangeBean = new LoggerDetailContext();
valueChangeBean.setTableName(changeBean.getTableName());
valueChangeBean.setFieldName(field.getName());
valueChangeBean.setFieldDesc(apiModelProperty.value());
valueChangeBean.setNewValue(newJo.getString(field.getName()));
valueChangeBean.setOldValue(oldJo.getString(field.getName()));
valueChangeBean.setShoworder(showOrder++);
valueChangeList.add(valueChangeBean);
if (changeBeans != null)
for (TableChangeBean changeBean : changeBeans) {
if (changeBean != null && (changeBean.getNewValue() != null || changeBean.getOldValue() != null)) {
ApiModel apiModel = null;
JSONObject newJo = new JSONObject();
JSONObject oldJo = new JSONObject();
JSONObject valueChange = JSONObject.parseObject(JSONObject.toJSONString(changeBean));
if (changeBean.getNewValue() != null) {
apiModel = changeBean.getNewValue().getClass().getAnnotation(ApiModel.class);
newJo = valueChange.getJSONObject("newValue");
} else {
apiModel = changeBean.getOldValue().getClass().getAnnotation(ApiModel.class);
}
} else {
Set<String> keys = new HashSet<>();
for(String key : newJo.keySet()) {
keys.add(key);
LoggerDetailContext valueChangeBean = new LoggerDetailContext();
valueChangeBean.setTableName(changeBean.getTableName());
valueChangeBean.setFieldName(key);
valueChangeBean.setFieldDesc(key);
valueChangeBean.setNewValue(newJo.getString(key));
valueChangeBean.setOldValue(oldJo.getString(key));
valueChangeBean.setShoworder(showOrder++);
valueChangeList.add(valueChangeBean);
if (changeBean.getOldValue() != null) {
oldJo = valueChange.getJSONObject("oldValue");
}
for(String key : oldJo.keySet()) {
if(keys.contains(key))
continue;
keys.add(key);
LoggerDetailContext valueChangeBean = new LoggerDetailContext();
valueChangeBean.setTableName(changeBean.getTableName());
valueChangeBean.setFieldName(key);
valueChangeBean.setFieldDesc(key);
valueChangeBean.setNewValue(newJo.getString(key));
valueChangeBean.setOldValue(oldJo.getString(key));
valueChangeBean.setShoworder(showOrder++);
valueChangeList.add(valueChangeBean);
if (apiModel != null) {
Field[] fields = changeBean.getNewValue().getClass().getDeclaredFields();
for (Field field : fields) {
ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
LoggerDetailContext valueChangeBean = new LoggerDetailContext();
valueChangeBean.setTableName(changeBean.getTableName());
valueChangeBean.setFieldName(field.getName());
valueChangeBean.setFieldDesc(apiModelProperty.value());
valueChangeBean.setNewValue(newJo.getString(field.getName()));
valueChangeBean.setOldValue(oldJo.getString(field.getName()));
valueChangeBean.setShoworder(showOrder++);
valueChangeList.add(valueChangeBean);
}
} else {
Set<String> keys = new HashSet<>();
for (String key : (Set<String>) newJo.keySet()) {
keys.add(key);
LoggerDetailContext valueChangeBean = new LoggerDetailContext();
valueChangeBean.setTableName(changeBean.getTableName());
valueChangeBean.setFieldName(key);
valueChangeBean.setFieldDesc(key);
valueChangeBean.setNewValue(newJo.getString(key));
valueChangeBean.setOldValue(oldJo.getString(key));
valueChangeBean.setShoworder(showOrder++);
valueChangeList.add(valueChangeBean);
}
for (String key : (Set<String>)oldJo.keySet()) {
if (keys.contains(key))
continue;
keys.add(key);
LoggerDetailContext valueChangeBean = new LoggerDetailContext();
valueChangeBean.setTableName(changeBean.getTableName());
valueChangeBean.setFieldName(key);
valueChangeBean.setFieldDesc(key);
valueChangeBean.setNewValue(newJo.getString(key));
valueChangeBean.setOldValue(oldJo.getString(key));
valueChangeBean.setShoworder(showOrder++);
valueChangeList.add(valueChangeBean);
}
}
}
}
}
if(valueChangeList.size() > 0)
if (valueChangeList.size() > 0)
context.setDetailContexts(valueChangeList);
}
@ -140,12 +133,13 @@ public class LoggerTemplate {
/**
* 获取日志实体类
*
* @return
*/
public LoggerContext getContext() {
LoggerContext loggerContext = new LoggerContext();
loggerContext.setUuid(UUID.randomUUID().toString().replace("-",""));
loggerContext.setUuid(UUID.randomUUID().toString().replace("-", ""));
loggerContext.setModuleName(this.module);
loggerContext.setFunctionName(this.function);
@ -157,8 +151,4 @@ public class LoggerTemplate {
this.localQueue = module + "LocalQueue";
this.module = module;
}
public void setAsyncClient(AsyncClient asyncClient) {
this.asyncClient = asyncClient;
}
}

View File

@ -12,7 +12,7 @@ import java.util.LinkedList;
import java.util.List;
@Component
public class ExcelFuncs {
protected final Logger logger = LoggerFactory.getLogger(getClass());
final static private String ALLFORM="all";

View File

@ -9,7 +9,7 @@ import java.util.HashMap;
import java.util.Map;
@Component
public class FuncDescUtil {
protected final Logger logger = LoggerFactory.getLogger(FuncDescUtil.class);
Map<String, String> funcMap = new HashMap();

View File

@ -0,0 +1,36 @@
package com.engine.salary.mapper.elog;
import com.engine.salary.elog.dto.LoggerContext;
import com.engine.salary.elog.dto.LoggerDetailContext;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* @ClassName: LocalElogDao
* @Description 本地操作日志持久层
* @Author tanghj
* @Date 2021/2/24 9:35
*/
public interface LocalElogDaoMapper {
int insertElogContext(@Param(value = "logContent") LoggerContext loggerContext,
@Param(value = "params") String params,
@Param(value = "cusColumns") String cusColumns,
@Param(value = "cusValus") String cusValus,
@Param(value = "tableName") String tableName);
List<Map<String, Object>> queryElogList(@Param(value = "logContent") LoggerContext loggerContext,
@Param("limit") String limit,
@Param(value = "tableName") String tableName);
Map<String, Object> elogCount(@Param(value = "logContent") LoggerContext loggerContext,
@Param(value = "tableName") String tableName);
int insertElogDetail(@Param(value = "detailContext") LoggerDetailContext loggerDetailContext,
@Param(value = "mainid") String mainid,
@Param(value = "cusColumns") String cusColumns,
@Param(value = "cusValus") String cusValus,
@Param(value = "detailTableName") String tableName);
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.engine.salary.mapper.elog.LocalElogDaoMapper">
<insert id="insertElogContext">
insert into ${tableName} (uuid, date, tenant_key, modulename, functionName,
operator, operatorname, targetid, targetname, interfacename, operatetype, operatedesc,
params, clientIp, groupnamelabel, redoservice, redocontext, cancelservice, cancelcontext, device, groupid
${cusColumns})
values
(#{logContent.uuid}, #{logContent.date},
#{logContent.tenant_key}, #{logContent.moduleName}, #{logContent.functionName}, #{logContent.operator}, #{logContent.operatorName}, #{logContent.targetId}
, #{logContent.targetName}, #{logContent.interfaceName}, #{logContent.operateType}, #{logContent.operatedesc},
#{params}, #{logContent.clientIp}, #{logContent.groupNameLabel}, #{logContent.redoService},
#{logContent.redoContext}, #{logContent.cancelService}, #{logContent.cancelContext}, #{logContent.device}, #{logContent.groupId}
${cusValus})
</insert>
<select id="queryElogList" resultType="java.util.Map">
select *,DATE_FORMAT(date,"%Y-%m-%d %H:%i:%S") createDate from ${tableName}
where module = #{logContent.modulename} and function = #{logContent.functionName}
order by date desc ${limit}
</select>
<select id="elogCount" resultType="java.util.Map">
select count(1) counts from ${tableName}
where module = #{logContent.modulename} and function = #{logContent.functionName}
</select>
<insert id="insertElogDetail">
insert into ${detailTableName} (mainid, uuid, tablename, fieldname, newvalue, oldvalue,
fielddesc, showorder
${cusColumns})
values(
#{mainid}, #{detailContext.uuid}, #{detailContext.tableName}, #{detailContext.fieldName}, #{detailContext.newValue},
#{detailContext.oldValue}, #{detailContext.fieldDesc}, #{detailContext.showorder}
${cusValus}
)
</insert>
</mapper>

View File

@ -0,0 +1,8 @@
package com.engine.salary.mapper.elog;
import java.util.Map;
public interface QueryCurretValusMapper {
Map queryValues(String sql);
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.engine.salary.mapper.elog.QueryCurretValusMapper">
<select id="queryValues" resultType="java.util.Map">
${querySql} limit 1
</select>
</mapper>

View File

@ -0,0 +1,20 @@
package com.engine.salary.mapper.elog;
import com.engine.salary.elog.dto.TableColumnBean;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface TableCheckerMapper {
Long getVersion(@Param("mainTable") String mainTable);
void recordVersion(@Param("id") long id, @Param("mainTable") String mainTable, @Param("version") long version);
void createMainTable(@Param("mainTable") String mainTable);
void createDetailTable(@Param("detailTable") String detailTable);
List<TableColumnBean> getTableStructure(@Param("tableName") String tableName);
void createElogTable(@Param("createElogSql") String createElogSql);
}

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.engine.salary.mapper.elog.TableCheckerMapper">
<insert id="recordVersion">
insert into elog_version (id, maintable, version)
values (#{id}, #{mainTable}, #{version});
</insert>
<select id="getVersion" resultType="java.lang.Long">
select version
from elog_version
where maintable = #{mainTable}
</select>
<update id="createMainTable">
create table ${mainTable}
(
id bigint comment 'ID',
create_time datetime,
update_time datetime,
creator bigint,
delete_type int,
tenant_key varchar(10),
uuid char(36),
date datetime,
operator varchar(50),
operatorName varchar(50),
targetId varchar(50),
targetName varchar(1000),
module varchar(100),
`function` varchar(100),
interfaceName varchar(100),
operateType varchar(50),
desc varchar(1000),
params longtext,
clientIp varchar(50),
device varchar(200),
groupNameLabel varchar(500),
redoService varchar(200),
redoContext longtext,
cancelService varchar(200),
cancelContext longtext
)
</update>
<update id="createDetailTable">
create table ${detailTable}
(
id bigint comment 'ID',
create_time datetime,
update_time datetime,
creator bigint,
delete_type int,
tenant_key varchar(10),
uuid varchar(36),
tableName varchar(200),
fieldName char(200),
newValue longtext,
oldValue longtext,
fieldDesc varchar(200),
showorder int default 0
)
</update>
<!-- 获取表结构 -->
<select id="getTableStructure" resultType="com.engine.salary.elog.dto.TableColumnBean">
SELECT COLUMN_NAME columnName,
DATA_TYPE dataTypeStr,
COLUMN_TYPE columnType,
CHARACTER_MAXIMUM_LENGTH fieldLength,
IS_NULLABLE isNullableStr,
COLUMN_DEFAULT columnDefault,
COLUMN_COMMENT columnComment
FROM INFORMATION_SCHEMA.COLUMNS
where table_name = #{tableName}
</select>
<update id="createElogTable">
${createElogSql}
</update>
</mapper>