springMVC,aop管理log4j,把当前session信息和错误信息打印到日志

((((其实还是不太理解aop的正真意义但是这样可以实现想要的了,我的感觉是执行一个方法时首先通过filter( 这个fiter可以不配置,之所以要他是因为在aop切入的方法session消失了,我们要保存是谁在操作就需要他) > aop管理的log4j类,>log4j 来搞定日志的处理))))

记录一下学习路径,终于搞通了关于spring aop管理log4j和有关session的问题,目的是 当某个用户进行什么操作发生了什么异常,记录到日志以备查找错误进行修改,参考文档:http://blog.csdn.net/sorrow199117/article/details/8848505 这位大神写的我从头一直做到尾,但是就是获取不到session,如果没有用户信息记录不了用户就没什么意义了,继续调试,我靠 ,最后发现是缓存的问题,清理了服务器问题解决,借用大神的一句话:AOP配置文件会去检查你是否对此方法配置了日志切面,如果配置了,这儿是后向切入,他会在执行此方法之后执行切入类的一个方法(AOP配置此方法),切入类得到了此方法的完整路径名称,他会到一个配置文件中去读取方法描述,然后用log4j记录此描述信息

1. spring的配置文件 XXX.xml ,aop配置代码段

        <pre name="code" class="html"><aop:config><aop:pointcut id="serviceOperation" expression="execution (* com.esh.eatsong.customServer.*.service.impl.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/></aop:config><!--配置log对象--><bean id="logger" class="org.slf4j.LoggerFactory" factory-method="getLogger"><constructor-arg type="java.lang.String" value=""></constructor-arg></bean><bean id="action_log" class="org.slf4j.LoggerFactory" factory-method="getLogger"><constructor-arg type="java.lang.String" value="action_log"></constructor-arg></bean>	<bean id="service_log" class="org.slf4j.LoggerFactory" factory-method="getLogger"><constructor-arg type="java.lang.String" value="service_log"></constructor-arg></bean>	<bean id="dao_log" class="org.slf4j.LoggerFactory" factory-method="getLogger"><constructor-arg type="java.lang.String" value="dao_log"></constructor-arg></bean>	<bean id="job_log" class="org.slf4j.LoggerFactory" factory-method="getLogger"><constructor-arg type="java.lang.String" value="job_log"></constructor-arg></bean>

 

 2.下面是web.xml配置log4j 的主要部分 当启动项目时加载 

我把log4j.properties配置文件放在源文件夹下logs/XXX 目录下编译之后的路径是WEB-INF/classes/logs/XXXX

  <!--*******log4j日志信息的配置--><context-param><param-name>log4jConfigLocation</param-name><param-value>classpath:logs/log4j.properties</param-value></context-param><!--Spring默认刷新Log4j配置文件的间隔,单位为millisecond,可以不设置 -->  <context-param>  <param-name>log4jRefreshInterval</param-name>  <param-value>60000</param-value>  </context-param> 
<!-- Filter : GetUserFilter 他的作用是从SESSION中获取当前登录用户的信息,在Log4j配置文件中用到了,比如%X{name}是获取用户姓名,但是要在此Filter中先设置name属性。GetUserFilter是关键所在,因为等一下用AOP切入的方法已经得不到用户信息了,就要靠他了 --><filter>  <filter-name>GetUserFilter</filter-name>  <filter-class>com.esh.eatsong.framework.util.GetUserFilter</filter-class>  </filter>  <filter-mapping>  <filter-name>GetUserFilter</filter-name>  <url-pattern>/*</url-pattern>  </filter-mapping> 
log4j.properties 配置文件  这个文件但是搞了半天才明白这些类似与C 的代码是什么意思不知道的可以

参考:http://zc2690790.blog.163.com/blog/static/127891478200981445953120/

# root logger 
log4j.rootLogger=error, stdout, file ,filter
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d,[%-5p],%x,%c,%m%nlog4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=/home/shareupload/zhxy/logs/platform/system.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d,[%-5p],%x,%c,%m%n
log4j.appender.file.MaxFileSize=10480KB
log4j.appender.file.MaxBackupIndex=50 # hibernate log
log4j.logger.org.hibernate=error, hibernate
#log4j.appender.hibernate=org.apache.log4j.DailyRollingFileAppender
log4j.appender.hibernate=org.apache.log4j.RollingFileAppender
log4j.appender.hibernate.File=/home/shareupload/zhxy/logs/platform/hibernate.log
log4j.appender.hibernate.DatePattern='.'yyyy-MM-dd
log4j.appender.hibernate.layout=org.apache.log4j.PatternLayout
log4j.appender.hibernate.layout.ConversionPattern=%d,[%-5p],%x,%c,%m%n
log4j.appender.hibernate.MaxFileSize=10480KB
log4j.appender.hibernate.MaxBackupIndex=50# filter log   这里 %X{key} 在filter里用MDC.put("cus_id", "cus_id:"+customer.getId());给key赋值
log4j.appender.filter=org.apache.log4j.RollingFileAppender
log4j.appender.filter.File=/home/shareupload/zhxy/logs/platform/filter.log
log4j.appender.filter.DatePattern='.'yyyy-MM-dd
log4j.appender.filter.layout=org.apache.log4j.PatternLayout
log4j.appender.filter.layout.ConversionPattern=%d,[%-5p],%X{cus_id},%X{cus_tel},%X{emp_id},%X{emp_name},%c,[%l], %m%n 
log4j.appender.filter.MaxFileSize=10480KB
log4j.appender.filter.MaxBackupIndex=50
过滤器 ,用这个filter获得我们登陆时的session信息并且把用户通过%X{cus_id}形式进行打印到日志

package com.esh.eatsong.framework.util;/**  * 文件名: GetUserFilter.java  * 描述:(得到SESSION中的用户)  */import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.log4j.MDC;import com.esh.eatsong.customServer.customer.pojo.Customer;
import com.esh.eatsong.customServer.employee.pojo.Employee;public class GetUserFilter  implements Filter {// 定义默认用户姓名private final static String DEFAULT_USER = "guest";// 定义默认用户telprivate final static String DEFAULT_TEL = "guestTel";public void destroy() {}public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpSession session = req.getSession();if (session == null) {MDC.put("cus_id", (int) (Math.random() * 1000));MDC.put("cus_tel", DEFAULT_TEL);MDC.put("emp_id", (int) (Math.random() * 1000));MDC.put("emp_name", DEFAULT_USER);} else {Employee employee = (Employee) session.getAttribute("employee");Customer customer = (Customer) session.getAttribute("customer");if (customer == null) {MDC.put("cus_id", (int) (Math.random() * 1000));MDC.put("cus_tel", DEFAULT_TEL);} else {MDC.put("cus_id", "cus_id:"+customer.getId());MDC.put("cus_tel",customer.getTelphone());}if (employee==null) {MDC.put("emp_id", (int) (Math.random() * 1000));MDC.put("emp_name", DEFAULT_USER);} else {MDC.put("emp_id", "emp_id:"+employee.getId());MDC.put("emp_name",employee.getName());}}chain.doFilter(request, response);}public void init(FilterConfig Config) throws ServletException {}
}

制造一个error异常

package com.esh.framework.util;import java.lang.reflect.Method;import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;/*** 基于注解的AOP日志示例* @author */
@Component
@Aspect
public class AopLog {/** * 必须为final String类型的,注解里要使用的变量只能是静态常量类型的 */  private static final String EDP = "execution (* com.esh.eatsong.customServer.*.*.impl.*.*(..))";private static final Logger logger = Logger.getLogger(Log4jAspect.class);private static final String DOT = ".";//点号private static final String COMMA = ",";//逗号String strLog = null ;  /** * 前置通知:在某连接点之前执行的通知,但这个通知不能阻止连接点前的执行 * @param jp 连接点:程序执行过程中的某一行为,例如,AServiceImpl.barA()的调用或者抛出的异常行为 */  public void doBefore(JoinPoint jp) {  strLog = "log Begining method: "  + jp.getTarget().getClass().getName() + "."  + jp.getSignature().getName();  logger.warn(strLog);  }  /** * 抛出异常后通知 : 在方法抛出异常退出时执行的通知。 * @param jp 连接点:程序执行过程中的某一行为,例如,AServiceImpl.barA()的调用或者抛出的异常行为 */  public void doAfter(JoinPoint jp) {  strLog ="doAfter:log Ending method: "  + jp.getTarget().getClass().getName() + "."  + jp.getSignature().getName();   logger.warn(strLog);  }  /** * 环绕通知:包围一个连接点的通知,可以在方法的调用前后完成自定义的行为,也可以选择不执行 * 类似Web中Servlet规范中的Filter的doFilter方法。 * @param pjp 当前进程中的连接点 * @return * @throws Throwable */ @Around(EDP)public Object rround(ProceedingJoinPoint joinPoint) throws Throwable {StringBuilder sb = new StringBuilder();Object[] paramValues = joinPoint.getArgs();//获取参数值String[] paramNames = new String[paramValues.length];Class<? extends Object> invokeClass = joinPoint.getTarget().getClass();String signatureName = joinPoint.getSignature().getName();Method methods[] = invokeClass.getMethods();for (Method method : methods) {if(method.getName().equals(signatureName)) {String paramCollection ="";AOPLog4jAnnotation log4jAnnotation = method.getAnnotation(AOPLog4jAnnotation.class);if(log4jAnnotation!=null){paramCollection=log4jAnnotation.paramCollection();//获取注解值String[] names = paramCollection.split(COMMA);System.arraycopy(names, 0, paramNames, 0, names.length);}else{;}}}for (int i = 0; i < paramValues.length; i++) {sb.append(paramNames[i] + "=" + paramValues[i] + COMMA);}//入参日志if(sb.length()!=0){logger.info(invokeClass  + DOT + signatureName + ",remote input:" + sb.toString().substring(0, sb.length() - 1));	}Object result = joinPoint.proceed();//出参日志logger.info(invokeClass  + DOT + signatureName + ",remote output:" + result);return result;}//方法运行出现异常时调用@AfterThrowing(pointcut = EDP,throwing = "ex")public void afterThrowing(JoinPoint jp, Exception ex){strLog ="afterThrowing:log Ending method: " + jp.getTarget().getClass().getName() + DOT + jp.getSignature().getName();   logger.error(strLog+"["+ex+"]");}
}



web项目日志输出文件在服务器根目录下 然后跟路径/X/X/XX/filter.log

高度关注filter.log 这里存放了session信息




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/553560.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu/环境变量:修改/etc/environment 导致开机不能进入桌面

解决思路是&#xff1a;将环境变量的参数修改正确。 1、卡在界面的地方&#xff1a; CTRLALTF1&#xff0c;进入命令界面 2、临时修改环境变量 export PATH"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games" 3、这样就…

搜狗浏览器收藏夹在什么位置?搜狗浏览器收藏夹路径在哪?

搜狗浏览器是一款比较受大家欢迎的浏览器软件&#xff0c;很多都在问搜狗浏览器的收藏路径在哪。下面小编就为大家分享一下搜狗浏览器收藏夹在什么位置&#xff0c;接下来我们一起往下看看。 方法步骤 1、打开你的搜狗浏览器&#xff0c;你点击 “收藏”; 搜狗浏览器收藏夹在…

xp/win 7 系统搭建 Java环境

win 7 系统搭建 Java环境 xp系统大同小异 下面是具体的值

vim 强制保存只读文件

转自 http://kuanghy.github.io/2015/12/30/sudo-vim :w !sudo tee %

世界之窗浏览器怎么隐藏收藏栏?

想必大家都知道&#xff0c;无论是什么浏览器&#xff0c;默认都是会显示收藏栏的&#xff0c;这样用户就可以快速打开收藏栏中收藏的网页&#xff0c;但很多时候有些用户会收藏一些不想被人看到的网页&#xff0c;这时候最好的方法就是将收藏栏隐藏起来了。那么&#xff0c;世…

原始servlet+hibernate+struts2,从前台到后台的整个过程

现在三大框架的兴起ssh spring springmvc 基于注解式的编程简单方便了开发,但是让我感觉摸不着头绪,框架固然是好,提高了开发效率, 对企业有很大的帮助,框架封装的一些底层的东西让我不知道为什么要这么做,只知道该这么做,编程的路线肯定是简单快捷,趋势就是随便点点拖拖,就是…

Ubuntu中MySQL的启动/关闭/重启

一、启动 1. mysqld脚本启动: /etc/init.d/ mysql start 二、关闭 1. mysqld脚本关闭: /etc/init.d/ mysql stop 三、重启 1. mysqld脚本重启: /etc/init.d/ mysql restart 打开 mysql-client 客户端&#xff0c; mysql -u root -p

Win10怎么样修复edge浏览器?如何重置edge浏览器

在Windows10系统桌面右键点击左下角的开始按钮&#xff0c;在弹出的菜单中点击设置菜单项。 Win10怎么样修复edge浏览器&#xff1f;如何重置edge浏览器[多图] 在打开的Windows设置窗口中&#xff0c;点击应用图标。 Win10怎么样修复edge浏览器&#xff1f;如何重置edge浏览…

Hibernate实体映射配置1(java@注解方式)

实体和数据库之间存在某种映射关系&#xff0c;hibernate根据这种映射关系完成数据的存取。在程序中这种映射关系由映射文件&#xff08;*.hbm.xml&#xff09;或者java注解()定义。 本文以java注解的形式总结映射关系配置。 实体类组件以及注解标签映射关系 实体类--------…

火狐浏览器工具栏/折叠菜单怎么设置?火狐浏览器工具栏/折叠菜单定制教程

为了方便用户将一些常用的功能及应用添加到工具栏/折叠菜单中&#xff0c;火狐浏览器推出了一项特别的功能“定制”。也就是说&#xff0c;借助该功能&#xff0c;用户就可以自由添加或替换工具栏/折叠菜单中的各类功能了!那么&#xff0c;该怎么操作呢?让我们来了解一下。 方…

Python 文件操作 'w+' 和 'wb'的区别

在文件上传的时候遇到个问题&#xff0c;就是 w 和 wb 在文件上传的时候是否回车。 根据项目的实景情况模拟一下区别。 首先说一下 w 和 wb 的区别 。w 是文本写入&#xff0c;wb是字节写入。 看代码。首先在window 操作系统下。 1.字节 # utf-8# 模拟上传的文件内容 read…

MySQL左关联、右关联、内关联查询

要说MySQL的关联查询&#xff0c;首先先说一下笛卡尔积&#xff0c; 有两个集合 A {1, 2},B {1, 3},这两个集合的笛卡尔积 A * B就有四种情况, A * B {(1,1), (1,3), (2,1),(2,3)} 笛卡尔积12132123 假设现在有两张表&#xff0c;table_A和 table_B table_Aa_user_ida_nam…

java获取net地址 本机

InetAddress netAddress;try {netAddress InetAddress.getLocalHost();String name netAddress.getHostName();System.out.println(name);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();}

手机优酷APP怎么上传视频

手机优酷怎样视频上传&#xff0c;自身在日常生活拍到好玩的视频&#xff0c;我们可以上传优酷&#xff0c;那如何上传到优酷呢&#xff1f; 01、 在优酷首页&#xff0c;点一下提交按键。 手机优酷APP怎么上传视频 02、 随后登录自身的优酷视频帐户。 手机优酷APP怎么上传…

warnings (imported as 'THREE') was not found in 'three'

这个问题还没解决&#xff01; 用Vue.js 重构项目的时候&#xff0c;引入three.js和其他相关的东西的时候会出现上面的警告。今天就说一下这个解决办法&#xff0c;但是我觉得这个方法不一定适用所有的项目。 一、引入THREE 首先用 npm 安装了 three, 然后再项目里面引入了。…

springMVC实体用注解管理,多对多 set集合元素排序问题 解决

实现效果 分类在set集合里不可排序 现要使商家拥有的相同的分来在同一列,需要把set集合里的元素放入list 但是问题是页面是双循环,必须以 . 的形式取集合元素所以需要把list集合声明到实体中,只做临时存储,所以写到dto类,这样就可排序了 我们用一个内部类Collections 的sort ( …

浏览器怎么截长图?怎么使用浏览器截长图?

我们在使用电脑浏览网页的时候有可能会想截取整篇网页&#xff0c;由于页面在电脑上显示不全&#xff0c;阅读的时候都需要滚动条来看&#xff0c;直接截屏根本截不全整个网页&#xff0c;这时候就需要截取网页的长截图了&#xff0c;那么怎么使用浏览器截长图呢? 1、以Edge浏…

three.js 把geometry转换成BufferGeometry

在 three.js 的文档里面有这个方法 https://threejs.org/docs/index.html#api/en/core/BufferGeometry.fromGeometry var bufferGeometry new THREE.BufferGeometry().fromGeometry( geometry );

进栈出栈示意图

进栈出栈示意图 12345 一次进栈 可以是54321,21543,32541等, 原理 : 后进先出,先进后出