差異處
這裏顯示兩個版本的差異處。
java:log4j:extend_appender [2017/01/22 15:53] tony [How to?] |
java:log4j:extend_appender [2023/06/25 09:48] |
||
---|---|---|---|
行 1: | 行 1: | ||
- | {{tag>java log4j}} | ||
- | ====== Extend the appender (Working) ====== | ||
- | ===== Problem ===== | ||
- | 我替老婆做了某個遊戲外掛,然後我希望能把log內容顯示在畫面上,例如:\\ | ||
- | {{:java:log4j:log4j_extend_appender_result.png|}}\\ | ||
- | 我想透過log4j去通知畫面更新而不是再另開一個api;本篇文章主要告訴大家extend log4j appender的方法去達到這個目的。 | ||
- | ===== How to? ===== | ||
- | 原先我的Subject是目前工作的狀態,負責通知的是工作的controller;而Observer則是UI,實作以下介面,Subject有變動會通知它: | ||
- | <code java> | ||
- | public interface IStateChangedListener { | ||
- | void update(Object[] messages); | ||
- | } | ||
- | |||
- | public class MessageTable extends JTable implements IStateChangedListener { | ||
- | // skip | ||
- | } | ||
- | </code> | ||
- | 修改後,Subject為extend的appender,要做這些事情: | ||
- | - Extend AppenderSkeleton。 | ||
- | - 負責Observer的註冊與通知。 | ||
- | <code java> | ||
- | public class NotificationAppender extends AppenderSkeleton { | ||
- | |||
- | protected static List<IStateChangedListener> mStateChangedListenerList = new ArrayList<>(); | ||
- | |||
- | private static NotificationAppender mInstance = new NotificationAppender(); | ||
- | |||
- | public static NotificationAppender getInstance(){ | ||
- | return mInstance; | ||
- | } | ||
- | |||
- | @Override | ||
- | protected void append(LoggingEvent arg0) { | ||
- | notify(arg0.getLevel().toString(), arg0.getMessage().toString()); | ||
- | } | ||
- | |||
- | public void addListener(IStateChangedListener aListener){ | ||
- | mStateChangedListenerList.add(aListener); | ||
- | } | ||
- | |||
- | private static String getTimeString(Date aDate){ | ||
- | DateFormat df = new SimpleDateFormat("HH:mm:ss"); | ||
- | return df.format(aDate); | ||
- | } | ||
- | |||
- | protected void notify(String aState, String aMessage){ | ||
- | Date now = new Date(); | ||
- | for( IStateChangedListener listener : mStateChangedListenerList){ | ||
- | listener.update(new Object[]{ | ||
- | getTimeString(now), aState, aMessage | ||
- | }); | ||
- | } | ||
- | } | ||
- | |||
- | @Override | ||
- | public void close() { | ||
- | |||
- | } | ||
- | |||
- | @Override | ||
- | public boolean requiresLayout() { | ||
- | return false; | ||
- | } | ||
- | } | ||
- | </code> | ||
- | 在config的部分如下,我針對某兩個類別將訊息送至MessageTable UI: | ||
- | <code java> | ||
- | log4j.additivity.org.tonylin.bot.fantasycity.RunBotJob=false | ||
- | log4j.logger.org.tonylin.bot.fantasycity.RunBotJob=DEBUG, CONSOLE, LOGFILE, MESSAGETABBLE | ||
- | |||
- | log4j.additivity.org.tonylin.bot.fantasycity.BotUtils=false | ||
- | log4j.logger.org.tonylin.bot.fantasycity.BotUtils=DEBUG, CONSOLE, LOGFILE, MESSAGETABBLE | ||
- | |||
- | # MessageTable Logger | ||
- | log4j.appender.MESSAGETABBLE=org.tonylin.bot.common.NotificationAppender | ||
- | log4j.appender.CONSOLE.Threshold=DEBUG | ||
- | </code> | ||
- | ===== Reference ===== | ||
- | * [[https://gist.github.com/kengelke/4664612|GitHub - CachingSingletonAppender]] | ||
- | |||
- | |||
- | |||