问题描述
我有一个将日志发送到日志服务器存储的记录器.此工作正常,但是 tatterlayout 尚未使用.有或没有任何情况都不会改变任何东西.我相信记得在某个地方阅读 socketAppender 使用是自己的模式,而不是其他模式.
<appender name="LOGSTASH" class="org.apache.log4j.net.SocketAppender"> <param name="Port" value="5000"/> <param name="RemoteHost" value="192.168.81.131"/> <param name="ReconnectionDelay" value="5000"/> <param name="LocationInfo" value="true" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n" /> </layout> </appender>
但在此 documentation (以及其他一些)用这个.此文档的示例:
<appender name="A1" class="org.apache.log4j.net.SocketAppender"> <param name="RemoteHost" value="localhost"/> <param name="Port" value="5000"/> <param name="LocationInfo" value="true"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/> </layout> </appender>
所以不可能使用 socketAppender 使用人体模式还是我的错?
如果不可能使用自定义模式的TCP记录?
推荐答案
看来 socketAppender 不要使用布局.
请参阅此处的文档 /p>
所以我使用 syslogappender 替换.由于未使用的可能性(例如设施和优先级),但效果很好.
其他推荐答案
作为解决方法,
- for log4j 1.x
- 复制套接字代码到您的本地项目
-
更改,"需要"方法
public boolean requiresLayout() { return true; }
-
更改附录方法为;
public void append(LoggingEvent event) { ///...... event.getThrowableStrRep(); if (this.layout == null) { errorHandler.error("No layout for appender " + name, null, ErrorCode.MISSING_LAYOUT); return; } String message = this.layout.format(event); oos.writeObject(message); ///...... }
-
将此类设置为您的appender.
- 现在,您可以为此Appender设置任何布局.
希望它有帮助.
其他推荐答案
@myuce发布的解决方法正在工作,但是您还需要在" standard" utputStream (OS)中替换 ObjectOutputStream (OOS).
您可以在OOS内部检查 - 它正在准备"接收器"的其他内容.
??t?{"@timestamp":"2018-03-27T14...
所以...我刚刚替换(在我的情况下是Scala):
oos = new ObjectOutputStream(new Socket(address, port).getOutputStream());和 oos = new ObjectOutputStream(socket.getOutputStream());
内部: stream = new Socket(address, port).getOutputStream和stream = socket.getOutputStream(以及可变名称[当然每次出现;]为了清楚起见).
问题描述
I have a logger that send log to a log server storage. This work fine but the patternlayout isn't used. With or without that doesn't change anything. I believe remember to read somewhere that socketappender use is own pattern and not others.
<appender name="LOGSTASH" class="org.apache.log4j.net.SocketAppender"> <param name="Port" value="5000"/> <param name="RemoteHost" value="192.168.81.131"/> <param name="ReconnectionDelay" value="5000"/> <param name="LocationInfo" value="true" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n" /> </layout> </appender>
But on this documentation (and a few other) thay use this. Example from this doc :
<appender name="A1" class="org.apache.log4j.net.SocketAppender"> <param name="RemoteHost" value="localhost"/> <param name="Port" value="5000"/> <param name="LocationInfo" value="true"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/> </layout> </appender>
So is it impossible to use personnal pattern with socketappender or is it my fault?
If it's impossible is there an alternative appender for tcp logging with custom pattern?
推荐答案
It seems that SocketAppender don't use a layout.
SocketAppenders do not use a layout. They ship a serialized LoggingEvent object to the server side.
So I use a SyslogAppender to replace. It's not perfect because of unused possibilies (like facility and priority) but works fine.
其他推荐答案
As a workaround,
- For Log4j 1.x
- Copy SocketAppender code to your local project
Change, "requiresLayout" method as
public boolean requiresLayout() { return true; }
Change append method as ;
public void append(LoggingEvent event) { ///...... event.getThrowableStrRep(); if (this.layout == null) { errorHandler.error("No layout for appender " + name, null, ErrorCode.MISSING_LAYOUT); return; } String message = this.layout.format(event); oos.writeObject(message); ///...... }
Set this class as your appender.
- Now on, you can set any layout to this appender.
Hope it helps.
其他推荐答案
Workaround that @myuce posted is working, but you also need to replace ObjectOutputStream (OOS) within "standard" OutputStream (OS).
You can check inside OOS - it's prepending output with some additional stuff for "the receiver".
??t?{"@timestamp":"2018-03-27T14...
So... I've just replaced (it's scala in my case):
oos = new ObjectOutputStream(new Socket(address, port).getOutputStream()); and oos = new ObjectOutputStream(socket.getOutputStream());
within: stream = new Socket(address, port).getOutputStream and stream = socket.getOutputStream (and variable name [of course every occurrence;] for clarity).