Java log4j syslogappender堆栈跟踪输出不在同一行上

Java log4j syslogappender堆栈跟踪输出不在同一行上,java,tomcat,solr,log4j,rsyslog,Java,Tomcat,Solr,Log4j,Rsyslog,我正在尝试使用log4j和rsyslog进行集中日志记录 到目前为止我拥有的 Solr在RHEL6上的tomcat6内部运行,使用以下log4j和sl4j库 # lsof -u tomcat | grep log4j java 14503 tomcat mem REG 253,0 9711 10208 /usr/share/java/tomcat6/slf4j-log4j12-1.6.6.jar java 14503 tomcat

我正在尝试使用log4j和rsyslog进行集中日志记录

到目前为止我拥有的

Solr在RHEL6上的tomcat6内部运行,使用以下log4j和sl4j库

# lsof -u tomcat | grep log4j
java    14503 tomcat  mem    REG              253,0      9711    10208 /usr/share/java/tomcat6/slf4j-log4j12-1.6.6.jar
java    14503 tomcat  mem    REG              253,0    481535    10209 /usr/share/java/tomcat6/log4j-1.2.16.jar
java    14503 tomcat  mem    REG              253,0    378088  1065276 /usr/share/java/log4j-1.2.14.jar
java    14503 tomcat   20r   REG              253,0    378088  1065276 /usr/share/java/log4j-1.2.14.jar
java    14503 tomcat   21r   REG              253,0    481535    10209 /usr/share/java/tomcat6/log4j-1.2.16.jar
java    14503 tomcat   35r   REG              253,0      9711    10208 /usr/share/java/tomcat6/slf4j-log4j12-1.6.6.jar
# 
Solr正在使用以下log4j.properties文件(通过-Dlog4j.configuration=file:///opt/solr/lib/log4j.properties)

在同一台服务器上,我让rsyslog运行并接受来自log4j的日志消息

# rpmquery -a | grep syslog
rsyslog-5.8.10-7.el6_4.x86_64
# 
rsyslog配置

# #### MODULES ####
$MaxMessageSize 32k
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imklog   # provides kernel logging support (previously done by rklogd)
$ModLoad imfile   # provides file monitoring support
#
$ModLoad imudp.so
$UDPServerRun 514
$WorkDirectory /var/lib/rsyslog # where to place spool files
# #### GLOBAL DIRECTIVES ####
# # Use default timestamp format
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
$IncludeConfig /etc/rsyslog.d/*.conf
$ActionQueueType LinkedList   # run asynchronously
$ActionQueueFileName fwdRule1 # unique name prefix for spool files
$ActionQueueMaxDiskSpace 1g   # 1gb space limit (use as much as possible)
$ActionQueueSaveOnShutdown on # save messages to disk on shutdown
$ActionResumeRetryCount -1    # infinite retries if host is down

$ActionSendStreamDriverMode 0 # require TLS for the connection
$ActionSendStreamDriverAuthMode anon # chain and server are verified
#local1.*;*.* @@(o)XXXXXXXX:5544
local1.*                                                /var/log/remote.log
# # The authpriv file has restricted access.
authpriv.*                                              /var/log/secure
# # Log all the mail messages in one place.
mail.*                                                  -/var/log/maillog
# # Log cron stuff
cron.*                                                  /var/log/cron
# # Everybody gets emergency messages
*.emerg                                                 *
# # Save news errors of level crit and higher in a special file.
uucp,news.crit                                          /var/log/spooler
# # Save boot messages also to boot.log
local7.*                                                /var/log/boot.log
我正在从Solr的logj4捕获local1消息,并将它们重定向到/var/log/remote.log 一切正常。示例信息消息

Oct 31 13:57:08 hostname.here 3431839 [http-8080-10] java INFO  org.apache.solr.core.SolrCore  [collection1] webapp=/solr path=/select params={indent=true&q=*:*&wt=json&rows=1} hits=42917 status=0 QTime=1
和堆栈跟踪与错误消息位于同一行

Oct 31 12:27:17 hostname.here 157666248 [http-8080-7] java ERROR org.apache.solr.core.SolrCore  org.apache.solr.common.SolrException: undefined field *#012#011at org.apache.solr.schema.IndexSchema.getDynamicFieldType(IndexSchema.java:1223)#012... Cut for brevity....#011at java.lang.Thread.run(Thread.java:724)#012
注意#012作为行结束和#011选项卡

使用此设置,我可以通过TCP将日志发送到远程rsyslog服务器,并通过管道将日志发送到fluentd/elaticsearch/kibana等。。。一切正常

问题 我现在正试图让另一个webapp在同一个tomcat容器中运行,以如上所述的方式进行日志记录,除了堆栈跟踪之外,所有工作都按预期进行,堆栈跟踪的每一行都以单独的行结束(单独的syslog消息)

webapp附带了自己的log4j libs和log4j.xml配置。LIB与solr使用的版本相同

此应用程序的log4j.xml文件

 <appender name="SYSLOG" class="org.apache.log4j.net.SyslogAppender">
                <param name="SyslogHost" value="localhost" />
                <param name="Facility" value="LOCAL1" />
                <param name="Header" value="false" />
                <property name="facilityPrinting" value="false"/>
                <param name="Threshold" value="DEBUG" />
                <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern"
                      value="%-4r [%t] java %-5p %c %x %m%n"/>
                </layout>
                </appender>

我希望看到来自新应用程序的堆栈跟踪像Solr一样出现在同一行上

有人知道这是否是log4j配置问题吗


非常感谢

我最近也在做类似的事情(事实上,我现在打开了一个你可以帮助的窗口)

这可能不是一个很好的答案,但它包含的信息比我在评论中所能容纳的要多,所以请看这里(我希望其中一些对您来说是新的)。rsyslog rsyslog文档包含以下部分:

读取模式[模式]

当具有多行消息时,应定义此模式。该值的范围为0-2,并确定多行检测方法。
0(默认)-基于行(每行都是新消息)
1-段落(日志消息之间有一个空行)
2-缩进(新日志消息从一行的开头开始。如果一行以空格开头,则它是其前面日志消息的一部分)

rsyslog文档没有此类配置选项。我猜UDP输入模块不支持多行日志记录。因此,堆栈跟踪的每一行都作为单独的日志条目发送出去


您在/etc/rsyslog.d中有任何配置文件吗?那里可能有更多信息。

谢谢。我放弃了让rsyslog正常工作的尝试,并选择了它。我们正在发布运行在Tomcat内部的Java应用程序日志,到目前为止,它运行良好,只出现了一些小故障。它比rsyslog灵活得多。如果你感兴趣,我可以分享我们的配置。我还没听说过fluentd。那很聪明。那么,您让堆栈跟踪一个集合,然后在一行json上序列化它?您对fluentd日志条目使用弹性搜索的体验如何?是的,我想了解一下你确定的配置。谢谢Andrey。我定制了log4j布局,包括应用程序名和主机名(从Tomcat statup上的java系统属性集中用-D获取)。然后fluentd插件读取日志文件,并将其发送到另一个fluentd服务器,该服务器使用插件进行侦听。然后,此服务器将条目存储在Elastic中。然后,我们将从Elastic读取。StackTrace由regexp捕获(请参阅中的“格式”)。
Oct 31 12:54:47  hostname.here 4909 [main] java ERROR org.hibernate.tool.hbm2ddl.SchemaUpdate  could not get database metadata
Oct 31 12:54:47 hostname.here org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Communications link failure
Oct 31 12:54:47 hostname.here 
Oct 31 12:54:47 hostname.here The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.)
 <appender name="SYSLOG" class="org.apache.log4j.net.SyslogAppender">
                <param name="SyslogHost" value="localhost" />
                <param name="Facility" value="LOCAL1" />
                <param name="Header" value="false" />
                <property name="facilityPrinting" value="false"/>
                <param name="Threshold" value="DEBUG" />
                <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern"
                      value="%-4r [%t] java %-5p %c %x %m%n"/>
                </layout>
                </appender>