Skip to content

Instantly share code, notes, and snippets.

@zaneli
Created January 3, 2012 07:17
Show Gist options
  • Save zaneli/1553906 to your computer and use it in GitHub Desktop.
Save zaneli/1553906 to your computer and use it in GitHub Desktop.
「log4j でエンコード指定できる SyslogAppendar を作る(おまけ)」ブログ用
import java.io.FilterWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.helpers.SyslogQuietWriter;
import org.apache.log4j.helpers.SyslogWriter;
import org.apache.log4j.net.SyslogAppender;
public class SyslogAppendarTest {
public void execute(String syslogHost, int syslogFacility)
throws NoSuchFieldException, IllegalAccessException {
Layout layout = new PatternLayout("%d|%p|%m");
SyslogAppender appender = new SyslogAppender(layout, syslogHost, syslogFacility);
// Writer を入れ替える
setEncodeSpecifiableWriter(appender, "UTF-8");
Logger logger = Logger.getLogger(SyslogAppendarTest.class);
logger.addAppender(appender);
logger.setLevel(Level.WARN);
logger.warn("警告ですよ!!");
}
private static void setEncodeSpecifiableWriter(
SyslogAppender appender, String encode) throws NoSuchFieldException, IllegalAccessException {
// SyslogAppender が持っている SyslogQuietWriter を取得
Field sqwField = SyslogAppender.class.getDeclaredField("sqw");
sqwField.setAccessible(true);
SyslogQuietWriter writer = (SyslogQuietWriter) sqwField.get(appender);
// SyslogQuietWriter が持っている SyslogWriter を EncodeSpecifiableSyslogWriter に入れ替える
Field outField = FilterWriter.class.getDeclaredField("out");
outField.setAccessible(true);
outField.set(writer, new EncodeSpecifiableSyslogWriter(appender.getSyslogHost(), encode));
}
// SyslogWriter を継承した Writer を実装する。
private static class EncodeSpecifiableSyslogWriter extends SyslogWriter {
private final String encode;
public EncodeSpecifiableSyslogWriter(String syslogHost, String encode) {
super(syslogHost);
this.encode = encode;
}
// write をオーバーライドする。string.getBytes(encode) 以外は親クラスと同じ。
@Override
public void write(String string) throws IOException {
if (getDs() != null && getAddress() != null) {
byte[] bytes = string.getBytes(encode);
int bytesLength = bytes.length;
if (bytesLength >= 1024)
bytesLength = 1024;
DatagramPacket packet = new DatagramPacket(
bytes, bytesLength, getAddress(), getPort());
getDs().send(packet);
}
}
private DatagramSocket getDs() {
try {
Field field = SyslogWriter.class.getDeclaredField("ds");
field.setAccessible(true);
return (DatagramSocket) field.get(this);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private InetAddress getAddress() {
try {
Field field = SyslogWriter.class.getDeclaredField("address");
field.setAccessible(true);
return (InetAddress) field.get(this);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private int getPort() {
try {
Field field = SyslogWriter.class.getDeclaredField("port");
field.setAccessible(true);
return ((Integer) field.get(this)).intValue();
} catch (Exception e) {
e.printStackTrace();
return 514;
}
}
}
public static void main(String[] args)
throws NoSuchFieldException, IllegalAccessException {
new SyslogAppendarTest().execute(
"xxx.xxx.xxx.xxx", SyslogAppender.getFacility("LOCAL0"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment