Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
213 lines (171 sloc) 8.98 KB
title tagline last_updated category layout tags published description
java中自定义log4j日志等级以及读取配置文件信息的方法
java
post
java
log4j
true

{% include JB/setup %}

本文主要参考网上两位师兄写的关于log4j详细讲解Log4j 日志详细用法Log4J日志配置详解

log4j日志基本配置用法

log4j是帮助开发人员进行日志输出管理的api类库。它能够很方便的设置日志信息的优先级、日志信息输出目的地、日志信息的输出格式。

定义配置文件log4j.properties

log4j支持两种配置文件格式:

  • XML格式的文件
  • java属性配置文件log4j.properties

这里我们介绍使用log4j.properties文件来配置,下面是一个log4j.pproperties配置的一个简单例子:

log4j.rootLogger=debug,A,R,WA,ER,

log4j.appender.A=org.apache.log4j.ConsoleAppender
log4j.appender.A.Threshold=INFO
log4j.appender.A.layout=org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss},%6.6r]%-5p[%t]%x(%F\:%L) - %m%n   

log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.Threshold=INFO
log4j.appender.R.File=/opt/logs/log111.log
log4j.appender.R.DatePattern='.'yyyy-MM-dd
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss},%6.6r]%-5p[%t]%x(%F\:%L) - %m%n

1、配置根logger,语法如上:log4j.rootLogger=[level],appenderName,appenderName,...,这里level是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL以及自定义的级别。一般我们只使用ERRORWARNINFODEBUG这四个等级,优先级分别从高到底。
通过在这里定义的级别,我们可以控制到程序中对应级别的日志信息打印的开关。我们上面定义的是DEBUG级别,也就是说程序中所有高于或等于DEBUG级别的日志信息将不被打印。若我们定义INFO级别,那么DEBUG级别的日志信息将不会打印。appenderName指定日志输出器。

2、配置日志信息的输出器,基本语法为:

log4j.appender.appenderName=fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1=value1
...
log4j.appender.appenderName.option=valueN

log4j提供的输出器(appender)有一下几种:

org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(文件)
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

3、配置日志信息的格式,语法如下:

log4j.appender.appenderName=fully.qualified.name.of.layout.class
log4j.appender.appenderName.option1=value1
...
log4j.appender.appenderName.option=valueN

log4j提供的layout有一下几种:

org.apache.log4j.HTMLLayout(以HTML表格形式布局)
org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)

在代码中使用log4j

1、得到记录器:

private static Logger logger = Logger.getLogger(MyClass.class);

我们一般通过新定义一个日志记录类并命名为当前类名,来负责当前类中的日志信息输出。

2、插入日志信息:
一般我们的log4j.properties放在工程根目录的话,不需要重新去在代码中通过PropertyConfigurator.configure ( String configFilename);去读取日志配置文件。
通过在类中声明日志记录器之后,我们就可以通过以下代码来输出指定日志信息了:

logger.debug(Object message);
logger.info(Object message);
logger.warn(Object message);
logger.error(Object message);

自定义log4j日志等级

在之前应用中,由于碰到需要将某功能的日志信息进行单独文件输出的情况。这里我们就要自己定义我们自己的日志等级了,下面是一个短信日志记录器及输出器配置:

log4j.logger.smsLogger=DEBUG,SMS
log4j.appender.SMS=org.apache.log4j.FileAppender
log4j.appender.SMS.File=/opt/logs/sms.log
log4j.appender.SMS.DatePattern='.'yyyy-MM-dd
log4j.appender.SMS.layout=org.apache.log4j.PatternLayout
log4j.appender.SMS.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss},%6.6r]%-5p[%t]%x(%F\:%L) - %m%n

比如上面我们定义一个单独的日志记录器smsLogger,并指定它的输出等级及目的输出器。这样在代码中,我们只要取得这个日志记录器就可以调用它来进行日志记录了:

private static Log smsLogger = LogFactory.getLog("smsLogger");

而后面输出器的配置中,我们指定日志以文件的形式记录;日志文件的位置;日志文件每天进行滚动更新,每天生成一个新的日志文件sms.log.yyyy-MM-dd;自定义日志文件的输出样式为自定义并格式化日期输出。

java读取项目中配置文件信息

在配置完log4j日志输出之后,这边需要将某些短信模板放在配置文件中,来进行保存读取。所以在这里一道记录下java读取配置文件的方法。这里主要参考Java配置文件Properties的读取、写入与更新操作

首先需要定义Properties类,并指定读取配置文件(像.properties是一种键值对的形式来保存属性集的特性文件),如下:

private static String profilepath = "sms.properties";
private static Properties props = new Properties();
static {
  try {
    props.load(new FileInputStream(profilepath));
  } catch (FileNotFoundException e) {
    logger.error("短信模板配置文件路径异常", e.getCause());
    e.printStackTrace();
  } catch (IOException e) {
    logger.error("读取短信模板配置文件异常", e.getCause());
    e.printStackTrace();
  }
}

那么接下来就可以调用Properties对象来进行配置未见键值对的读写操作了:

String value = props.getProperty(key);
props.setProperty(keyname, keyvalue);

不过由于我这个工程是需要打包成一个jar包之后,再由其他工程引入使用。所以这里在当前工程中是不能直接读取到sms.properties属性文件的,因为在这里,当前工程的jar包属于一个文件,里面的其他类及配置算是这个文件里面的内容了,需要用流的形式读取。所以修改之后我们的代码如下:

public class DYSMSSender {

	private static Logger logger = Logger.getLogger(DYSMSSender.class);
	private static Log smsLogger = LogFactory.getLog("smsLogger");

  //设置静态配置文件路径以及加载模板配置文件的静态方法
	private static String profilepath = "sms.properties";
	private static Properties props = new Properties();
	static {
		try {
      //这里指定字符编码是防止配置文件和运行环境编码不一致,导致中文乱码的情况
			InputStreamReader is = new InputStreamReader(DYSMSSender.class.getClassLoader().getResourceAsStream(profilepath), "UTF-8");
			props.load(is);
			is.close();
		} catch (FileNotFoundException e) {
			logger.error("短信模板配置文件路径异常", e.getCause());
			e.printStackTrace();
		} catch (IOException e) {
			logger.error("读取短信模板配置文件异常", e.getCause());
			e.printStackTrace();
		}
	}

  /**
	 * 通用短信发送接口
	 * @param phone  //手机号码
	 * @param templateCode  //短信模板code
	 * @param paramMap //短信内容参数
	 */
	public static void sendGeneralMsg(String phone, String templateCode, Map<String, String> paramMap) {
		if(BaseURL.SITE_BASE.contains("http://localhost:8080")){
			logger.info("省钱,本地验证码、通知短信看日志吧....");
		} else {
			String paramJson = JSON.toJSONString(paramMap, true);
			TaobaoClient client = new DefaultTaobaoClient(baseUrl, appKey, appSecret);
			AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
			req.setSmsType("normal");
			req.setSmsFreeSignName("喔图摄影");
			req.setSmsParamString(paramJson);
			req.setRecNum(phone);
			req.setSmsTemplateCode(templateCode);
			AlibabaAliqinFcSmsNumSendResponse rsp = null;
			try {
				rsp = client.execute(req);
			} catch (ApiException e) {
				logger.error("发送短信请求失败!", e.getCause());
			}
			if (rsp.isSuccess()) {
				smsLogger.info("阿里大鱼短信发送: to -->: " + phone + ", template -->: "
			+ props.getProperty("dayu_template." + templateCode) + ", params -->: " + paramJson);
			} else {
				logger.info("阿里大鱼发送短信请求失败,时间:" + new Date() + ",号码:" + phone);
			}
		}
	}