((((其实还是不太理解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信息

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

  1. SVN 出错信息汇总/错误信息一览表

    编号 出错信息 信息解读 剖析及解决方案 1 svn: Server sent unexpected return value (500 Internal Server Error) in respo ...

  2. springboot启动不打印日志信息_springboot项目大量打印debug日志问题

    目前,java下应用最广泛的日志系统主要就是两个系列: log4j和slf4j+logback . 其中,slf4j只包含日志的接口,logback只包括日志的具体实现,两者加起来才是一个完整的日志系 ...

  3. 基于Ajax提交formdata数据、错误信息展示和局部钩子、全局钩子的校验。

    formdata重点: 实例化FormData这个类 循环serializeArray可以节省代码量 图片要用$('#id')[0].files[0]来获得 加上contentType:false和p ...

  4. 要坚信错误信息能帮你解决问题

    我们遇到错误,第一个要看的是啥,是错误信息,错误信息其实就是堆栈信息,有些错误很明显直接的就告诉你,哪里出错了,有限错误信息却隐藏了很深,需要很好的经验.不过我告诉你,你要坚信,相信,可以从错误信息里 ...

  5. Linux errno错误信息大全

    通常情况下,Linux平台开发过程中,总会遇到调用系统函数调用失败问题,为了更好地及时捕获错误信息,我们通常使用errno来捕获错误信息.需要注意的是,Linux系统调用的错误都存储在errno中,e ...

  6. 一步一步实现中后台管理平台模板-08-登录页和用户信息保存

    一,前言 上一篇,完善了Header组件,添加了用户信息的显示和退出功能 用户信息(昵称+头像)都是写死的,线上应用肯定是通过登录获取到用户信息这一篇,制作一个简单的登录页面,模拟接口异步调用(用户信 ...

  7. 使用反射机制深入理解AOP机制并自定义AOP管理模块

    最近在总结过去一年所做的项目,由于开发周期或者对需求的把握不是太到位,每个项目随着所做的项目进度,从需求分析到code阶段总或多或少有一些自己感觉不是太完美或没有尽善尽美的地方,使用开源框架和第三方接 ...

  8. html5获取设备信息 视频,设备信息的管理(Device) ---- HTML5+

    Device模块管理设备信息,用于获取手机设备的相关信息,如IMEI.IMSI.型号.厂商等.通过plus.device获取设备信息管理对象. 应用场景:打电话,铃声提醒,震动提醒,音量设置,查看设备 ...

  9. SpringBoot集成AOP管理日志

    写在前面 如何将所有的通过url的请求参数以及返回结果都输出到日志中? 如果在controller的类中每个方法名都写一个log输出肯定是不明智的选择.使用Spring的AOP功能即可完成. AOP ...

最新文章

  1. 解析C语言中的sizeof
  2. 8大领域、6大机遇!读懂2020年AI医疗新风向
  3. Catalyst3550交换机配置三层接口
  4. oracle去重等基础问题
  5. 《众妙之门——自由网站设计师成功之道》一1.4 自由网站设计师犯的严重错误...
  6. SM2 国密算法被 Linux 内核社区接受
  7. 首次超过苹果!华为高端智能手机Q1国内市场出货量占48%
  8. 《『若水新闻』客户端开发教程》——14.代码编写(6)
  9. 并行程序调试、测试与模型检测
  10. C# 与 C++ 数据类型对照
  11. python 评分卡
  12. Idea中jrebel激活码
  13. RNDR | 基于区块链的Web3.0渲染网络
  14. subject 获取登录用户信息
  15. unity 打包APK 应用未安装
  16. 鸿蒙系统手机游戏,鸿蒙系统官网下载手机
  17. vue中的路由对象和路由记录
  18. HTML期末作业课程设计大作业~环境保护学生网页设计作业源码(HTML+CSS)
  19. Windows 7系统实用进阶技巧
  20. CSS进阶(5)- 浏览器兼容性

热门文章

  1. 英雄联盟怎么解除小窗口_英雄联盟手游怎么加好友_英雄联盟手游怎么加好友一起玩_资讯...
  2. quick time不可用_那些校园中“不可言说”的鄙视链
  3. Java读取HTML传人文件,java读取html文件并获取body中所有的标签及内容的案例.pdf
  4. python 整数最大_Python程序使用floor()方法查找最大整数
  5. mysql语句数据库_数据库的Mysql语句
  6. python return用法_初学Python要了解什么 装饰器知识汇总有哪些
  7. ruby hash添加数据_如何在Ruby中向Hash添加元素?
  8. c++中cend end_vector :: cend()函数以及C ++ STL中的示例
  9. Java 200+ 面试题补充 ThreadLocal 模块
  10. 公网访问阿里云数据库MongoDB——填坑笔记