使用log4j在web项目中,需要打印日志到文件中。使用相对路径,默认的是相对于tomcat的bin目录下。顿时觉得很坑。寻找解决到相对于项目之下,踩了很多坑。最后决定自己实现配置加载处理,就不会出现什么问题。
使用servlet加载log4j配置,log4j只在项目启动加载一次,所以给servlet加load-on-startup为1就行,代表的是服务启动就加载此servlet
我的log4j配置文件 |
log4j.rootLogger=DEBUG, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] %t - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=logs/logs.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] %t - %m%n
加载log4j的servlet配置 |
<servlet>
<servlet-name>log4jServlet</servlet-name>
<servlet-class>tao.Control.Log4jInitControl</servlet-class>
<!--log4j的配置文件路径-->
<init-param>
<param-name>log4j-location</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</init-param>
<!--这个参数可写可不写,properties中有日志输出文件路径配置,-->
<!--首先依照配置文件中的-->
<!--没有,可以在此处写相对项目的路径-->
<init-param>
<param-name>logSavePath</param-name>
<param-value>/logs/all.logs</param-value>
</init-param>
<!--log4j的配置驱动-->
<init-param>
<param-name>logDriverName</param-name>
<param-value>logfile</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
加载log4j的servlet |
public class Log4jInitControl extends HttpServlet{
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("Log4JInitServlet 正在初始化 log4j日志设置信息");
setConfig(config);
}
private void setConfig(ServletConfig config){
String log4jLocation = config.getInitParameter("log4j-location"); //配置文件的相对路径
ServletContext sc = config.getServletContext();
if(null == log4jLocation){
System.err.println("*** 没有 log4j-properties-location 初始化的文件, 所以使用 BasicConfigurator初始化");
BasicConfigurator.configure();//使用默认配置
}else {
String webAppPath = sc.getRealPath("/"); // 得到项目webRoot的路径
String filePath = webAppPath+log4jLocation; // 配置文件绝对路径路径
File cfg = new File(filePath);
if(!cfg.exists()){
System.err.println("*** " + filePath + " 文件没有找到, 所以使用 BasicConfigurator初始化");
BasicConfigurator.configure();
return;
}
Properties props = new Properties();
try {
String logSavePath = config.getInitParameter("logSavePath");
FileInputStream fs = new FileInputStream(filePath);
props.load(fs);//加载配置文件
System.out.println(props.getProperty("log4j.rootLogger"));
fs.close();
webAppPath = webAppPath.substring(0,webAppPath.lastIndexOf("\\"));
webAppPath = webAppPath.substring(0,webAppPath.lastIndexOf("\\"));
webAppPath = webAppPath.substring(0,webAppPath.lastIndexOf("\\"));
String projectROOT = webAppPath.substring(0,webAppPath.lastIndexOf("\\")); //得到项目根目录的路径
if (null == props.getProperty("log4j.appender."+config.getInitParameter("logDriverName")+".File")) {//如果在配置文件中没有日志文件的相对路径 ,根据web.xml设置相对路径
if (null != logSavePath)
props.setProperty("log4j.appender." + config.getInitParameter("logDriverName") + ".File", projectROOT + logSavePath);
else
throw new Exception("找不到log4j日志输出路径!");//xml和配置文件都找不到文件配置路径
}else {//根据配置文件设置输出路径
props.setProperty("log4j.appender." + config.getInitParameter("logDriverName") + ".File",
projectROOT + props.getProperty("log4j.appender." + config.getInitParameter("logDriverName") + ".File"));
}
PropertyConfigurator.configure(props);//根据配置文件得到配置对象
}catch (Exception e){
e.printStackTrace();
}
}
}
}
当配置一个东西踩坑的时候,自己写驱动就能解决问题。虽然不一定是最佳的,但是能给问题带来一定的解决。