我一直在尝试使用ConfigurationFactory和配置文件将log4j2日志记录发送到rsyslog服务器。 Niether方式导致输出与记录到文件相比较。
在所有情况下,我都使用log.error("test", new Throwable().fillInStackTrace());
我尝试过两种不同的方式:
使用AppenderComponentBuilder
@Plugin(name =" CustomConfigurationFactory",category = ConfigurationFactory.CATEGORY) @Order(50)
公共类Log4jConfigurationFactory扩展了ConfigurationFactory {
static Configuration createConfiguration(final String name,ConfigurationBuilder builder){
builder.setConfigurationName(name);
builder.setStatusLevel(Level.INFO);
AppenderComponentBuilder fileAppenderBuilder = builder.newAppender("logFile", FileAppender.PLUGIN_NAME)
.addAttribute("fileName", "Audit.log");
fileAppenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", "%d [%t] %-5level: %msg%n"));
KeyValuePair exc = new KeyValuePair("exception", "%ex");
AppenderComponentBuilder syslogAppenderBuilder = builder.newAppender("syslog","Syslog")
.addAttribute("host", "example.com")
.addAttribute("port", 512)
.addAttribute("protocol", "TCP")
.addAttribute( "immediateFlush", true )
.addAttribute( "newLine", true )
.addAttribute("reconnectionDelayMillis", 10000)
.addAttribute( "facility", "LOCAL5" )
.addAttribute("format", "RFC5424")
.addAttribute("appName","audit")
.addAttribute("includeMDC",true)
.addAttribute("enterpriseNumber", 18060)
.addAttribute("id", "Audit")
.addAttribute("mdcId", "mdc")
.addAttribute("messageId","log");
syslogAppenderBuilder.add(builder.newLayout("RFC5424Layout")
.addAttribute("exceptionPattern", "%rThrowable{full}"));
// .addAttribute("LoggerFields", exc)); .. LoggerFields doesn't exist as an attribute so enabling full stack traces is impossible with the bare builder. See second attempt.
builder.add(syslogAppenderBuilder);
builder.add(fileAppenderBuilder);
builder.add(builder.newRootLogger(Level.INFO).
add(builder.newAppenderRef("logFile")));
add(builder.newAppenderRef("syslog")));
Configuration config = builder.build();
return config;
}
@Override
public Configuration getConfiguration(final LoggerContext loggerContext, final ConfigurationSource source) {
return getConfiguration(loggerContext, source.toString(), null);
}
@Override
public Configuration getConfiguration(final LoggerContext loggerContext, final String name, final URI configLocation) {
ConfigurationBuilder<BuiltConfiguration> builder = newConfigurationBuilder();
return createConfiguration(name, builder);
}
@Override
protected String[] getSupportedTypes() {
return new String[] {"*"};
}
}
(第一种方法无法添加LoggerFields
属性,因此它注定要失败。)它显示"ERROR test"
使用SyslogAppender.Builder
KeyValuePair[] exc = new KeyValuePair[4];
exc[0] = new KeyValuePair("exception", "%ex");
exc[1] = new KeyValuePair("thread", "%t");
exc[2] = new KeyValuePair("priority", "%p");
exc[3] = new KeyValuePair("category", "%c");
LoggerFields[] lf = new LoggerFields[1];
lf[0] = LoggerFields.createLoggerFields(exc, null, "18060", false);
SyslogAppender.Builder syslogAppenderBuilder1 = SyslogAppender.newSyslogAppenderBuilder();
syslogAppenderBuilder1.withName("syslog");
syslogAppenderBuilder1.withHost("example.com");
syslogAppenderBuilder1.withPort(512);
syslogAppenderBuilder1.withProtocol(Protocol.TCP);
syslogAppenderBuilder1.withImmediateFlush(true);
syslogAppenderBuilder1.setNewLine(true);
syslogAppenderBuilder1.setFacility(Facility.USER);
syslogAppenderBuilder1.setFormat("RFC5424");
syslogAppenderBuilder1.setAppName("Audit");
syslogAppenderBuilder1.setIncludeMdc(true);
syslogAppenderBuilder1.setEnterpriseNumber(18060);
syslogAppenderBuilder1.setId("audit");
syslogAppenderBuilder1.setMdcId("mdc");
syslogAppenderBuilder1.setMsgId("log");
syslogAppenderBuilder1.setExceptionPattern("%ex");
syslogAppenderBuilder1.setLoggerFields(lf);
builder.add(fileAppenderBuilder);
builder.add(builder.newRootLogger(Level.INFO).
add(builder.newAppenderRef("LogFile")));
Configuration config = builder.build();
config.getRootLogger().addAppender(syslogAppenderBuilder1.build(), Level.INFO, null);
return config;
这样只会显示"e"
或"n"
<Configuration>
<Appenders>
<Syslog name="syslog" format="RFC5424" host="example.com" port="512" protocol="UDP" appName="Audit" newLine="true" immediateFlush="true" includeMDC="true" mdcId="mdc" facility="LOCAL5" enterpriseNumber="18060" messageId="log" id="audit" charset="UTF-8">
<LoggerFields>
<KeyValuePair key="thread" value="%t" />
<KeyValuePair key="priority" value="%p" />
<KeyValuePair key="category" value="%c" />
<KeyValuePair key="exception" value="%rThrowable{full}" />
</LoggerFields>
<ExceptionPattern>%rThrowable{full}</ExceptionPattern>
</Syslog>
<RollingRandomAccessFile name="file" fileName="logs/Audit.log" filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}-%i.log">
<Policies>
<TimeBasedTriggeringPolicy interval="1" />
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="syslog" />
<AppenderRef ref="file" />
</Root>
</Loggers>
</Configuration>
&#13;
这导致以下日志输出: 测试#012java.lang.Throwable#012#011at main(main.java:5)[main.jar:?]#012
我认为#012是新行,并且没有像它应该那样处理。
似乎没有一种将日志发送到rsyslog的完美方式。任何解决方案?