springboot 은 업무 로그 와 이상 업무 로 그 를 기록 하 는 작업 을 수행 합 니 다.
31951 단어 springboot업무 일지이상 하 다
1.주 해 를 바탕 으로 로그 기록 을 실현 하고 해당 하 는 방법 을 스 캔 하여 로그 기록 을 실현 합 니 다.
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface BussinessLog {
/**
* , :" "
*/
String value() default "";
/**
* , : "id"
*/
String key() default "id";
/**
*
*/
String type() default "0";
/**
* ( key )
*/
Class<? extends AbstractDictMap> dict() default SystemDict.class;
}
2.스 캔 방법,주 해 를 바탕 으로 로 그 를 스 캔 하고 기록 합 니 다.3.@Aspect 주석 을 기반 으로 로그 스 캔 을 실현 하고 로 그 를 기록 합 니 다.
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Map;
/**
*
*
*/
@Aspect
@Component
public class LogAop {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Pointcut(value = "@annotation(com.stylefeng.guns.core.common.annotion.BussinessLog)")
public void cutService() {
}
@Around("cutService()")
public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {
//
Object result = point.proceed();
try {
handle(point);
} catch (Exception e) {
log.error(" !", e);
}
return result;
}
private void handle(ProceedingJoinPoint point) throws Exception {
//
Signature sig = point.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException(" ");
}
msig = (MethodSignature) sig;
Object target = point.getTarget();
Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
String methodName = currentMethod.getName();
// ,
ShiroUser user = ShiroKit.getUser();
if (null == user) {
return;
}
//
String className = point.getTarget().getClass().getName();
Object[] params = point.getArgs();
//
BussinessLog annotation = currentMethod.getAnnotation(BussinessLog.class);
String bussinessName = annotation.value();
String key = annotation.key();
Class dictClass = annotation.dict();
StringBuilder sb = new StringBuilder();
for (Object param : params) {
sb.append(param);
sb.append(" & ");
}
// ,
String msg;
if (bussinessName.contains(" ") || bussinessName.contains(" ")) {
Object obj1 = LogObjectHolder.me().get();
Map<String, String> obj2 = HttpContext.getRequestParameters();
msg = Contrast.contrastObj(dictClass, key, obj1, obj2);
} else {
Map<String, String> parameters = HttpContext.getRequestParameters();
AbstractDictMap dictMap = (AbstractDictMap) dictClass.newInstance();
msg = Contrast.parseMutiKey(dictMap, key, parameters);
}
log.info("[ ][RESULT:{}]",user.getId()+bussinessName+className+methodName+msg.toString());
LogManager.me().executeLog(LogTaskFactory.bussinessLog(user.getId(), bussinessName, className, methodName, msg));
}
}
4.두 대상 의 도구 류 비교
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
/**
*
*
* @author ...
* @Date 2017/3/31 10:36
*/
public class Contrast {
//
public static final String separator = ";;;";
/**
* ,
*
* @author ...
* @Date 2017/5/9 19:34
*/
public static String contrastObj(Object pojo1, Object pojo2) {
String str = "";
try {
Class clazz = pojo1.getClass();
Field[] fields = pojo1.getClass().getDeclaredFields();
int i = 1;
for (Field field : fields) {
if ("serialVersionUID".equals(field.getName())) {
continue;
}
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
Method getMethod = pd.getReadMethod();
Object o1 = getMethod.invoke(pojo1);
Object o2 = getMethod.invoke(pojo2);
if (o1 == null || o2 == null) {
continue;
}
if (o1 instanceof Date) {
o1 = DateUtil.getDay((Date) o1);
}
if (!o1.toString().equals(o2.toString())) {
if (i != 1) {
str += separator;
}
str += " " + field.getName() + ", :" + o1 + ", :" + o2;
i++;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* pojo1 pojo2,
*
* @author ...
* @Date 2017/5/9 19:34
*/
public static String contrastObj(Class dictClass, String key, Object pojo1, Map<String, String> pojo2) throws IllegalAccessException, InstantiationException {
AbstractDictMap dictMap = (AbstractDictMap) dictClass.newInstance();
String str = parseMutiKey(dictMap, key, pojo2) + separator;
try {
Class clazz = pojo1.getClass();
Field[] fields = pojo1.getClass().getDeclaredFields();
int i = 1;
for (Field field : fields) {
if ("serialVersionUID".equals(field.getName())) {
continue;
}
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
Method getMethod = pd.getReadMethod();
Object o1 = getMethod.invoke(pojo1);
Object o2 = pojo2.get(StrKit.firstCharToLowerCase(getMethod.getName().substring(3)));
if (o1 == null || o2 == null) {
continue;
}
if (o1 instanceof Date) {
o1 = DateUtil.getDay((Date) o1);
} else if (o1 instanceof Integer) {
o2 = Integer.parseInt(o2.toString());
}
if (!o1.toString().equals(o2.toString())) {
if (i != 1) {
str += separator;
}
String fieldName = dictMap.get(field.getName());
String fieldWarpperMethodName = dictMap.getFieldWarpperMethodName(field.getName());
if (fieldWarpperMethodName != null) {
Object o1Warpper = DictFieldWarpperFactory.createFieldWarpper(o1, fieldWarpperMethodName);
Object o2Warpper = DictFieldWarpperFactory.createFieldWarpper(o2, fieldWarpperMethodName);
str += " :" + fieldName + ", :" + o1Warpper + ", :" + o2Warpper;
} else {
str += " :" + fieldName + ", :" + o1 + ", :" + o2;
}
i++;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* pojo1 pojo2,
*
* @author ...
* @Date 2017/5/9 19:34
*/
public static String contrastObjByName(Class dictClass, String key, Object pojo1, Map<String, String> pojo2) throws IllegalAccessException, InstantiationException {
AbstractDictMap dictMap = (AbstractDictMap) dictClass.newInstance();
String str = parseMutiKey(dictMap, key, pojo2) + separator;
try {
Class clazz = pojo1.getClass();
Field[] fields = pojo1.getClass().getDeclaredFields();
int i = 1;
for (Field field : fields) {
if ("serialVersionUID".equals(field.getName())) {
continue;
}
String prefix = "get";
int prefixLength = 3;
if (field.getType().getName().equals("java.lang.Boolean")) {
prefix = "is";
prefixLength = 2;
}
Method getMethod = null;
try {
getMethod = clazz.getDeclaredMethod(prefix + StrKit.firstCharToUpperCase(field.getName()));
} catch (NoSuchMethodException e) {
System.err.println("this className:" + clazz.getName() + " is not methodName: " + e.getMessage());
continue;
}
Object o1 = getMethod.invoke(pojo1);
Object o2 = pojo2.get(StrKit.firstCharToLowerCase(getMethod.getName().substring(prefixLength)));
if (o1 == null || o2 == null) {
continue;
}
if (o1 instanceof Date) {
o1 = DateUtil.getDay((Date) o1);
} else if (o1 instanceof Integer) {
o2 = Integer.parseInt(o2.toString());
}
if (!o1.toString().equals(o2.toString())) {
if (i != 1) {
str += separator;
}
String fieldName = dictMap.get(field.getName());
String fieldWarpperMethodName = dictMap.getFieldWarpperMethodName(field.getName());
if (fieldWarpperMethodName != null) {
Object o1Warpper = DictFieldWarpperFactory.createFieldWarpper(o1, fieldWarpperMethodName);
Object o2Warpper = DictFieldWarpperFactory.createFieldWarpper(o2, fieldWarpperMethodName);
str += " :" + fieldName + ", :" + o1Warpper + ", :" + o2Warpper;
} else {
str += " :" + fieldName + ", :" + o1 + ", :" + o2;
}
i++;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* key( )
*
* @author ...
* @Date 2017/5/16 22:19
*/
public static String parseMutiKey(AbstractDictMap dictMap, String key, Map<String, String> requests) {
StringBuilder sb = new StringBuilder();
if (key.indexOf(",") != -1) {
String[] keys = key.split(",");
for (String item : keys) {
String fieldWarpperMethodName = dictMap.getFieldWarpperMethodName(item);
String value = requests.get(item);
if (fieldWarpperMethodName != null) {
Object valueWarpper = DictFieldWarpperFactory.createFieldWarpper(value, fieldWarpperMethodName);
sb.append(dictMap.get(item) + "=" + valueWarpper + ",");
} else {
sb.append(dictMap.get(item) + "=" + value + ",");
}
}
return StrKit.removeSuffix(sb.toString(), ",");
} else {
String fieldWarpperMethodName = dictMap.getFieldWarpperMethodName(key);
String value = requests.get(key);
if (fieldWarpperMethodName != null) {
Object valueWarpper = DictFieldWarpperFactory.createFieldWarpper(value, fieldWarpperMethodName);
sb.append(dictMap.get(key) + "=" + valueWarpper);
} else {
sb.append(dictMap.get(key) + "=" + value);
}
return sb.toString();
}
}
}
5.입력 방법 에 따라 데이터 사전 의 데 이 터 를 가 져 옵 니 다.
import java.lang.reflect.Method;
public class DictFieldWarpperFactory {
public static Object createFieldWarpper(Object parameter, String methodName) {
IConstantFactory constantFactory = ConstantFactory.me();
try {
Method method = IConstantFactory.class.getMethod(methodName, parameter.getClass());
return method.invoke(constantFactory, parameter);
} catch (Exception e) {
try {
Method method = IConstantFactory.class.getMethod(methodName, Integer.class);
return method.invoke(constantFactory, Integer.parseInt(parameter.toString()));
} catch (Exception e1) {
throw new RuntimeException("BizExceptionEnum.ERROR_WRAPPER_FIELD");
}
}
}
}
6.데이터 사전 을 가 져 오 는 방법
public interface IConstantFactory {
/**
*
*/
String getWordStatus(Integer DATA_STATUS);
}
import com.qihoinfo.dev.log.util.SpringContextHolder;
import org.anyline.service.AnylineService;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
@Component
@DependsOn("springContextHolder")
public class ConstantFactory implements IConstantFactory {
private AnylineService anylineService = SpringContextHolder.getBean(AnylineService.class);
public static IConstantFactory me() {
return SpringContextHolder.getBean("constantFactory");
}
@Override
public String getWordStatus(Integer DATA_STATUS) {
if ("1".equals(DATA_STATUS.toString())) {
return " ";
} else {
return " ";
}
}
}
7.spring 방법 명 에 따라 해당 용기 의 대상 가 져 오기
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Spring ApplicationContext , spring bean
*/
@Component
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextHolder.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
assertApplicationContext();
return applicationContext;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName) {
assertApplicationContext();
return (T) applicationContext.getBean(beanName);
}
public static <T> T getBean(Class<T> requiredType) {
assertApplicationContext();
return applicationContext.getBean(requiredType);
}
private static void assertApplicationContext() {
if (SpringContextHolder.applicationContext == null) {
throw new RuntimeException("applicaitonContext null, SpringContextHolder!");
}
}
}
8.문자열 도구 클래스
/**
*
*/
public class StrKit {
/**
*
*/
public static String firstCharToLowerCase(String str) {
char firstChar = str.charAt(0);
if (firstChar >= 'A' && firstChar <= 'Z') {
char[] arr = str.toCharArray();
arr[0] += ('a' - 'A');
return new String(arr);
}
return str;
}
/**
*
*/
public static String firstCharToUpperCase(String str) {
char firstChar = str.charAt(0);
if (firstChar >= 'a' && firstChar <= 'z') {
char[] arr = str.toCharArray();
arr[0] -= ('a' - 'A');
return new String(arr);
}
return str;
}
/**
*
*/
public static String removeSuffix(String str, String suffix) {
if (isEmpty(str) || isEmpty(suffix)) {
return str;
}
if (str.endsWith(suffix)) {
return str.substring(0, str.length() - suffix.length());
}
return str;
}
/**
* , 1、 null <br>
* 2、 ""<br>
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
}
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
public class ToolUtil {
public static final int SALT_LENGTH = 6;
public ToolUtil() {
}
public static String getExceptionMsg(Throwable e) {
StringWriter sw = new StringWriter();
try {
e.printStackTrace(new PrintWriter(sw));
} finally {
try {
sw.close();
} catch (IOException var8) {
var8.printStackTrace();
}
}
return sw.getBuffer().toString().replaceAll("\\$", "T");
}
}
9.데이터 사전 가 져 오 는 클래스
import java.util.HashMap;
public abstract class AbstractDictMap {
protected HashMap<String, String> dictory = new HashMap<>();
protected HashMap<String, String> fieldWarpperDictory = new HashMap<>();
public AbstractDictMap() {
put("ID", " ID");
init();
initBeWrapped();
}
public abstract void init();
protected abstract void initBeWrapped();
public String get(String key) {
return this.dictory.get(key);
}
public void put(String key, String value) {
this.dictory.put(key, value);
}
public String getFieldWarpperMethodName(String key) {
return this.fieldWarpperDictory.get(key);
}
public void putFieldWrapperMethodName(String key, String methodName) {
this.fieldWarpperDictory.put(key, methodName);
}
}
public class SystemDict extends AbstractDictMap {
@Override
public void init() {
}
@Override
protected void initBeWrapped() {
}
}
public class WordMap extends AbstractDictMap {
@Override
public void init() {
put("EN", " ");
put("CN", " ");
put("SHORT", " ");
put("REMARK", " ");
put("DATA_STATUS", " ");
}
@Override
protected void initBeWrapped() {
putFieldWrapperMethodName("DATA_STATUS","getWordStatus");
}
}
10.캐 시 대상 을 가 져 오 는 bean
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import java.io.Serializable;
@Component
@Scope(scopeName = WebApplicationContext.SCOPE_SESSION)
public class LogObjectHolder implements Serializable{
private Object object = null;
public void set(Object obj) {
this.object = obj;
}
public Object get() {
return object;
}
public static LogObjectHolder me(){
LogObjectHolder bean = SpringContextHolder.getBean(LogObjectHolder.class);
return bean;
}
}
11.실행 중 이상 가 져 오기
@ControllerAdvice
public class GlobalExceptionHandler extends BasicMemberJSONController {
private Logger log = LoggerFactory.getLogger(this.getClass());
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public String notFount(RuntimeException e) {
String userName = curManage().get("USERNAME").toString();
LogManager.me().executeLog(LogTaskFactory.exceptionLog(userName, e));
log.error(" :", e);
return fail();
}
}
12.스 레 드 탱크 를 사용 하여 작업 로 그 를 만 듭 니 다.
import java.util.Date;
public class LogFactory {
/**
*
*/
public static DataRow createOperationLog(LogType logType, String userName, String bussinessName, String clazzName, String methodName, String msg, LogSucceed succeed) {
DataRow operationLog = new DataRow();
operationLog.put("log_type", logType.getMessage());
operationLog.put("USER_NAME", userName);
operationLog.put("log_name", bussinessName);
operationLog.put("CLASS_NAME", clazzName);
operationLog.put("METHOD", methodName);
operationLog.put("CREATE_TIME", new Date());
operationLog.put("SUCCEED", succeed.getMessage());
if (msg.length() > 800) {
msg = msg.substring(0, 800);
operationLog.put("MESSAGE", msg);
} else {
operationLog.put("MESSAGE", msg);
}
return operationLog;
}
}
import java.util.TimerTask;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class LogManager {
//
private final int OPERATE_DELAY_TIME = 10;
//
private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
private LogManager() {
}
public static LogManager logManager = new LogManager();
public static LogManager me() {
return logManager;
}
public void executeLog(TimerTask task) {
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
}
public enum LogSucceed {
SUCCESS(" "),
FAIL(" ");
String message;
LogSucceed(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
import com.qihoinfo.dev.log.annotation.RedisDb;
import com.qihoinfo.dev.log.util.ToolUtil;
import org.anyline.entity.DataRow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.TimerTask;
@Component
@DependsOn("springContextHolder")
public class LogTaskFactory {
private static Logger logger = LoggerFactory.getLogger(LogManager.class);
private static StringRedisTemplate redisTemplate = RedisDb.getMapper(StringRedisTemplate.class);
public static TimerTask bussinessLog(final String userName, final String bussinessName, final String clazzName, final String methodName, final String msg) {
return new TimerTask() {
@Override
public void run() {
DataRow operationLog = LogFactory.createOperationLog(
LogType.BUSSINESS, userName, bussinessName, clazzName, methodName, msg, LogSucceed.SUCCESS);
try {
redisTemplate.opsForList().rightPush("sys_operation_log", operationLog.getJson());
} catch (Exception e) {
logger.error(" !", e);
}
}
};
}
public static TimerTask exceptionLog(final String userName, final Exception exception) {
return new TimerTask() {
@Override
public void run() {
String msg = ToolUtil.getExceptionMsg(exception);
DataRow operationLog = LogFactory.createOperationLog(
LogType.EXCEPTION, userName, "", null, null, msg, LogSucceed.FAIL);
try {
redisTemplate.opsForList().rightPush("sys_operation_log", operationLog.getJson());
} catch (Exception e) {
logger.error(" !", e);
}
}
};
}
}
public enum LogType {
EXCEPTION(" "),
BUSSINESS(" ");
String message;
LogType(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
13.redis 데이터베이스 에 로 그 를 기록 합 니 다.
package com.qihoinfo.dev.log.annotation;
import com.qihoinfo.dev.log.util.SpringContextHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
public class RedisDb<T> {
private Class<T> clazz;
private StringRedisTemplate baseMapper;
private RedisDb(Class clazz) {
this.clazz = clazz;
this.baseMapper = (StringRedisTemplate) SpringContextHolder.getBean(clazz);
}
public static <T> RedisDb<T> create(Class<T> clazz) {
return new RedisDb<T>(clazz);
}
public StringRedisTemplate getMapper() {
return this.baseMapper;
}
public static <T> T getMapper(Class<T> clazz) {
return SpringContextHolder.getBean(clazz);
}
}
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
* @Description:
* @Auther: wj
* @Date: 2019/5/28 13:56
*/
public class HttpContext {
public HttpContext() {
}
public static String getIp() {
HttpServletRequest request = getRequest();
return request == null ? "127.0.0.1" : request.getRemoteHost();
}
public static HttpServletRequest getRequest() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return requestAttributes == null ? null : requestAttributes.getRequest();
}
public static HttpServletResponse getResponse() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return requestAttributes == null ? null : requestAttributes.getResponse();
}
public static Map<String, String> getRequestParameters() {
HashMap<String, String> values = new HashMap();
HttpServletRequest request = getRequest();
if (request == null) {
return values;
} else {
Enumeration enums = request.getParameterNames();
while (enums.hasMoreElements()) {
String paramName = (String) enums.nextElement();
String paramValue = request.getParameter(paramName);
values.put(paramName, paramValue);
}
return values;
}
}
}
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin Springboot -- 파트 14 사용 사례 REST로 전환하여 POST로 JSON으로 전환前回 前回 前回 記事 の は は で で で で で で を 使っ 使っ 使っ て て て て て リクエスト を を 受け取り 、 reqeustbody で 、 その リクエスト の ボディ ボディ を を 受け取り 、 関数 内部 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.