在进行代码开发的过程中,日志是非常重要的。如果没有日志是难以进行代码调试和排错的。
在开发过程中,我们可以选择适合自己(团队)的日志类来实现日志输出,也可以自己编写日志类来实现(也是有一定工作量的,不推荐),当然也可以选择第三方的日志类来辅助,比如Log4j等。如果开发环境是JDK1.4以上的话,可以利用JDK自带的日志类java.util.logging,也可以使用第三方的日志类;如果开发环境是JDK1.3,那就只能使用第三方的日志类,或者自行编写日志类。
本文主要介绍如何在Log4j的基础上,实现符合自己需要的日志类。
Log4j功能相当完善,一般都通过脚本配置将日志按照一定的规则输出到文件或者console上,这种做法还是比较灵活的。
但现在需求比较特殊:
1、不想把日志输出到一个确定的文件中,而希望是哪个类的日志就输出到以这个类命名的文件中(通过脚本较难实现,如何您能实现的话,请一定要告诉我,呵呵);
2、每天的日志放在以日期命名的文件夹中,比如今天是2006-12-15,那么日志所在的文件夹是061215;
3、对于每天的日志采用循环日志,日志文件最大大小为2M,超过2M就清空重写(这个功能Log4j本身是可以实现的);
4、日志输出应包含时间(这个功能Log4j本身也是可以实现的)。
下面是自行编写的LogBase类,文件名为:LogBase.java
------------------------------------------------------------------------------------------------
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ResourceBundle;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
public class LogBase {
private static String PROPERTIES_FILE = "logconf";
private static String LOG_PATH;
private static String DATE_LOG_FOLDER;
private static String LOG_LEVEL;
private static String PATTERN_LAYOUT;
private static long MAX_FILE_SIZE;
private LogBase() {
}
public static Logger getLogInstance(String name) {
Logger logger = Logger.getLogger(name);
try {
String pattern = getPatternLayout();
RollingFileAppender appender = new RollingFileAppender(
new PatternLayout(pattern), createClassLogFile(name)
.getAbsolutePath());
long maxfilesize = getMaxFileSize();
appender.setMaximumFileSize(maxfilesize);
logger.addAppender(appender);
String level = getLogLevel();
logger.setLevel((Level) Level.toLevel(level));
} catch (Exception e) {
e.printStackTrace();
}
return logger;
}
/*
* 在LOG_PATH下创建以当天日期为名字的文件夹
*/
private static File createDateLogFolder() {
LOG_PATH = getLogPath();
if (LOG_PATH == null) {
readLogConfigParams();
}
String currentdate = getCurrentDate();
DATE_LOG_FOLDER = LOG_PATH + System.getProperty("file.separator")
+ currentdate;
File logFolder = new File(DATE_LOG_FOLDER);
try {
if (!logFolder.exists()) {
logFolder.mkdirs();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return logFolder;
}
private static File createClassLogFile(String classname) {
if (DATE_LOG_FOLDER == null) {
createDateLogFolder();
}
String classnameString = DATE_LOG_FOLDER
+ System.getProperty("file.separator") + classname + ".txt";
File logFile = new File(classnameString);
try {
if (!logFile.exists()) {
logFile.createNewFile();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return logFile;
}
private static void readLogConfigParams() {
ResourceBundle rb = ResourceBundle.getBundle(PROPERTIES_FILE);
LOG_PATH = rb.getString("LOG_PATH");
LOG_LEVEL = rb.getString("LOG_LEVEL");
PATTERN_LAYOUT = rb.getString("PATTERN_LAYOUT");
MAX_FILE_SIZE = Long.parseLong(rb.getString("MAX_FILE_SIZE"));
}
private static String getLogPath() {
return LOG_PATH;
}
private static String getCurrentDate() {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
return df.format(new Date());
}
private static String getLogLevel() {
if (LOG_LEVEL == null) {
readLogConfigParams();
}
return LOG_LEVEL;
}
private static String getPatternLayout() {
if (PATTERN_LAYOUT == null) {
readLogConfigParams();
}
return PATTERN_LAYOUT;
}
private static long getMaxFileSize() {
if (!(MAX_FILE_SIZE > 0)) {
readLogConfigParams();
}
return MAX_FILE_SIZE;
}
public static void main(String[] args) {
Logger logger = LogBase.getLogInstance("LogBase");
logger.info("info");
logger.error("error");
}
}
------------------------------------------------------------------------------------------------
LogBase类从配置文件logconf.properties文件中读入日志存放路径,logconf.properties文件内容很简单,如下:
------------------------------------------------------------------------------------------------
LOG_PATH = D:\\logs
LOG_LEVEL = Level.DEBUG
PATTERN_LAYOUT = %-5p %d{yyyy-MM-dd HH:mm:ss} %m%n
#MaxFileSize is set to about 10M
MAX_FILE_SIZE = 10485760
------------------------------------------------------------------------------------------------
注意,LogBase类对外只提供一个public类型的方法getLogInstance(String name),其余类都是private类型的。getLogInstance方法返回的类型是Logger,在getLogInstance方法中通过addAppender指向一个RollingFileAppender类型的文件,并设置日志文件的最大大小,然后通过setLevel方法设置日志级别。LOG_LEVEL,PATTERN_LAYOUT和MAX_FILE_SIZE都从配置文件中取得。
写好这个类后,当需要使用LogBase类的时候,只要在你的源程序中加入:private static Logger logger = LogBase.getLogInstance("XXXXXX");
XXXXXX代表你的类名,然后通过logger.info()之类的进行写日志就可以了。
例如下面的测试
------------------------------------------------------------------------------------------------
import org.apache.log4j.Logger;
public class LogBaseTest {
private static Logger logger = LogBase.getLogInstance("LogBaseTest");
public static void main(String[] args) {
logger.info("LogBaseTest");
}
}
------------------------------------------------------------------------------------------------
运行结束后,请到日志路径下查找,是否出现以今天日期为名字的文件夹,并检查该文件夹里面是否有一个LogBaseTest.txt文件,看看文件里的内容是什么样子的,日志格式应该如下:
INFO 2006-12-15 13:33:36 LogBaseTest
以上的源程序和配置文件,请下载附件。
如果读者对以上的内容有任何疑问,可以和我联系,
jw_ws@163.com 版权所有,严禁转载