首页 > 其他分享 >AOP写日志

AOP写日志

时间:2024-12-25 14:28:36浏览次数:7  
标签:COMMENT String utf8mb4 DEFAULT operLog AOP 日志 NULL

AOP写日志

1.表SQL

DROP TABLE IF EXISTS `sys_oper_log`;
CREATE TABLE `sys_oper_log`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志主键',
  `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '模块标题',
  `business_type` tinyint NULL DEFAULT 0 COMMENT '业务类型(0=其它,1=新增,2=修改,3=删除)',
  `method` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '方法名称',
  `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求方式',
  `operator_type` tinyint NULL DEFAULT 1 COMMENT '操作类别(0=其它,1=后台用户,2=手机端用户)',
  `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作人员',
  `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '部门名称',
  `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求URL',
  `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '主机地址',
  `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作地点',
  `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求参数',
  `json_result` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '返回参数',
  `status` tinyint NULL DEFAULT 0 COMMENT '操作状态(0=正常,1=异常)',
  `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '错误消息',
  `oper_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间',
  `cost_time` bigint NULL DEFAULT 0 COMMENT '消耗时间',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `idx_business_type`(`business_type` ASC) USING BTREE,
  INDEX `idx_status`(`status` ASC) USING BTREE,
  INDEX `idx_oper_time`(`oper_time` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 27 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '操作日志记录' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

2.定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface OperLogAnnotation {
    String title() default ""; // 模块标题
    String businessType() default "0"; // 业务类型(0=其他,1=新增,2=修改,3=删除)

}

3.地图工具类

主要是拿到省市信息用的

public class GeoUtils {
    // ip->地址信息
    public static IpLocationResponse IpToAddressDTO(String key,String ip){
        String url =String.format("https://restapi.amap.com/v3/ip?key=%s&ip=%s",key,ip);
        String json = HutoolHttpUtil.sendGet(url, new HashMap<>());
        return JSONUtil.toBean(json, IpLocationResponse.class);
    }
}    

返回实体

@Data
public class IpLocationResponse {
    private String status;
    private String info;
    private String infocode;
    private String province;
    private String city;
    private String adcode;
    private String rectangle;
}
 {
 *     "status": "1",
 *     "info": "OK",
 *     "infocode": "10000",
 *     "province": "江苏省",
 *     "city": "无锡市",
 *     "adcode": "320200",
 *     "rectangle": "120.1788533,31.4648817;120.4605818,31.68307651"
 * }

4.进行AOP切面

@Aspect
@Component
@Slf4j
public class OperLogAspect {

    @Autowired
    private OperLogMapper operLogMapper;

    @Autowired
    private HttpServletRequest request;
    @Value("${GaoDe.key:linxi}")
    private String key;
    @Value("${GaoDe.open:false}")
    private boolean open;

    @Around("@annotation(top.remained.site.common.annotation.OperLogAnnotation)")
    public Object logOperation(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        OperLog operLog = new OperLog();
        // 获取方法上的注解信息
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        OperLogAnnotation annotation = signature.getMethod().getAnnotation(OperLogAnnotation.class);
        if (annotation != null) {
            operLog.setTitle(annotation.title());
            operLog.setBusinessType(Integer.parseInt(annotation.businessType()));
        }

        // 设置操作信息
        operLog.setOperName(getUsernameFromSecurity());
        operLog.setMethod(signature.getDeclaringTypeName() + "." + signature.getName());
        operLog.setRequestMethod(request.getMethod());
        operLog.setOperUrl(request.getRequestURI());
        operLog.setOperIp(request.getRemoteAddr());
        if (open) {
            IpLocationResponse ipLocationResponse = GeoUtils.IpToAddressDTO(key, request.getRemoteAddr());
            operLog.setOperLocation(ipLocationResponse.getProvince()+ipLocationResponse.getCity());
        }
        operLog.setOperTime(LocalDateTime.now());

        // 设置操作类别(后台/移动端用户)
        String userAgent = request.getHeader("User-Agent");
        operLog.setOperatorType(getOperatorTypeFromUserAgent(userAgent));

        // 设置请求参数
        Object[] args = joinPoint.getArgs();
        operLog.setOperParam(args != null ? args.toString() : null);

        Object result;
        try {
            result = joinPoint.proceed(); // 执行目标方法
            operLog.setStatus(0); // 操作成功
            operLog.setJsonResult(result != null ? result.toString() : null);
        } catch (Exception e) {
            operLog.setStatus(1); // 操作失败
            operLog.setErrorMsg(e.getMessage());
            throw e;
        } finally {
            long endTime = System.currentTimeMillis();
            operLog.setCostTime(endTime - startTime);
            // 保存日志
            operLogMapper.insert(operLog);
        }
        return result;
    }
    /**
     * 从 Spring Security 中获取用户名
     */
    private String getUsernameFromSecurity() {
        try {
            return SecurityUtils.getUsername();
        } catch (Exception e) {
            log.warn("无法从 SecurityContext 中获取用户名");
            return "Unknown";
        }
    }
    private int getOperatorTypeFromUserAgent(String userAgent) {
        if (userAgent == null) {
            return 0; // 未知
        }
        userAgent = userAgent.toLowerCase();
        if (userAgent.contains("mobile") || userAgent.contains("iphone") || userAgent.contains("android")) {
            return 2; // 移动端用户
        }
        return 1; // 后台用户(浏览器端)
    }
 }

5.使用

   @PostMapping("/login")
    @ApiOperation("登录")
    @OperLogAnnotation(title = "登录")
    public Result<TokenVo> login(@Validated @RequestBody LoginDto loginDto) {
        return Result.ok(loginService.login(loginDto.getUsername(),loginDto.getPassword()));
    }

标签:COMMENT,String,utf8mb4,DEFAULT,operLog,AOP,日志,NULL
From: https://blog.csdn.net/qq_46058550/article/details/144718602

相关文章

  • 日志 12.24
    DS题,主题平衡树和可并堆。T2未知来源模拟赛题题意简述:给一棵有根树,树上权值形成排列,对\(i\in[1,n]\)依次执行:选择子树内(包括i自己)的一个j,并交换\(a_i,a_j\)。问是否能在n次操作之后使\(\foralli:a_i=i\),如有须构造方案。容易注意到,有解的必要条件是每个置换环所有......
  • 【Kibana01】企业级日志分析系统ELK之Kibana的安装与介绍
    Kibana图形显示Kibana介绍Kibana是一款开源的数据分析和可视化平台,它是ElasticStack成员之一,设计用于和Elasticsearch 协作,可以使用Kibana对Elasticsearch索引中的数据进行搜索、查看、交互操作,您可以很方便的利用图表、表格及地图对数据进行多元化的分析和......
  • aop
    1.核心概念1.1.切面(Aspect)切面是AOP的核心概念,指的是横切关注点的模块化。一个切面就是关注程序中某一类功能(如事务管理、日志记录等)的独立模块。切面可以由通知(Advice)和切入点(Pointcut)组成。1.2.通知(Advice)通知是指具体的增强行为,它是在目标方法执行前后做一些操作。通......
  • 启用Linux防火墙日志记录和分析功能
    防火墙的基本功能是阻止来自可疑网络/来源的连接。它会检查所有连接的源地址、目的地址和端口,并决定是否允许或阻止流量。防火墙的每个操作都会记录为日志数据。监控和分析这些日志对于保护您的网络免受攻击至关重要。要这样做,您需要首先启用日志功能。以下是在Linux防火墙中启用......
  • Zed调试宏 C语言错误日志 异常错误调试信息
    1、C中的错误码           在C语言中通过返回错误码或设置全局的errno值来反馈错误问题。errno.h是一个头文件,它定义了一个全局变量errno,用于在程序中记录和报告错误的原因。这个机制主要用于处理系统调用或标准库函数出错时的错误反馈。当系统调用或库函数遇到......
  • 解决Spring Boot jar包启动日志输出中文乱码
    解决SpringBootjar包启动日志输出中文乱码|Id|Title|DateAdded|SourceUrl|PostType|Body|BlogId|Description|DateUpdated|IsMarkdown|EntryName|CreatedTime|IsActive|AutoDesc|AccessPermission||-------------|-------------|------------......
  • 网易伏羲亮相CCF程序员大会,有灵AOP平台首届编程挑战赛正式启幕
    12月21日至23日,由中国计算机学会(CCF)主办的首届“CCF程序员大会”在云南大理隆重召开。作为国内人工智能领域的领军者,网易伏羲受邀参与此次大会,与各界专家学者一同探索技术前沿,共赴思想盛宴。本届大会以“智汇大理,码动未来——共筑新发展、新范式”为主题,以技术与文化为核心,聚焦A......
  • AOP 开发明确的事项
    AOP开发明确的事项1)需要编写的内容编写核心业务代码(目标类的目标方法)编写切面类,切面类中有通知(增强功能方法)在配置文件中,配置织入关系,即将哪些通知与哪些连接点进行结合2)AOP技术实现的内容Spring框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用......
  • XML 配置 AOP 详解
    XML配置AOP详解1)切点表达式的写法表达式语法:execution([修饰符]返回值类型包名.类名.方法名(参数))访问修饰符可以省略返回值类型、包名、类名、方法名可以使用星号*代表任意包名与类名之间一个点.代表当前包下的类,两个点…表示当前包及其子包下的类......
  • 程序员日志之DNF手游65版本全职业公会桩冲榜打法教学
    目录传送门正文日志0.概要1.狂战士2.剑魂3.鬼泣4.阿修罗5.散打6.气功师7.枪炮师8.漫游枪手9.元素师10.魔道学者11.圣骑士12.驭剑士13.流浪武士14.契魔者15.暗殿骑士传送门SpringMVC的源码解析(精品)Spring6的源码解析(精品)SpringBoot3框架(精品)MyBatis框架(精品)MyBat......