log4j几个tips

log4j是很常用的日志框架,这里总结几个小知识点:

1. logger是以名称为key,logger为value的形式存储在Hashtable里,所以,logger作为入参不需要传入引用,直接输入名称get即可。

LogFactoryImpl.java


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16


/**

* The {@link org.apache.commons.logging.Log} instances that have

* already been created, keyed by logger name.

*/

protected Hashtable instances = new Hashtable();

public Log getInstance(String name) throws LogConfigurationException {

Log instance = (Log) instances.get(name);

if (instance == null) {

instance = newInstance(name);

instances.put(name, instance);

}

return (instance);

}

2. logger的继承关系是根据名称的“.”分割来区分,表现为子logger打印日志时遍历父logger里的appender的进行日志打印。

Category.java


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20


public

void callAppenders(LoggingEvent event) {

int writes = 0;

for(Category c = this; c != null; c=c.parent) {

// Protected against simultaneous call to addAppender, removeAppender,...

synchronized(c) {

if(c.aai != null) {

writes += c.aai.appendLoopOnAppenders(event);

}

if(!c.additive) {

break;

}

}

}

if(writes == 0) {

repository.emitNoAppenderWarning(this);

}

}

3.定义模块名为常量,按模块名称取logger,解决项目里包名类名相同日志无法区分问题。

贴代码:
示例一


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43


package com.zoo;

import java.util.Properties;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.apache.log4j.PropertyConfigurator;

/**

*

* @author yankai913@gmail.com

* @date 2014年12月22日

*/

public class LogTest {

static final Log log = LogFactory.getLog(LogTest.class);

public static void main(String[] args) {

Properties properties = new Properties();

properties.setProperty("log4j.rootLogger", "DEBUG,stdout");

properties.setProperty("log4j.appender.stdout", "org.apache.log4j.ConsoleAppender");

properties.setProperty("log4j.appender.stdout.layout", "org.apache.log4j.PatternLayout");

properties.setProperty("log4j.appender.stdout.layout.ConversionPattern",

"%d [%t] %-5p %C{6} (%F:%L) - %m%n");

// log4j的继承关系是"."

// log --> com.zoo.LogTest

// log2(父log) --> com.zoo

// log3(父log2) --> com

// 以此类推

// 子logger的继承关系表现是,子logger打印日志时,遍历父logger里的appender

// 进行日志打印,"com.zoo.LogTest"的父子logger分别是:

// "com.zoo.LogTest"的logger -> "com.zoo"的logger -> "root"的logger。

// 以下这句话定义了上述的log2(即父log),导致日志打印2次。

properties.setProperty("log4j.logger.com.zoo", "INFO, stdout");

// 以下这句话定义com.zoo包的logger(即log2)的appender不被继承,日志打印只有一条。

properties.setProperty("log4j.additivity.com.zoo", "false");

PropertyConfigurator.configure(properties);

System.out.println(log);

log.info("Hello World!");

System.out.println("end");

}

}

示例二


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78


package com.zoo;

import java.util.Properties;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.apache.log4j.PropertyConfigurator;

/**

*

* @author yankai913@gmail.com

* @date 2014年12月22日

*/

public class LogTest2 {

// 定义公共的logerName,按module分

static final String Module1_LogName = "Module1";

static final String Module2_LogName = "Module2";

public static void main(String[] args) {

Properties properties = new Properties();

properties.setProperty("log4j.rootLogger", "DEBUG,file");

properties.setProperty("log4j.appender.file", "org.apache.log4j.FileAppender");

properties.setProperty("log4j.appender.file.layout", "org.apache.log4j.PatternLayout");

properties.setProperty("log4j.appender.file.layout.ConversionPattern",

"%d [%t] %-5p %c{1} %C{6} (%F:%L) - %m%n");

properties.setProperty("log4j.appender.file.append", "true");

properties.setProperty("log4j.appender.file.file", "logtest2.log");

PropertyConfigurator.configure(properties);

// 比较同名称的log,结果为true,所以log作为入参不需要传入引用,直接get即可。

System.out.println(Module1.log.equals(ServiceImpl_1.log));

System.out.println(Module2.log.equals(ServiceImpl_2.log));

// 按模块搜索查看日志,关键词就是模块名称,即上面的Module1,Module2。

// 解决包名类名完全一样,但是在不同模块的日志查询。

Module1.println();

Module2.println();

ServiceImpl_1.println();

ServiceImpl_2.println();

System.out.println("end");

}

public static class Module1 {

public static Log log = LogFactory.getLog(Module1_LogName);

public static void println() {

log.info("this is module1");

}

}

public static class Module2 {

public static Log log = LogFactory.getLog(Module2_LogName);

public static void println() {

log.info("this is module2");

}

}

public static class ServiceImpl_1 {

public static Log log = LogFactory.getLog(Module1_LogName);

public static void println() {

log.info("this is service");

}

}

public static class ServiceImpl_2 {

public static Log log = LogFactory.getLog(Module2_LogName);

public static void println() {

log.info("this is service");

}

}

}

练习代码看这里

时间: 2024-08-03 13:32:16

log4j几个tips的相关文章

一个与Log4j相关的死锁(转)

 这个死锁的原因:一个动作需要两个临界对象.静态同步方法,就是一个临界对象.这种场景,静态同步方法每次只能有一个线程持有.如果存在另一个临界对象,静态同步方法中也需要获取这个临界对象.即一个动作需要两个临界对象. We are experiencing deadlocks on our server. We have tested with log4j version 1.2.8 up to and including 1.2.15 We have identified that cause t

Log4j输出到mysql数据库

问题描述 Log4j输出到mysql数据库 用MDC.put()将值放进去,再使用log.info()触发.但是触发前总会有一行空白的字段自动添加进去.这是什么原因?怎么设置自定义级别呢?就是当我想输出到数据库就输出,不想就不输出,应该怎么写呢? 解决方案 http://blog.csdn.net/yaerfeng/article/details/18151339 解决方案二: http://xialiang19851204.blog.163.com/blog/static/3720773520

LOG4J输出日志到web目录的相对路径

 LOG4J输出日志到web目录的相对路径 项目中必须是在使用spring web.xml加入 <span style="font-size:18px;"><context-param> <param-name>webAppRootKey</param-name> <param-value>webApp.root</param-value> </context-param> <context-

40个良好用户界面Tips

1 尽量使用单列而不是多列布局 单列布局能够让对全局有更好的掌控.同时用户也可以一目了然内容.而多列而已则会有分散用户注意力的风险使你的主旨无法很好表达.最好的做法是用一个有逻辑的叙述来引导用户并且在文末给出你的操作按钮. 2 放出礼品往往更具诱惑力 给用户一份精美小礼品这样的友好举动再好不过了.具体来讲,送出礼品也是之有效的获得客户忠诚度的战术,这是建立在人们互惠准则上的.而这样做所带来的好处也是显而易见的,会让你在往后的活动进展(不管是推销,产品更新还是再次搞活动)中更加顺利. 3 合并重复

mybatis显示sql语句log4j配置

log4j.logger.com.ibatis=DEBUG log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG log4j.logger.java.sql.Connection=DEB

Java必知小Tips

Tips 1: Java里面Override返回值是否必须和父类相同 1234567891011121314151617181920212223242526272829 class Base { public Base newInstance() { return new Base(); } public Base newInstance2() { return new Base(); } public Number hello() { return 0; }}class Test extend

slf4j-api、slf4j-log4j12以及log4j之间的关系

几乎在每个jar包里都可以看到log4j的身影,在多个子工程构成项目中,slf4j相关的冲突时不时就跳出来让你不爽,那么slf4j-api.slf4j-log4j12还有log4j是什么关系?      slf4j:Simple Logging Facade for Java,为java提供的简单日志Facade.Facade门面,更底层一点说就是接口.它允许用户以自己的喜好,在工程中通过slf4j接入不同的日志系统.更直观一点,slf4j是个数据线,一端嵌入程序,另一端链接日志系统,从而实现将

UML Use Case Diagrams: Tips and FAQ

UML Use Case Diagrams: Tips and FAQ 来源:http://www.andrew.cmu.edu/course/90-754/umlucdfaq.html Contents: What is a UML Use Case Diagram (UCD), and when should I use it? How do you know who the actors are in a UCD? How do you know what to put in the "S

log4j在服务器不打印日志

问题描述 log4j在服务器不打印日志 我在本地配置可以打印.但是当我放到服务器上面去之后,却不打印日志了. 唯一改动的地方就是日志所在路径了. 都是用的绝对路径. log4j.appender.dailyFile.File=E:/work/apache-tomcat-6.0.44/webapps/ifpws/logs/message.log 在服务器中就是把这个路径换了个位置.但是不打印日志了. 路径下面有事先建立好的message.log. 本地 win7 64 , 服务器 win serv