我的编程空间,编程开发者的网络收藏夹
学习永远不晚

springboot 实现记录业务日志和异常业务日志的操作

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

springboot 实现记录业务日志和异常业务日志的操作

日志记录到redis展现形式

1.基于注解的方式实现日志记录,扫描对应的方法实现日志记录


@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface BussinessLog {
 
    
    String value() default "";
 
    
    String key() default "id";
 
    
    String type() default "0";
 
    
    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;
 

public class Contrast {
 
    //记录每个修改字段的分隔符
    public static final String separator = ";;;";
 
    
    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;
    }
 
    
    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;
    }
 
    
    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;
    }
 
    
    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; 

@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;
    }
    
    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;
 

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;
        }
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

springboot 实现记录业务日志和异常业务日志的操作

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

springboot中怎么实现记录业务日志和异常业务日志操作

今天就跟大家聊聊有关springboot中怎么实现记录业务日志和异常业务日志操作,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。日志记录到redis展现形式1.基于注解的方式实现日志记
2023-06-20

记录业务系统操作日志方案实践

通过以上实践,我们可以实现对业务系统中数据变更的追踪和记录,通过通用的接口规则,可以动态地展示不同业务数据模型变更过程。这种方案的核心是将数据变更的追踪和记录与业务逻辑分离,使其成为一个通用的、可复用的服务。通过注解和 AOP技术,我们可以

Springboot使用Logback实现日志配置与异常记录

默认情况下,SpringBoot内部使用logback作为系统日志实现的框架,将日志输出到控制台,不会写到日志文件。本篇文章主要讲解下如何自定义logabck.xml以及对logback文件中配置做一个详解,需要的可以参考一下
2022-11-21

Java SpringBoot项目如何优雅的实现操作日志记录

这篇文章主要介绍了Java SpringBoot项目如何优雅的实现操作日志记录,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
2022-11-13

SpringBoot实战:轻松使用AOP+注解实现操作日志记录

通过上述步骤,我们利用AOP和自定义注解在SpringBoot应用中实现了操作日志的记录。这种方式不仅减少了代码冗余,提高了开发效率,还增强了系统的可维护性和可扩展性。

PHP 函数的最佳实践:异常处理和日志记录?

异常处理和日志记录在 php 函数中至关重要:通过 try/catch 块捕获异常并抛出自定义异常。使用日志记录库(如 psr-3 或 monolog)记录事件,并根据严重程度对日志消息进行分级。记录异常以提供更多上下文,并在输入错误时采取
PHP 函数的最佳实践:异常处理和日志记录?
2024-05-04

阿里云服务器操作日志怎么查看记录的

操作系统和应用程序的日志记录:阿里云服务器上的所有应用程序和操作系统日志都会记录下来,包括系统和应用程序的错误、异常和性能数据。这些日志可以帮助您识别和解决应用程序或操作系统的故障。网络日志:网络日志包括服务器连接到互联网的流量、数据包转发和数据包路由的详细信息。如果您在阿里云服务器上访问了网络服务,这些日志可能会记录
阿里云服务器操作日志怎么查看记录的
2023-10-28

面向跨语言的操作系统日志异常检测技术研究与实现

随着国产化生态的不断成熟,越来越多的应用和服务构建在国产操作系统上。同时,信息系统面临的恶意攻击、内部威胁以及数据泄露风险增加,给个人和国家信息安全造成了很大的威胁。

如何利用Systemd和Crontab在Linux系统中实现定时任务日志记录

要在Linux系统中实现定时任务日志记录,可以使用Systemd和Crontab的组合。下面是具体的步骤:1. 创建一个Shell脚本,用于执行定时任务,并将任务执行的结果输出到日志文件中。例如,创建一个名为`mytask.sh`的脚本文件
2023-10-09

再续面向跨语言的操作系统日志异常检测技术研究与实现

LaBSE模型由两个共享参数的12层堆叠双向Transformer编码器组成,包括 768个隐藏层和一亿一千万个参数组成,主要是基于注意力机制实现的。

如何在MySQL中设计一个可维护的会计系统表结构以支持日常业务操作和维护?

如何在MySQL中设计一个可维护的会计系统表结构以支持日常业务操作和维护?在企业中,会计系统是一个非常重要的组成部分,负责处理财务数据的存储、计算和管理。为了能够支持日常业务操作和维护,设计一个可维护的会计系统表结构是至关重要的。在MySQ
如何在MySQL中设计一个可维护的会计系统表结构以支持日常业务操作和维护?
2023-10-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录