首先介绍一下我尝试做的事情。我的雇主正在从使用C#的Windows服务器迁移到Linux上的Java以迁移到AWS。尝试创建Log Appender以将日志推送到AWS CloudWatch时出现了这个特殊问题。我还是Java的新手,所以请耐心等待:)我使用IntelliJ-IDEA 15.0.2 Windows进行编程
我找到了Mihailo Despotovic创建的现有Log Appender。 Github Link
我做了一些修改,使其更易于配置使用凭证配置文件,日志组/流等。
现在我遇到的问题,希望有人可以指导我找到可能的解决方案。
尝试#1
我是在AWS实例上做到的。我的Chef食谱在Jar文件所在的文件夹中创建了log4j2.xml文件。使用Stack中的Custom JSON分配配置。调用Jar文件时,-Dlog4j.configurationfile指向路径/ log4j2.xml。一旦调用getLogger(),就会出现大量 ERROR StatusLogger无法识别的格式说明符[XXXX] ,其中XXXX是不同的布局选项。然后它说它找不到log4j2配置文件并且会使用默认值,然后跟着完全相同的 ERROR StatusLogger无法识别的流...
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="com.something.something">
<Appenders>
<CloudWatchLogAppender name="CloudWatchLogAppender"
awsLogGroupName="log group name"
awsLogStreamName="log stream name"
awsCredentialProfile="credential profile name"
queueDepth="50000"
drainLimit="256"
flushPeriod="5"
>
<PatternLayout pattern="%msg" />
</CloudWatchLogAppender>
</Appenders>
<Loggers>
<Root level="all">
<AppenderRef ref="CloudWatchLogAppender" />
</Root>
</Loggers>
</Configuration>
尝试#2
这一次,我想从IDEA中将log4j2.xml包含在Jar中,而不必担心动态配置设置。 XML文件放在src / main / resources
中调用getLogger()时,会创建以下输出:
ERROR Unable to invoke factory method in class class com.something.something.CloudWatchLogAppender for element CloudWatchLogAppender.
ERROR Null object returned for CloudWatchLogAppender in Appenders.
ERROR Unable to locate appender "CloudWatchLogAppender" for logger config "root"
尝试#3
接下来,我想尝试以Java编程方式设置配置。 log4j文档对我来说有点混乱,但我偶然发现了这个问题:https://issues.apache.org/jira/browse/LOG4J2-743
并更改为使用我的自定义日志附加程序:
org.apache.logging.log4j.core.Logger rootLogger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger();
PatternLayout layout = PatternLayout.createLayout("%msg", null, null, null, null, false, true, null, null);
CloudWatchLogAppender appender = new CloudWatchLogAppender("CloudWatchLogAppender",
logGroupName,
logStreamName,
null,
queueDepth,
drainLimit,
flushPeriod,
layout);
appender.start();
rootLogger.getContext().getConfiguration().addLoggerAppender(rootLogger, appender);
rootLogger.setLevel(Level.ALL);
Logger logger = LogManager.getLogger(com.something.something.App.class);
我必须包含以下内容,将默认的Level.ERROR更改为其他内容(将通过配置处理&#34;级别&#34;)
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.setLevel(Level.ALL);
ctx.updateLoggers();
从IDEA运行时,这就像一个魅力。记录的任何内容都会按预期发送到AWS CloudWatch。
然后我将它构建成一个Jar(maven项目,也在gradle中试过),运行它并且发生了同样的 ERROR StatusLogger无法识别的格式说明符[XXXX] 。
Log Appender仍然记录到AWS CloudWatch,但它只是发送%msg 的模式布局
而不是实际的日志消息。然后我使用远程调试来查看是否可以深入查看log4j2并找到从IDEA和Jar运行它之间的区别。这就是我发现从IDEA运行时,它引用maven存储库log4j2-core 2.5 Jar来获取 Log4j2Plugins.dat 并找到默认的插件类别,名为 converter 。但是当从Jar运行时,它使用maven包含的META-INF / org / apache / logging / log4j / core / config / plugins / Log4j2Plugins.dat进入Jar,它只有&#34; root&#34 ;类别和对我的自定义日志附加程序的引用。这意味着log4j2无法找到转换器的预期默认类别,这会产生大量布局错误。
我甚至尝试从存储库核心Jar文件中提取 Log4j2Plugins.dat 文件,并在同一路径下包含在项目中。构建Jar时会被忽略。
我如何能够解决该问题并让maven包含正确的 Log4j2Plugins.dat 文件?或任何其他可能的解决方案?
EDITED
适用于Try#3的Hack:
我从log4j2核心jar存储库文件中提取了Log4j2Plugins.dat,并将其包含在我的Chef Cookbook中。让配方将文件复制到正确的文件夹结构中,然后使用&#34; jar -uf&#34;通过食谱更新我的jar文件。