1、导入log4j.jar包
2、在src源码包下建立log4j.properties配置文件
log4j.peoperties
log4j.rootLogger=INFO,Console,RollingFile,RollingFileWarn
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.Threshold=INFO
log4j.appender.Console.layout.ConversionPattern=%d %-5p [%c{5}] - %m%n
#RollingFile
log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.RollingFile.DatePattern='.'yyyy-MM-dd
log4j.appender.RollingFile.File=G://logs/log.log
log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
#RollingFile Warn
log4j.appender.RollingFileWarn=org.apache.log4j.DailyRollingFileAppender
log4j.appender.RollingFileWarn.DatePattern='.'yyyy-MM-dd
log4j.appender.RollingFileWarn.File=G://logs/logwarn.log
log4j.appender.RollingFileWarn.layout=org.apache.log4j.PatternLayout
log4j.appender.RollingFileWarn.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.appender.RollingFileWarn.Append=true
log4j.appender.RollingFileWarn.Threshold=WARN
#loginCtrl登录时写入日志,级别设置为warn
log4j.logger.com.ctrl.loginCtrl=WARN
3、spring-mvc.xml
<!--配置拦截器, 多个拦截器,顺序执行 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
<mvc:mapping path="/goindex.do" />
<bean class="com.frame.interceptor.CommonInterceptor"></bean>
</mvc:interceptor>
<!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
</mvc:interceptors>
4、CommonInterceptor.java
package com.frame.interceptor;
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class CommonInterceptor extends HandlerInterceptorAdapter{
private final Logger log = Logger.getLogger(CommonInterceptor.class);
private static final ThreadLocal<Long> startTimeThreadLocal =
new NamedThreadLocal<Long>("ThreadLocal StartTime");
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
long beginTime = System.currentTimeMillis();//1、开始时间
startTimeThreadLocal.set(beginTime); //线程绑定变量(该数据只有当前请求的线程可见)
log.warn("开始计时:"+new SimpleDateFormat("hh:mm:ss.SSS")
.format(beginTime)+" URI:"+request.getRequestURI());
Thread.currentThread().sleep(3000);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
// 打印JVM信息。
long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间)
long endTime = System.currentTimeMillis(); //2、结束时间
log.warn("计时结束:{"+new SimpleDateFormat("hh:mm:ss.SSS").format(endTime)+"} 耗时:{"+formatDateTime(endTime - beginTime)+"} URI: {"+request.getRequestURI()+"} 最大内存: {"+Runtime.getRuntime().maxMemory()/1024/1024+"}m 已分配内存: {"+Runtime.getRuntime().totalMemory()/1024/1024+"}m 已分配内存中的剩余空间: {"+Runtime.getRuntime().freeMemory()/1024/1024+"}m 最大可用内存: {"+(Runtime.getRuntime().maxMemory()-Runtime.getRuntime().totalMemory()+Runtime.getRuntime().freeMemory())/1024/1024+"}m");
}
/**
* 转换为时间(天,时:分:秒.毫秒)
* @param timeMillis
* @return
*/
public static String formatDateTime(long timeMillis){
long day = timeMillis/(24*60*60*1000);
long hour = (timeMillis/(60*60*1000)-day*24);
long min = ((timeMillis/(60*1000))-day*24*60-hour*60);
long s = (timeMillis/1000-day*24*60*60-hour*60*60-min*60);
long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000);
return (day>0?day+"天"+",":"")+(hour>0?hour+"小时"+",":"")+(min>0?min+"分钟"+",":"")+s+"."+sss+"秒";
}
}
对应日志输出
maxMemory()这个方法返回的是java虚拟机(这个进程)能构从操作系统那里挖到的最大的内存,以字节为单位,如果在运行java程序的时 候,没有添加-Xmx参数,那么就是64兆,也就是说maxMemory()返回的大约是64*1024*1024字节,这是java虚拟机默认情况下能 从操作系统那里挖到的最大的内存。如果添加了-Xmx参数,将以这个参数后面的值为准,例如java -cp ClassPath -Xmx512m ClassName,那么最大内存就是512*1024*0124字节。
totalMemory()这个方法返回的是java虚拟机现在已经从操作系统那里挖过来的内存大小,也就是java虚拟机这个进程当时所占用的所有 内存。如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操作系统那里挖的,基本上是用多少挖多少,直 挖到maxMemory()为止,所以totalMemory()是慢慢增大的。如果用了-Xms参数,程序在启动的时候就会无条件的从操作系统中挖- Xms后面定义的内存数,然后在这些内存用的差不多的时候,再去挖。
freeMemory()是什么呢,刚才讲到如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操 作系统那里挖的,基本上是用多少挖多少,但是java虚拟机100%的情况下是会稍微多挖一点的,这些挖过来而又没有用上的内存,实际上就是 freeMemory(),所以freeMemory()的值一般情况下都是很小的,但是如果你在运行java程序的时候使用了-Xms,这个时候因为程 序在启动的时候就会无条件的从操作系统中挖-Xms后面定义的内存数,这个时候,挖过来的内存可能大部分没用上,所以这个时候freeMemory()可 能会有些大。