问题描述
以下在这里,我想,我想通过自定义转换器扩展log4j,以将Shiro用户名添加到日志中.这是我的代码:
@Plugin(name = "shiro", type = "Converter") @ConverterKeys({"susr", "shiro"}) public class ShiroUserConverter extends LogEventPatternConverter { private static final ShiroUserConverter INSTANCE = new ShiroUserConverter(); private ShiroUserConverter() { this("shiro", "shiro"); // not sure why! } protected ShiroUserConverter(String name, String style) { super(name, style); } public static ShiroUserConverter newInstance(final String[] options) { return INSTANCE; } @Override public void format(LogEvent arg0, StringBuilder arg1) { // TODO Auto-generated method stub Subject currentUser = SecurityUtils.getSubject(); if ( currentUser != null && currentUser.getPrincipal() != null) arg1.append(currentUser.getPrincipal().toString()); else arg1.append("No User"); }
}
配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration status="debug"> <appenders> <File name="A1" fileName="/tmp/logs/A1.log" append="false"> <PatternLayout pattern="%d %-5p [%t] [%susr] %C{2} (%F:%L) - %m%n"/> </File> <Console name="STDOUT" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p [%t] [%susr] %C{2} (%F:%L) - %m%n"/> </Console> </appenders> <loggers> <logger name="org.apache.log4j.xml" level="debug"> <appender-ref ref="A1"/> </logger> <root level="debug"> <appender-ref ref="A1"/> </root> </loggers> </configuration>
问题是log4j不会拿起我的自定义转换器.当我调试时,我会收到以下错误消息:
ERROR Unrecognized format specifier [susr] ERROR Unrecognized conversion specifier [susr] starting at position 19 in conversion pattern.
我什至把我的班级放在同一包中package org.apache.log4j.pattern;,但仍然没有运气.任何帮助将不胜感激.
- 编辑:这是完整的控制台输出:
2013-08-09 16:55:01,370 DEBUG Found Plugin Map at jar:file:/Users/path/to/log4j-core-2.0-beta5.jar!/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat 2013-08-09 16:55:01,373 DEBUG Generated plugins in 0.003793000 seconds 2013-08-09 16:55:01,374 DEBUG Generated plugins in 0.000551000 seconds 2013-08-09 16:55:01,375 DEBUG Generated plugins in 0.000548000 seconds 2013-08-09 16:55:01,376 DEBUG Generated plugins in 0.000555000 seconds 2013-08-09 16:55:01,377 DEBUG Generated plugins in 0.000546000 seconds 2013-08-09 16:55:01,378 DEBUG Generated plugins in 0.000540000 seconds 2013-08-09 16:55:01,379 DEBUG Generated plugins in 0.000546000 seconds 2013-08-09 16:55:01,380 DEBUG Generated plugins in 0.000548000 seconds 2013-08-09 16:55:01,381 DEBUG Generated plugins in 0.000556000 seconds 2013-08-09 16:55:01,382 DEBUG Generated plugins in 0.000552000 seconds 2013-08-09 16:55:01,390 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %-5p [%t] %susr %C{2} (%F:%L) - %m%n", Configuration(/Users/path/to/target/classes/WEB-INF/log4j.properties), null, charset="null") 2013-08-09 16:55:01,392 DEBUG Generated plugins in 0.000585000 seconds 2013-08-09 16:55:01,392 ERROR Unrecognized format specifier [susr] 2013-08-09 16:55:01,393 ERROR Unrecognized conversion specifier [susr] starting at position 18 in conversion pattern. 2013-08-09 16:55:01,399 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.FileAppender for element File with params(fileName="/tmp/logs/A1.log", append="true", locking="null", name="A1", immediateFlush="null", suppressExceptions="null", bufferedIO="null", PatternLayout(%d %-5p [%t] %susr %C{2} (%F:%L) - %m%n), null, advertise="null", advertiseURI="null", Configuration(/Users/path/to/target/classes/WEB-INF/log4j.properties)) 2013-08-09 16:55:01,401 DEBUG Starting FileManager /tmp/logs/A1.log 2013-08-09 16:55:01,402 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %-5p [%t] [%susr] %C{2} (%F:%L) - %m%n", Configuration(/Users/path/totarget/classes/WEB-INF/log4j.properties), null, charset="null") 2013-08-09 16:55:01,403 ERROR Unrecognized format specifier [susr] 2013-08-09 16:55:01,403 ERROR Unrecognized conversion specifier [susr] starting at position 19 in conversion pattern. 2013-08-09 16:55:01,405 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console with params(PatternLayout(%d %-5p [%t] [%susr] %C{2} (%F:%L) - %m%n), null, target="SYSTEM_OUT", name="STDOUT", follow="null", suppressExceptions="null") 2013-08-09 16:55:01,405 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.plugins.AppendersPlugin for element appenders with params(appenders={A1, STDOUT}) 2013-08-09 16:55:01,407 DEBUG Generated plugins in 0.000665000 seconds 2013-08-09 16:55:01,407 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.AppenderRef for element appender-ref with params(ref="A1", level="null", null) 2013-08-09 16:55:01,409 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig for element logger with params(additivity="null", level="debug", name="org.apache.log4j.xml", includeLocation="null", appender-ref={org.apache.logging.log4j.core.config.AppenderRef@f818d7}, properties={}, Configuration(/Users/path/to/target/classes/WEB-INF/log4j.properties), null) 2013-08-09 16:55:01,410 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.AppenderRef for element appender-ref with params(ref="A1", level="null", null) 2013-08-09 16:55:01,411 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger for element root with params(additivity="null", level="debug", includeLocation="null", appender-ref={org.apache.logging.log4j.core.config.AppenderRef@530ababd}, properties={}, Configuration(/Users/path/to/target/classes/WEB-INF/log4j.properties), null) 2013-08-09 16:55:01,412 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.config.plugins.LoggersPlugin for element loggers with params(loggers={org.apache.log4j.xml, root})
推荐答案
将您的配置行更改为
<configuration status="debug" packages="path.to.ShiroUserConverterDirectory">
要清楚,包是包含类的目录,而不是类本身.
我有以下操作:
package com.test.util; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.pattern.ConverterKeys; import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; @Plugin(name = "shiro", category = "Converter") @ConverterKeys({"susr", "shiro"}) public class ShiroUserConverter extends LogEventPatternConverter { private static final ShiroUserConverter INSTANCE = new ShiroUserConverter(); private ShiroUserConverter() { this("shiro", "shiro"); // not sure why! } protected ShiroUserConverter(String name, String style) { super(name, style); } public static ShiroUserConverter newInstance(final String[] options) { return INSTANCE; } @Override public void format(LogEvent arg0, StringBuilder arg1) { // TODO Auto-generated method stub arg1.append("No User"); }
}
和我的log4j2.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration status="debug" packages="com.test.util"> <appenders> <Console name="CA" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p [%t] [%susr] %C{2} (%F:%L) - %m%n"/> </Console> </appenders> <loggers> <root level="debug"> <appender-ref ref="CA"/> </root> </loggers> </configuration>
问题描述
Following here, I'd like to extend log4j by a custom convertor, to add the shiro user name to the log. Here's my code:
@Plugin(name = "shiro", type = "Converter") @ConverterKeys({"susr", "shiro"}) public class ShiroUserConverter extends LogEventPatternConverter { private static final ShiroUserConverter INSTANCE = new ShiroUserConverter(); private ShiroUserConverter() { this("shiro", "shiro"); // not sure why! } protected ShiroUserConverter(String name, String style) { super(name, style); } public static ShiroUserConverter newInstance(final String[] options) { return INSTANCE; } @Override public void format(LogEvent arg0, StringBuilder arg1) { // TODO Auto-generated method stub Subject currentUser = SecurityUtils.getSubject(); if ( currentUser != null && currentUser.getPrincipal() != null) arg1.append(currentUser.getPrincipal().toString()); else arg1.append("No User"); }
}
The configuration file is as follows:
<?xml version="1.0" encoding="UTF-8"?> <configuration status="debug"> <appenders> <File name="A1" fileName="/tmp/logs/A1.log" append="false"> <PatternLayout pattern="%d %-5p [%t] [%susr] %C{2} (%F:%L) - %m%n"/> </File> <Console name="STDOUT" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p [%t] [%susr] %C{2} (%F:%L) - %m%n"/> </Console> </appenders> <loggers> <logger name="org.apache.log4j.xml" level="debug"> <appender-ref ref="A1"/> </logger> <root level="debug"> <appender-ref ref="A1"/> </root> </loggers> </configuration>
The problem is that log4j does not pick up my custom convertor. When I debug it, I get the following error message:
ERROR Unrecognized format specifier [susr] ERROR Unrecognized conversion specifier [susr] starting at position 19 in conversion pattern.
I even put my class in the same package package org.apache.log4j.pattern; but still no luck. Any help would be appreciated.
-- Edit: This is the full console output:
2013-08-09 16:55:01,370 DEBUG Found Plugin Map at jar:file:/Users/path/to/log4j-core-2.0-beta5.jar!/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat 2013-08-09 16:55:01,373 DEBUG Generated plugins in 0.003793000 seconds 2013-08-09 16:55:01,374 DEBUG Generated plugins in 0.000551000 seconds 2013-08-09 16:55:01,375 DEBUG Generated plugins in 0.000548000 seconds 2013-08-09 16:55:01,376 DEBUG Generated plugins in 0.000555000 seconds 2013-08-09 16:55:01,377 DEBUG Generated plugins in 0.000546000 seconds 2013-08-09 16:55:01,378 DEBUG Generated plugins in 0.000540000 seconds 2013-08-09 16:55:01,379 DEBUG Generated plugins in 0.000546000 seconds 2013-08-09 16:55:01,380 DEBUG Generated plugins in 0.000548000 seconds 2013-08-09 16:55:01,381 DEBUG Generated plugins in 0.000556000 seconds 2013-08-09 16:55:01,382 DEBUG Generated plugins in 0.000552000 seconds 2013-08-09 16:55:01,390 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %-5p [%t] %susr %C{2} (%F:%L) - %m%n", Configuration(/Users/path/to/target/classes/WEB-INF/log4j.properties), null, charset="null") 2013-08-09 16:55:01,392 DEBUG Generated plugins in 0.000585000 seconds 2013-08-09 16:55:01,392 ERROR Unrecognized format specifier [susr] 2013-08-09 16:55:01,393 ERROR Unrecognized conversion specifier [susr] starting at position 18 in conversion pattern. 2013-08-09 16:55:01,399 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.FileAppender for element File with params(fileName="/tmp/logs/A1.log", append="true", locking="null", name="A1", immediateFlush="null", suppressExceptions="null", bufferedIO="null", PatternLayout(%d %-5p [%t] %susr %C{2} (%F:%L) - %m%n), null, advertise="null", advertiseURI="null", Configuration(/Users/path/to/target/classes/WEB-INF/log4j.properties)) 2013-08-09 16:55:01,401 DEBUG Starting FileManager /tmp/logs/A1.log 2013-08-09 16:55:01,402 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %-5p [%t] [%susr] %C{2} (%F:%L) - %m%n", Configuration(/Users/path/totarget/classes/WEB-INF/log4j.properties), null, charset="null") 2013-08-09 16:55:01,403 ERROR Unrecognized format specifier [susr] 2013-08-09 16:55:01,403 ERROR Unrecognized conversion specifier [susr] starting at position 19 in conversion pattern. 2013-08-09 16:55:01,405 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console with params(PatternLayout(%d %-5p [%t] [%susr] %C{2} (%F:%L) - %m%n), null, target="SYSTEM_OUT", name="STDOUT", follow="null", suppressExceptions="null") 2013-08-09 16:55:01,405 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.plugins.AppendersPlugin for element appenders with params(appenders={A1, STDOUT}) 2013-08-09 16:55:01,407 DEBUG Generated plugins in 0.000665000 seconds 2013-08-09 16:55:01,407 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.AppenderRef for element appender-ref with params(ref="A1", level="null", null) 2013-08-09 16:55:01,409 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig for element logger with params(additivity="null", level="debug", name="org.apache.log4j.xml", includeLocation="null", appender-ref={org.apache.logging.log4j.core.config.AppenderRef@f818d7}, properties={}, Configuration(/Users/path/to/target/classes/WEB-INF/log4j.properties), null) 2013-08-09 16:55:01,410 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.AppenderRef for element appender-ref with params(ref="A1", level="null", null) 2013-08-09 16:55:01,411 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger for element root with params(additivity="null", level="debug", includeLocation="null", appender-ref={org.apache.logging.log4j.core.config.AppenderRef@530ababd}, properties={}, Configuration(/Users/path/to/target/classes/WEB-INF/log4j.properties), null) 2013-08-09 16:55:01,412 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.config.plugins.LoggersPlugin for element loggers with params(loggers={org.apache.log4j.xml, root})
推荐答案
Change your configuration line to
<configuration status="debug" packages="path.to.ShiroUserConverterDirectory">
Just to be clear, packages is the directory containing the class, not the class itself.
I got the following to work:
package com.test.util; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.pattern.ConverterKeys; import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; @Plugin(name = "shiro", category = "Converter") @ConverterKeys({"susr", "shiro"}) public class ShiroUserConverter extends LogEventPatternConverter { private static final ShiroUserConverter INSTANCE = new ShiroUserConverter(); private ShiroUserConverter() { this("shiro", "shiro"); // not sure why! } protected ShiroUserConverter(String name, String style) { super(name, style); } public static ShiroUserConverter newInstance(final String[] options) { return INSTANCE; } @Override public void format(LogEvent arg0, StringBuilder arg1) { // TODO Auto-generated method stub arg1.append("No User"); }
}
and my log4j2.xml file was the following:
<?xml version="1.0" encoding="UTF-8"?> <configuration status="debug" packages="com.test.util"> <appenders> <Console name="CA" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p [%t] [%susr] %C{2} (%F:%L) - %m%n"/> </Console> </appenders> <loggers> <root level="debug"> <appender-ref ref="CA"/> </root> </loggers> </configuration>