如何以编程方式配置log4j 2.3
纯private static final Logger logger = LogManager.getLogger();
//
// some method
logger.debug(someString);
(没有任何格式的配置文件)?
基本上我正在寻找这个console appender
的2.x版本。
在我的课程中,我会使用
private static void configureLog4J() {
PatternLayout layout = PatternLayout.createDefaultLayout();
ConsoleAppender appender = ConsoleAppender.createDefaultAppenderForLayout(layout);
LoggerConfig loggerConfig = new LoggerConfig();
loggerConfig.addAppender(appender, DEBUG, null);
}
没有任何配置我(正如预期的那样)面对
ERROR StatusLogger找不到log4j2配置文件。使用默认配置:仅将错误记录到控制台。
虽然配置文件的使用似乎是1.x code,但我找不到一个只有裸机代码的好例子。
我得到的最接近的是properly documented仍然使用虚拟文件。
这是我最好的(尽管完全不成功)拍摄:
{{1}}
我错过了什么吗?
如果它仍然是RTFM案例,请指出我正确的方向。
答案 0 :(得分:17)
package com;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.layout.PatternLayout;
import java.nio.charset.Charset;
public class MyLoggerTest {
public static void main(String[] args){
LoggerContext context= (LoggerContext) LogManager.getContext();
Configuration config= context.getConfiguration();
PatternLayout layout= PatternLayout.createLayout("%m%n", null, null, Charset.defaultCharset(),false,false,null,null);
Appender appender=ConsoleAppender.createAppender(layout, null, null, "CONSOLE_APPENDER", null, null);
appender.start();
AppenderRef ref= AppenderRef.createAppenderRef("CONSOLE_APPENDER",null,null);
AppenderRef[] refs = new AppenderRef[] {ref};
LoggerConfig loggerConfig= LoggerConfig.createLogger("false", Level.INFO,"CONSOLE_LOGGER","com",refs,null,null,null);
loggerConfig.addAppender(appender,null,null);
config.addAppender(appender);
config.addLogger("com", loggerConfig);
context.updateLoggers(config);
Logger logger=LogManager.getContext().getLogger("com");
logger.info("HELLO_WORLD");
}
}
不确定这是否是您要找的。这将创建默认配置并添加控制台记录器。但是,LogManager.getLogger()不起作用并使用LogManager.getContext()。getLogger()不允许记录器层次结构。老实说,我不建议使用程序化方法,Log4j2对它过敏。
答案 1 :(得分:11)
以下是log4j 2.8编程配置的完整示例。 它有3个appender:RollingFile,JDBC和SMTP。
有1个类和2个属性配置文件,一个用于将类注册为log4j2 configurationFactory,另一个用于设置属性,如日志文件目录。
Class#1:MPLoggingConfiguration
package com.websitester.config;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.zip.Deflater;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.core.appender.SmtpAppender;
import org.apache.logging.log4j.core.appender.db.ColumnMapping;
import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
import org.apache.logging.log4j.core.appender.db.jdbc.DataSourceConnectionSource;
import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
import org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.OnStartupTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.Order;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.layout.HtmlLayout;
import org.apache.logging.log4j.core.layout.PatternLayout;
public class MPLoggingConfiguration {
public static final String WEBSITESTER_LOGGER_NAME = "com.websitester";
public static final String FILE_PATTERN_LAYOUT = "%n[%d{yyyy-MM-dd HH:mm:ss}] [%-5p] [%l]%n\t%m%n%n";
public static final String LOG_FILE_NAME = "awmonitor.log";
public static final String LOG_FILE_NAME_PATTERN = "awmonitor-%i.log";
/**
* Just to make JVM visit this class to initialize the static parts.
*/
public static void configure() {
}
@Plugin(category = ConfigurationFactory.CATEGORY, name = "MPConfigurationFactory")
@Order(15)
public static class MPConfigurationFactory extends ConfigurationFactory {
public static final String[] SUFFIXES = new String[] {".json", "*"};
@Override
protected String[] getSupportedTypes() {
return SUFFIXES;
}
@Override
public Configuration getConfiguration(LoggerContext arg0, ConfigurationSource arg1) {
return new Log4j2Configuration(arg1);
}
}
private static class Log4j2Configuration extends DefaultConfiguration {
public Log4j2Configuration(ConfigurationSource source) {
super.doConfigure();
setName("mp-log4j2");
String logFilePath = "/log/weblogic/wl-moniport/";
// LOGGERS
// com.websitester
AppenderRef[] refs = new AppenderRef[] {};
Property[] properties = new Property[] {};
LoggerConfig websitesterLoggerConfig = LoggerConfig.createLogger(true, Level.INFO, WEBSITESTER_LOGGER_NAME, "true", refs, properties, this, null);
addLogger(WEBSITESTER_LOGGER_NAME, websitesterLoggerConfig);
// APPENDERS
final Charset charset = Charset.forName("UTF-8");
// MP ROLLING FILE
TriggeringPolicy mpFileCompositePolicy = CompositeTriggeringPolicy.createPolicy(
SizeBasedTriggeringPolicy.createPolicy("3 M"),
OnStartupTriggeringPolicy.createPolicy(1));
final DefaultRolloverStrategy mpFileRolloverStrategy = DefaultRolloverStrategy.createStrategy("9", "1", "max", Deflater.NO_COMPRESSION + "", null, true, this);
Layout<? extends Serializable> mpFileLayout = PatternLayout.newBuilder()
.withPattern(FILE_PATTERN_LAYOUT)
.withPatternSelector(null)
.withConfiguration(this)
.withRegexReplacement(null)
.withCharset(charset)
.withAlwaysWriteExceptions(isShutdownHookEnabled)
.withNoConsoleNoAnsi(isShutdownHookEnabled)
.withHeader(null)
.withFooter(null)
.build();
Appender mpFileAppender = RollingFileAppender.newBuilder()
.withAdvertise(Boolean.parseBoolean(null))
.withAdvertiseUri(null)
.withAppend(true)
.withBufferedIo(true)
.withBufferSize(8192)
.setConfiguration(this)
.withFileName(logFilePath + LOG_FILE_NAME)
.withFilePattern(logFilePath + LOG_FILE_NAME_PATTERN)
.withFilter(null)
.withIgnoreExceptions(true)
.withImmediateFlush(true)
.withLayout(mpFileLayout)
.withCreateOnDemand(false)
.withLocking(false)
.withName("error_file_web")
.withPolicy(mpFileCompositePolicy)
.withStrategy(mpFileRolloverStrategy)
.build();
mpFileAppender.start();
addAppender(mpFileAppender);
getLogger(WEBSITESTER_LOGGER_NAME).addAppender(mpFileAppender, Level.DEBUG, null);
// JDBC
if (System.getProperty("log4jjdbcjndiName") != null){
ColumnConfig[] columnConfigs = new ColumnConfig[] {
ColumnConfig.newBuilder()
.setConfiguration(this)
.setName("DATED")
.setPattern(null)
.setLiteral(null)
.setEventTimestamp(true)
.setUnicode(false)
.setClob(false)
.build(),
ColumnConfig.newBuilder()
.setConfiguration(this)
.setName("LOGGER")
.setPattern("%logger")
.setLiteral(null)
.setEventTimestamp(false)
.setUnicode(false)
.setClob(false)
.build(),
ColumnConfig.newBuilder()
.setConfiguration(this)
.setName("LOG_LEVEL")
.setPattern("%level")
.setLiteral(null)
.setEventTimestamp(false)
.setUnicode(false)
.setClob(false)
.build(),
ColumnConfig.newBuilder()
.setConfiguration(this)
.setName("MESSAGE")
.setPattern("%message")
.setLiteral(null)
.setEventTimestamp(false)
.setUnicode(false)
.setClob(false)
.build(),
ColumnConfig.newBuilder()
.setConfiguration(this)
.setName("NODE")
.setPattern("" + System.getProperty("log4jmpserverid"))
.setLiteral(null)
.setEventTimestamp(false)
.setUnicode(false)
.setClob(false)
.build()
};
ConnectionSource dataSourceConnectionSource = DataSourceConnectionSource.createConnectionSource(System.getProperty("log4jjdbcjndiName"));
if (dataSourceConnectionSource != null){
Appender jdbcAppender = JdbcAppender.newBuilder()
.setBufferSize(0)
.setColumnConfigs(columnConfigs)
.setColumnMappings(new ColumnMapping[]{})
.setConnectionSource(dataSourceConnectionSource)
.setTableName("MTDTLOGS")
.withName("databaseAppender")
.withIgnoreExceptions(true)
.withFilter(null)
.build();
jdbcAppender.start();
addAppender(jdbcAppender);
getLogger(WEBSITESTER_LOGGER_NAME).addAppender(jdbcAppender, Level.WARN, null);
}
};
// SMTP
if (System.getProperty("log4jemailSubject") != null){
if (System.getProperty("log4jemailLevel").equalsIgnoreCase("error")) {
Layout<? extends Serializable> mpHtmlLayout = HtmlLayout.createLayout(false, "Monitor de Portales", null, null, "x-small", null);
Appender smtpAppender = SmtpAppender.createAppender(
this,
"SMTP",
System.getProperty("log4jemailTo"),
System.getProperty("log4jemailcc"),
System.getProperty("log4jemailbcc"),
System.getProperty("log4jemailFrom"),
System.getProperty("log4jemailreplyTo"),
System.getProperty("log4jemailSubject"),
System.getProperty("log4jemailProtocol"),
System.getProperty("log4jemailHost"),
System.getProperty("log4jemailPort"),
System.getProperty("log4jemailUserName"),
System.getProperty("log4jemailPassword"),
"false",
"50",
mpHtmlLayout,
null,
"true");
smtpAppender.start();
addAppender(smtpAppender);
getLogger(WEBSITESTER_LOGGER_NAME).addAppender(smtpAppender, Level.ERROR, null);
}
}
}
}
}
配置文件:src / main / resources / log4j2.component.properties
log4j.configurationFactory=com.websitester.config.MPLoggingConfiguration$MPConfigurationFactory
log4j.configurationFile=log4j2websitester.json
配置文件:src / main / resources / log4j2websitester.json
{"logFilePath" : "/log/weblogic/wl-moniport/"}
就我而言,我在其他类中设置了所有属性(通过System.getProperty在MPLoggingConfiguration中访问),例如:
System.setProperty("log4jjdbcjndiName", "weblogic-monitor");
当您更改某些属性并想要重新配置log4j2时,您必须进行此调用:
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
ctx.reconfigure();
希望这有帮助
答案 2 :(得分:3)
您可以在log4j中自定义您自己的ConfigurationFactory。 请参考https://logging.apache.org/log4j/2.x/manual/customconfig.html。它似乎可以满足您的需求。
很抱歉。这样可以满足您的需求吗?我只是测试,即使它仍然输出你上面提到的错误信息,它运行良好。
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
Layout<? extends Serializable> layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null,
null,true, true,null,null);
Appender appender = FileAppender.createAppender("/tmp/log4jtest.txt", "false", "false", "File", "true",
"false", "false", "4000", layout, null, "false", null, config);
appender.start();
config.addAppender(appender);
AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
AppenderRef[] refs = new AppenderRef[] {ref};
LoggerConfig loggerConfig = LoggerConfig.createLogger("false", Level.INFO, "org.apache.logging.log4j",
"true", refs, null, config, null );
loggerConfig.addAppender(appender, null, null);
config.addLogger("simpleTestLogger", loggerConfig);
ctx.updateLoggers();
Logger l = ctx.getLogger("simpleTestLogger");
l.info("message of info level shoud be output properly");
l.error("error message");
答案 3 :(得分:3)
如果你想要它用于控制台appender,有一个非常简单的方法,如果你使用maven,只需将这两个依赖项放在你的pom.xml中,所有的东西都将打印在你的控制台上。什么都不需要......根本没有log4j.properties文件。 slf4j扩展了log4j并具有许多丰富的功能。
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
答案 4 :(得分:0)
documentation建议使用Builder API进行程序化配置。使用此api,您的configureLog4J()
方法可能看起来像这样:
public static void configureLog4J() {
ConfigurationBuilder<BuiltConfiguration> builder =
ConfigurationBuilderFactory.newConfigurationBuilder();
// configure a console appender
builder.add(
builder.newAppender("stdout", "Console")
.add(
builder.newLayout(PatternLayout.class.getSimpleName())
.addAttribute(
"pattern",
"%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
)
)
);
// configure the root logger
builder.add(
builder.newRootLogger(Level.INFO)
.add(builder.newAppenderRef("stdout"))
);
// apply the configuration
Configurator.initialize(builder.build());
}
现在,诀窍是-而且afaik手册没有足够清楚地说明-
此静态初始化方法称为先于
LogManager.getLogger()
。
对于一个最小的工作示例,您可以使用像这样的静态初始化块
private static final Logger log;
static {
configureLog4J();
log = LogManager.getLogger(MyAwesomeClass.class);
}
也就是说,以编程方式配置日志对任何人都不是一个好主意 非同寻常的项目:您每次都必须重新编译,测试和交付代码 您想暂时增加某些记录器的日志级别以进行诊断 生产问题。因此,强烈建议您不要使用它。