Log4j supports syslog, but there are many deficiencies, so it needs to be modified.
1. When log4j supports syslog, the default size of the same MSG is 1024, which is also the rfc00004 standard of syslog. However, for more than 1024 MSG in actual applications, we still
In the hope that the log can be completed completely, log4j will unpack MSG greater than 1024.
This split will cause trouble.
Because of priority, the syslog standard attributes such as tag are included in MSG itself, and when it is not a special field, it can only be split in the first one when unpacking, the subsequent MSG will lose these key attributes. For example:
Apr 28 10:22:59 myhost MyApp: <info> msgdetailxxxxxxxxxxxxxxxxxxxxxxxx.
The actual MSG is "MyApp: <info> msgdetailxxxxxxxxxxxxxxxxxxxxxxxxxx". to split it into two records:
Apr 28 10:22:59 myhost MyApp: <info> msgdetailxxxxx
Apr 28 10:22:59 myhost xxxxxxxxxxxxxx
The second record will lose the tag and priority, and the document category will not know which file the message is placed in. Therefore, we can either manually split the message and send messages smaller than 1024 after the split to log4j. In this way, the message will be processed as multiple messages and the key attributes will not be removed.
This path still does not work, because after the MSG is split, the UDP transmission cannot ensure the order and integrity of the message, and the message is not completely sent to syslog in the order you split it. Therefore, the message cannot be restored. It is hard to ensure that the sequence ID is added.
2. I try my best to find a solution that supports more than 1024 message lengths. At the beginning, my test environment was syslogd (sysklogd) under log4j and ubuntu ). I modified the log4j source code and removed the 1024 limit from the UDP layer. However, after a message is sent to Syslogd, It is intercepted by the server. That is, syslogd cut the message according to rfc00004 standard. However, UDP can send messages larger than 1024.
3. Later, syslog-ng was used, and related parameters were modified. In this case, a 64 K message could be sent, which is already a limit for UDP packets. Of course, if a log exceeds 64 KB, it is not called a log.
Now the appender of log4j is modified. This is mainly to re-Implement UDP sending in syslogappender.
If we re-distribute them to our own package, we need to modify three classes to implement syslogwriter and then syslogappender so that he can call our own syslogquitewriter, then, the modified syslogwriter is called in syslogquitewriter.
If you want to add some control, such as adding a character set, because syslogwriter does not have character set parameters by default getbytes, using the system default character set may not be ours
If you want to add a configuration item, you must first add the setter method to syslogappender. When initializing loggerfactory, read a configuration item and
Reflection calls the Set Method of appender. For example, you have configured log4j. appender. syslog. axman = 12345
During initialization, The setaxman method of syslogappender will be called to inject the configuration item into it rather than put it in a data structure.
After the modification, you only need to direct log4j. appender. syslog To Our syslogappender:
Log4j. appender. syslog = com. axman. syslogappender, and COM. axman. syslogappender can work correctly in classpath. Otherwise, if you configure conversionpattern to MyApp: <% P> other options... % m % N
You can split logs into different files by MyApp and priority, especially by $ level. Fatal (corresponding to Emerg syslog) can be used) logs are sent to the monitoring system first, and info logs can be sent to other services for processing, which is very convenient.