springboot整合aop实现网站访问日志记录

目的:

统一日志输出格式,统计访问网站的ip.

思路:

1、针对不同的调用场景定义不同的注解,目前想的是接口层和服务层。

2、我设想的接口层和服务层的区别在于:

  (1)接口层可以打印客户端IP,而服务层不需要

  (2)接口层的异常需要统一处理并返回,而服务层的异常只需要向上抛出即可

3、就像Spring中的@Controller、@Service、@Repository注解那样,虽然作用是一样的,但是不同的注解用在不同的地方显得很清晰,层次感一下就出来了

4、AOP去拦截特定注解的方法调用

5、为了简化使用者的操作,采用Spring Boot自动配置

如果要直接用@Aspect注解的话,要在spring的配置文件中加入

<aop:aspectj-autoproxy />

那么我们这里要不要在程序的主类中增加@EnableAspectJAutoProxy来启用呢?实际并不需要

好的也就是说,只要引入SpringAOP相关的jar包依赖,我们就可以开始相关的Aspet的编程了。

首先需要引入依赖:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

controller中:

package com.cxy.shibernate.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/***
 * @ClassName: HelloController
 * @Description:
 * @Auther: cxy
 * @Date: 2019/5/19:18:06
 * @version : V1.0
 */
@Controller
public class HelloController {
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    @ResponseBody
    public String hello(@RequestParam String name) {
        return "Hello " + name;
    }

}

工具类:

package com.cxy.shibernate.controller;

/***
 * @ClassName: HttpContextUtils
 * @Description:
 * @Auther: cxy
 * @Date: 2019/5/19:18:17
 * @version : V1.0
 */
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

public class HttpContextUtils {

    public static HttpServletRequest getHttpServletRequest() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return servletRequestAttributes.getRequest();
    }
//获取ip
    public static String getIpAddress() {
        HttpServletRequest request = getHttpServletRequest();
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        }else if (ip != null && ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }
}

切面:

package com.cxy.shibernate.controller;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/***
 * @ClassName: WebLogAspect
 * @Description:
 * @Auther: cxy
 * @Date: 2019/5/19:18:08
 * @version : V1.0
 */
@Aspect
@Order(5)
@Component
public class WebLogAspect {
    private final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    ThreadLocal<Long> startTime = new ThreadLocal<>();
    /**
   第一个*表示返回任何类型,com.cxy.shibernate.controller下任何类,任何方法,任何参数
     也可以加入参数限定例如com.cxy.shibernate.controller.*.*(..)&&args(name,..)

     下面那中表示方法也是对的,表示com.cxy.shibernate.下面任何子包下任何方法,任何参数
    **/
    @Pointcut("execution(public * com.cxy.shibernate..*.*(..))")
    public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        startTime.set(System.currentTimeMillis());

        // 接收到请求,记录请求内容

        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        String ipAddress = HttpContextUtils.getIpAddress();

        // 记录下请求内容
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
        logger.info("ip:"+ipAddress);

    }

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求,返回内容
        logger.info("RESPONSE : " + ret);
        logger.info("SPEND TIME : " + (System.currentTimeMillis() - startTime.get()));
    }

}

启动类:

package com.cxy.shibernate;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ShibernateApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShibernateApplication.class, args);
    }

}

在application.yml不需要配置任何东西

启动项目:

当然可以配置文件输出的级别,制定输出的文件夹

原文地址:https://www.cnblogs.com/xiufengchen/p/10891027.html

时间: 2024-11-05 13:44:42

springboot整合aop实现网站访问日志记录的相关文章

SpringBoot整合aop日志管理

1. 开发前准备 1.1 前置知识 java基础自定义注解.反射 Spring aop SpringBoot简单基础知识即可 1.2 环境参数 开发工具:IDEA 基础环境:Maven+JDK8 所用技术:SpringBoot.lombok.mybatisplus.Spring aop SpringBoot版本:2.1.4 1.3 涉及知识点 自定义注解. 反射 spring aop 环绕通知 2. aop日志实现 AOP(Aspect Oriented Programming)是一个大话题,这

magento性能优化:禁用访问日志记录

系统记录所有访问数据到数据库里面,包括访客及机器的访问(例如搜索引擎爬虫),机器访问通常会占大部分,记录大量数据,这样会生产不小的额外服务器性能开销,包括web服务.mysql数据库服务:看需要,这部分数据可以不要. 负责记录访问日志的数据库表是:log_customer.log_quote.log_summary.log_summary_type.log_url.log_url_info.log_visitor.log_visitor_info.log_visitor_online.repor

apacheri访问日志记录

访问日志不记录静态文件按F12默认定位在network重新刷新网页每一行都是元素修改虚拟主机配置文件SetEnvif 环境 ENV=!img验证上传图片之后 访问有图片显示日志里面却没有记录PNG配置静态元素的过期时间修改虚拟主机配置文件编辑主配置文件 打开expires模块查看模块是否开启验证去掉模块再次验证没有过期时间apache 日志中记录代理IP以及真实客户端IP默认情况下log日志格式为:LogFormat "%h %l %u %t \"%r\" %>s %b

将Apache访问日志记录到Mysql数据库中

环境 操作系统:CentOS 步骤 1.下载源码 下载地址: https://packages.debian.org/jessie/libapache2-mod-log-sql-mysql 2.configure ./configure --with-apxs=/usr/local/bin/httpd/bin/apxs --with-mysql=/usr/local/bin/mariadb 注意:一定要检查configure完成有没有出现Mysql Driver ----------------

springboot整合aop全局日志管理

1.引入jar包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lomb

网站访问日志看安全

我本主开发,因没人,除了让人把几台服务器运到IDC,其它系统安装.虚拟机安装.系统上线.运维等事就我一手操办了. 幸好大学时对服务器的倒腾及毕业后在广东移动OCS维护经验,虽然不专业,但是能一步一个脚印地实施. 经常查看日志,偶尔会发现一些不怀好意的访问,当然也可能是某些人或者机构来检查网站的安全性吧. 通过日志看看别人是怎么扫描的,采取相应的措施,增加运维安全经验.有时候公司老是提安全不记心,还不如亲身体验一下风险,那会后怕. 1. 通过直接获取网站根目录的文件. 防治办法就是不要放置与网站无

Python开发程序:生成环境下统计网站访问日志信息

日志实时分析系统 生产环境下有需求:要每搁五分钟统计下这段时间内的网站访问量.UV.独立IP等信息,用直观的数据表格表现出来 环境描述: 网站为Nginx服务,系统每日凌晨会对日志进行分割,拷贝到其他位置,当前日志清空 NGINX日志配置信息: http { log_format main '$remote_addr - [$time_local] "$request" ' ' - $status "User_Cookie:$guid" '; } server {

springboot整合logback集成elk实现日志的汇总、分析、统计和检索功能

在Spring Boot当中,默认使用logback进行log操作.logback支持将日志数据通过提供IP地址.端口号,以Socket的方式远程发送.在Spring Boot中,通常使用logback-spring.xml来进行logback配置. 首先.创建一个elk的springboot项目,然后先对logback进行配置,配置各项的详细说明可以去看http://aub.iteye.com/blog/1101222,说的很详细.也多参考一下别人关于日志的描述https://www.cnbl

Springboot整合cxf后不能访问controller,不能访问接口

参考版本 springboot 1.4.X <=========> cxf-spring-boot-starter-jaxws 3.1.X springboot 1.5.X <=========> cxf-spring-boot-starter-jaxws 3.2.X 成功集成cxf后,发现只有webservice服务可以正常使用,其他请求url全部无法正常访问.然后在cxf 配置文件中 WebServiceCxfCfg.java 更改此方法名:dispatcherServlet