Skip to content

Commit

Permalink
修复 #18
Browse files Browse the repository at this point in the history
log 注解添加 condition 字段
  • Loading branch information
牟站通 committed Jun 3, 2021
1 parent d570b8c commit 77e7a21
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ public class LogRecordOps {
private String bizNo;
private String category;
private String detail;
private String condition;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,55 @@

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
* @author muzhantong
* create on 2021/2/9 2:22 下午
*/
public class LogRecordContext {

private static final InheritableThreadLocal<Map<String, Object>> variableMap = new InheritableThreadLocal<>();

private static final InheritableThreadLocal<Stack<Map<String, Object>>> variableMapStack = new InheritableThreadLocal<>();

public static void putVariable(String name, Object value) {
if (variableMap.get() == null) {
HashMap<String, Object> map = Maps.newHashMap();
map.put(name, value);
variableMap.set(map);
if (variableMapStack.get() == null) {
Stack<Map<String, Object>> stack = new Stack<>();
variableMapStack.set(stack);
}
Stack<Map<String, Object>> mapStack = variableMapStack.get();
if (mapStack.size() == 0) {
variableMapStack.get().push(new HashMap<>());
}
variableMap.get().put(name, value);
variableMapStack.get().peek().put(name, value);
}

public static Object getVariable(String key) {
Map<String, Object> variableMap = variableMapStack.get().peek();
return variableMap.get(key);
}

public static Map<String, Object> getVariables() {
return variableMap.get() == null ? Maps.newHashMap() : variableMap.get();
Stack<Map<String, Object>> mapStack = variableMapStack.get();
return mapStack.peek();
}

public static void clear() {
if (variableMap.get() != null) {
variableMap.get().clear();
if (variableMapStack.get() != null) {
variableMapStack.get().pop();
}
}

/**
* 日志使用方不需要使用到这个方法
* 每进入一个方法初始化一个 span 放入到 stack中,方法执行完后 pop 掉这个span
*/
public static void putEmptySpan() {
Stack<Map<String, Object>> mapStack = variableMapStack.get();
if (mapStack == null) {
Stack<Map<String, Object>> stack = new Stack<>();
variableMapStack.set(stack);
}
variableMapStack.get().push(Maps.newHashMap());

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@
String category() default "";

String detail() default "";

String condition() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import com.mzt.logapi.service.ILogRecordService;
import com.mzt.logapi.service.IOperatorGetService;
import com.mzt.logapi.starter.support.parse.LogRecordValueParser;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
Expand Down Expand Up @@ -39,7 +42,6 @@ public class LogRecordInterceptor extends LogRecordValueParser implements Initia

private IOperatorGetService operatorGetService;


@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
Expand All @@ -49,30 +51,26 @@ public Object invoke(MethodInvocation invocation) throws Throwable {
private Object execute(MethodInvocation invoker, Object target, Method method, Object[] args) throws Throwable {
Class<?> targetClass = getTargetClass(target);
Object ret = null;
boolean success = true;
String errorMsg = "";
Throwable throwable = null;
MethodExecuteResult methodExecuteResult = new MethodExecuteResult(true, null, "");
LogRecordContext.putEmptySpan();
try {
LogRecordContext.clear();
ret = invoker.proceed();
} catch (Exception e) {
success = false;
errorMsg = e.getMessage();
throwable = e;
methodExecuteResult = new MethodExecuteResult(false, e, e.getMessage());
}
try {
Collection<LogRecordOps> operations = getLogRecordOperationSource().computeLogRecordOperations(method, targetClass);
if (!CollectionUtils.isEmpty(operations)) {
recordExecute(ret, method, args, operations, targetClass, success, errorMsg);
recordExecute(ret, method, args, operations, targetClass, methodExecuteResult.isSuccess(), methodExecuteResult.getErrorMsg());
}
} catch (Exception t) {
//记录日志错误不要影响业务
log.error("log record parse exception", t);
} finally {
LogRecordContext.clear();
}
if (throwable != null) {
throw throwable;
if (methodExecuteResult.throwable != null) {
throw methodExecuteResult.throwable;
}
return ret;
}
Expand All @@ -86,44 +84,53 @@ private void recordExecute(Object ret, Method method, Object[] args, Collection<
action = operation.getSuccessLogTemplate();
} else {
action = operation.getFailLogTemplate();
if (StringUtils.isEmpty(action)) {
//执行失败,并且没有配失败日志模版则忽略
continue;
}
}
if (StringUtils.isEmpty(action)) {
//执行失败,并且没有配失败日志模版则忽略
continue;
}
String bizKey = operation.getBizKey();
String bizNo = operation.getBizNo();
String operatorId = operation.getOperatorId();
String category = operation.getCategory();
String detail = operation.getDetail();
String condition = operation.getCondition();
//获取需要解析的表达式
List<String> spElTemplates;
String realOperator = "";
List<String> spElTemplates = Lists.newArrayList(bizKey, bizNo, action, detail);
;
String realOperatorId = "";
if (StringUtils.isEmpty(operatorId)) {
spElTemplates = Lists.newArrayList(bizKey, bizNo, action, detail);
if (operatorGetService.getUser() == null || StringUtils.isEmpty(operatorGetService.getUser().getOperatorId())) {
throw new IllegalArgumentException("user is null");
}
realOperator = operatorGetService.getUser().getOperatorId();
realOperatorId = operatorGetService.getUser().getOperatorId();
} else {
spElTemplates = Lists.newArrayList(bizKey, bizNo, action, operatorId, detail);
}
if (!StringUtils.isEmpty(condition)) {
spElTemplates.add(condition);
}
Map<String, String> expressionValues = processTemplate(spElTemplates, ret, targetClass, method, args, errorMsg);

LogRecord logRecord = LogRecord.builder()
.tenant(tenantId)
.bizKey(expressionValues.get(bizKey))
.bizNo(expressionValues.get(bizNo))
.operator(!StringUtils.isEmpty(realOperator) ? realOperator : expressionValues.get(operatorId))
.category(category)
.detail(expressionValues.get(detail))
.action(expressionValues.get(action))
.createTime(new Date())
.build();

//save log 需要新开事务,失败日志不能因为事务回滚而丢失
Preconditions.checkNotNull(bizLogService, "bizLogService not init!!");
bizLogService.record(logRecord);
if (StringUtils.isEmpty(condition) || StringUtils.endsWithIgnoreCase(expressionValues.get(condition), "true")) {
LogRecord logRecord = LogRecord.builder()
.tenant(tenantId)
.bizKey(expressionValues.get(bizKey))
.bizNo(expressionValues.get(bizNo))
.operator(!StringUtils.isEmpty(realOperatorId) ? realOperatorId : expressionValues.get(operatorId))
.category(category)
.detail(expressionValues.get(detail))
.action(expressionValues.get(action))
.createTime(new Date())
.build();

//如果 action 为空,不记录日志
if (StringUtils.isEmpty(logRecord.getAction())) {
continue;
}
//save log 需要新开事务,失败日志不能因为事务回滚而丢失
Preconditions.checkNotNull(bizLogService, "bizLogService not init!!");
bizLogService.record(logRecord);
}
} catch (Exception t) {
log.error("log record execute exception", t);
}
Expand Down Expand Up @@ -160,4 +167,13 @@ public void afterPropertiesSet() throws Exception {
public void setOperatorGetService(IOperatorGetService operatorGetService) {
this.operatorGetService = operatorGetService;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
static class MethodExecuteResult {
private boolean success;
private Throwable throwable;
private String errorMsg;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ private LogRecordOps parseLogRecordAnnotation(AnnotatedElement ae, LogRecordAnno
.operatorId(recordAnnotation.operatorId())
.category(StringUtils.isEmpty(recordAnnotation.category()) ? recordAnnotation.prefix() : recordAnnotation.category())
.detail(recordAnnotation.detail())
.condition(recordAnnotation.condition())
.build();
validateLogRecordOperation(ae, recordOps);
return recordOps;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ public interface IOrderService {
boolean createOrder(Order order);

boolean update(Long orderId, Order order);

boolean testCondition(Long orderId, Order order, String condition);

boolean testContextCallContext(Long orderId, Order order);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
import com.mzt.logserver.beans.Order;
import com.mzt.logserver.constants.LogRecordType;
import com.mzt.logserver.service.IOrderService;
import com.mzt.logserver.service.UserQueryService;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
* @author muzhantong
* create on 2020/6/12 11:08 上午
Expand All @@ -16,6 +20,9 @@
@Slf4j
public class OrderServiceImpl implements IOrderService {

@Resource
private UserQueryService userQueryService;

/*'张三下了一个订单,购买商品「超值优惠红烧肉套餐」,下单结果:true' */
@Override
@LogRecordAnnotation(
Expand All @@ -41,4 +48,21 @@ public boolean createOrder(Order order) {
public boolean update(Long orderId, Order order) {
return false;
}

@Override
@LogRecordAnnotation(success = "更新了订单ORDER{#orderId}},更新内容为...",
prefix = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}",
detail = "{{#order.toString()}}", condition = "{{#condition == null}}")
public boolean testCondition(Long orderId, Order order, String condition) {
return false;
}

@Override
@LogRecordAnnotation(success = "更新了订单ORDER{#orderId}},更新内容为..{{#title}}}",
prefix = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}")
public boolean testContextCallContext(Long orderId, Order order) {
LogRecordContext.putVariable("title", "外层调用");
userQueryService.getUserList(Lists.newArrayList("mzt"));
return false;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.mzt.logserver.service.impl;

import com.mzt.logapi.context.LogRecordContext;
import com.mzt.logapi.starter.annotation.LogRecordAnnotation;
import com.mzt.logserver.constants.LogRecordType;
import com.mzt.logserver.service.UserQueryService;
import org.apache.catalina.User;
import org.springframework.stereotype.Service;
Expand All @@ -12,8 +15,11 @@
*/
@Service
public class UserQueryServiceImpl implements UserQueryService {

@Override
@LogRecordAnnotation(success = "获取用户列表,内层方法调用人{{#user}}", prefix = LogRecordType.ORDER, bizNo = "{{#user}}")
public List<User> getUserList(List<String> userIds) {
LogRecordContext.putVariable("user", "mzt");
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,34 @@ public void updateOrder() {
boolean ret = orderService.update(1L, order);

}

@Test
public void testCondition_打印日志() {
Order order = new Order();
order.setOrderNo("MT0000011");
order.setProductName("超值优惠红烧肉套餐");
order.setPurchaseName("张三");
boolean ret = orderService.testCondition(1L, order, null);
// 打印日志
}

@Test
public void testCondition_不打印日志() {
Order order = new Order();
order.setOrderNo("MT0000011");
order.setProductName("超值优惠红烧肉套餐");
order.setPurchaseName("张三");
boolean ret = orderService.testCondition(1L, order, "sss");
// 打印日志
}

@Test
public void testContextCallContext() {
Order order = new Order();
order.setOrderNo("MT0000011");
order.setProductName("超值优惠红烧肉套餐");
order.setPurchaseName("张三");
boolean ret = orderService.testContextCallContext(1L, order);
// 打印两条日志
}
}

0 comments on commit 77e7a21

Please sign in to comment.