During system running, sometimes we can see the error message from log4j log:
log4j:ERROR Attempted to append to closed appender named [*].
Here I would like to talk about one use case which could cause this problem.
Most of the components in our project could use log4j, and some of them could have duplicated log4j configuration file:
- log4j.xml and log4j.properties
Here is a log4j.xml demo for my test:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
<!-- Main log file for general output from SSP server. -->
<appender name="SYSTEM"
class="com.gemalto.util.log4j.DailyMaxRollingFileAppender">
<param name="File" value="logs/logFromlog4jXMLAppender.log" />
<param name="Append" value="true" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="maxNumberOfDays" value="7" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [GTO] [%c] %X{MSISDN} %X{IMEI} %m%n" />
</layout>
</appender>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n" />
</layout>
</appender>
<category name="com.test" additivity="true">
<priority value="DEBUG" />
<appender-ref ref="SYSTEM" />
</category>
<root>
<priority value="INFO" />
<appender-ref ref="SYSTEM" />
<appender-ref ref="CONSOLE" />
</root>
</log4j:configuration>
Also, there is a log4j.properties in same location as log4j.xml:
log4j.rootCategory=DEBUG, stdout
log4j.logger.com=DEBUG, smsdriver
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.appender.smsdriver=com.gemalto.util.log4j.DailyMaxRollingFileAppender
log4j.appender.smsdriver.file=logs/logFromlog4jPropertiesAppender.log
log4j.appender.smsdriver.append=true
log4j.appender.smsdriver.layout=org.apache.log4j.PatternLayout
log4j.appender.smsdriver.layout.ConversionPattern=%d %p [%c] - <%m> %F %n
During our test, we will load log4j.xml first to configure Logger Hierarchy, and then load log4j.properties to configure Logger Hierarchy. We will see what happen according to logs.
Here is the test code on log4j configuration:
@Test
public void testlog4jConfigurator() throws Exception {
System.setProperty("log4j.debug", "true");
Logger logger = org.apache.log4j.Logger
.getLogger("com.DOMConfigurator");
logger.info("Logger before DOMConfigurator."); //#1
System.setProperty("log4j.defaultInitOverride", "true");
URL log4jXml = TempTest.class.getResource("/log4j.xml");
URL log4jProperties = TempTest.class.getResource("/log4j.properties");
DOMConfigurator.configure(log4jXml);
Logger loggerDOMConfigurator = org.apache.log4j.Logger
.getLogger("com.DOMConfigurator");
loggerDOMConfigurator.info("Logger loggerDOMConfigurator.");//#2
// assertEquals(logger, loggerDOMConfigurator);
Logger loggerDOMConfigurator2 = org.apache.log4j.Logger
.getLogger("com.test.2");
Logger loggerDOMConfigurator3 = org.apache.log4j.Logger
.getLogger("com.test.3");
PropertyConfigurator.configureAndWatch(getFilePath(log4jProperties));
loggerDOMConfigurator.info("Logger loggerPropertyConfigurator."); //#3
// assertEquals(loggerPropertyConfigurator, loggerDOMConfigurator);
loggerDOMConfigurator2.info("Logger loggerDOMConfigurator2."); //#4
loggerDOMConfigurator3.info("Logger loggerDOMConfigurator3."); //#5
}
By default, org.apache.log4j.LogManager will load "log4j.xml", so we can see #1 and #2 output into file: logs/logFromlog4jXMLAppender.log:
2011-12-22 10:17:52,669 INFO [GTO] [com.DOMConfigurator] Logger before DOMConfigurator.
2011-12-22 10:17:52,669 INFO [GTO] [com.DOMConfigurator] Logger loggerDOMConfigurator.
#3 will output into file: logs/logFromlog4jPropertiesAppender.log:
2011-12-22 10:17:52,684 INFO [com.DOMConfigurator] - <Logger loggerPropertyConfigurator.> Log4jTest.java
#4 and #5 will be log into file logs/logFromlog4jPropertiesAppender.log because we configure a Category: log4j.logger.com. BUT we cannot see any log in logs/logFromlog4jXMLAppender.log. AND we will see the following errors in console:
log4j:ERROR Attempted to append to closed appender named [SYSTEM].
log4j:ERROR Attempted to append to closed appender named [SYSTEM].
Solutions
Here I would like to list some workaround.
1: Remove APPENDER ref from root category
We can remove the appender-ref to "SYSTEM" in log4j.xml/root like following:
<category name="com.test" additivity="true">
<priority value="DEBUG" />
<appender-ref ref="SYSTEM" />
</category>
<root>
<priority value="INFO" />
<!--appender-ref ref="SYSTEM" /-->
<appender-ref ref="DMCONSOLE" />
</root>
There won't be any error message refer to appender closed. In this case, we can see #4 and #5 logs in both files.
(Please be aware of that #2 won't be logged in this case.)
2: Remvoe APPENDER ref in specific Category
We can also remove the appender-ref to "SYSTEM" in log4j.xml/Category/com.test like following:
<category name="com.test" additivity="true">
<priority value="DEBUG" />
<!--appender-ref ref="SYSTEM" /-->
</category>
<root>
<priority value="INFO" />
<appender-ref ref="SYSTEM" />
<appender-ref ref="DMCONSOLE" />
</root>
In this case, there also won't be any error message refer to "appender closed". But #4 and #5 will only be logged in file: logs/logFromlog4jPropertiesAppender.log.
Conclusion
As descript in log4j, there will be only one Logger instance with specific name. Log4j allows logging requests to print to multiple destinations. In log4j speak, an output destination is called an appender. Currently, appenders exist for the console, files, GUI components, remote socket servers, JMS, NT Event Loggers, and remote UNIX Syslog daemons. It is also possible to log asynchronously.
More than one appender can be attached to a logger.
The addAppender method adds an appender to a given logger. Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy.
As we can see, Appender related to logger could be modified during second Configurator. So the error comes.
分享到:
相关推荐
Kernel panic - not syncing: Attempted to kill init 解决办法 开源成就技术;技术成就梦想
在Linux系统中,"Kernel panic(Attempted to kill init!)"是一个非常严重的错误提示,它意味着内核遇到了无法恢复的问题,通常会导致系统崩溃。这个错误通常发生在ARM架构的设备上,比如开发板、嵌入式系统或者...
0x000000BE (ATTEMPTED_WRITE_TO_READONLY_MEMORY) **含义**:试图写入只读内存。 **原因**:软件或驱动程序试图修改只读内存。 **解决方案**: - 卸载引起问题的软件。 - 更新驱动程序。 ##### 29. 0x000000C2...
本人最近在玩树莓派4B的时候,树莓派在烧录镜像之后,无法启动,一直卡死在end kernel panic not syncing: attempted to kill init! exitcode = 0x00000000b 环境 设备:树莓派4B 查找原因–树莓派官网 根据官网给...
在使用MyEclipse进行SVN提交时遇到错误:“Attempted to lock an already-locked dir”,具体表现为以下错误信息: ``` svn: Working copy 'D:/Program Files/MyEclipse 6.6flex/workspace/emis/WebRoot/emis/...
- **Attempted write protect violation**:尝试写入保护违规,当试图向受写入保护的设备写入数据时出现的错误提示。 - **Backing up files to diskette**:把文件备份到磁盘上,早期的数据备份方法。 - **Bad call ...
17. **attempt to do**:试图做某事,如“The boys attempted to leave for Beijing.”。 18. **wake 和 wake up**:wake是动词,表示唤醒;wake up表示醒来,如“Please wake me up at 8 o'clock.”。 19. **look...
1000000 attempted fails 1000000 resets received ``` #### 27. `ps -ef` - **用途**:显示所有运行中的进程。 - **示例输出**: ``` UID PID PPID C STIME TTY TIME CMD root 1 0 0 01:45 ? 00:00:00 /sbin...
11. **STOP 0x000000FE (ATTEMPTED_WRITE_TO_READONLY_MEMORY)** - **含义**:尝试写入只读内存。 - **可能原因**: - 驱动程序错误 - 内存故障 - **解决方法**: - 更新驱动程序。 - 测试内存条。 #### ...
标题“win7 odbc SQORAS32: An Unsupported operation was attempted”涉及到的是在Windows 7操作系统中,用户遇到一个ODBC(Open Database Connectivity)相关的错误。ODBC是微软提供的一种标准API,允许应用程序...
- **Division by zero attempted**:尝试执行除以零的操作时会触发此错误。 - **Overflow—Number too big**:当数值超过库能表示的最大范围时会触发此错误。 - **Internal Result is Negative**:如果内部结果为...
- **答案**:填入的词汇包括generally、rival、extending、in the hands of、distinctions、ineffectively、propose、attempted、desperation、surrender。 ### 二、词汇与结构部分(Part II Vocabulary and ...
### 问题8: Kernel panic – not syncing: Attempted to kill init! 这种错误通常由编译器和内核ABI(Application Binary Interface)不兼容引起。解决方案包括: 1. **启用EABI编译**:如果使用的是支持EABI的...
如果修复GRUB之后仍然出现问题,如“Kernel panic – not syncing: Attempted to kill init!”,这通常意味着内核未能找到必要的SCSI驱动。 1. **再次进入恢复模式**。 2. **修改配置文件**: - 执行`# vim /etc/...
在使用Subversion(SVN)进行版本控制时,有时可能会遇到一个常见的错误提示:“org.apache.subversion.javahl.ClientException: Attempted to lock an already-locked dir”。这个错误通常表示某个目录已经被锁定,...
### 4. 代码含义和解决方案 - `0x0000000A`: IRQL_NOT_LESS_OR_EQUAL,通常与驱动或硬件不兼容有关,可能需要更新驱动或检查硬件。 - `0x0000001E`: KMODE_EXCEPTION_NOT_HANDLED,可能是硬件兼容性问题,需要检查...
4. **职务 (Job title)**:销售人员的职位,如初级销售代表、高级销售顾问等,这有助于理解不同级别的销售人员在电话销售中的表现差异。 5. **标准 (Criteria)**:这些是评估电话销售效果的关键指标,可能包括但不...
- 确保你的项目目标框架与SDK兼容,通常是.NET Framework 4.x或更高版本。 2. **初始化相机**: - 使用SDK提供的API函数,例如`InitDevice`,通过相机的IP地址或MAC地址来初始化相机连接。 - 初始化过程中可能...