差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

Both sides previous revision 前次修改
下次修改
前次修改
java:log4j:extend_appender [2017/01/22 12:22]
tony [How to?]
java:log4j:extend_appender [2023/06/25 09:48] (目前版本)
行 1: 行 1:
 {{tag>​java log4j}} {{tag>​java log4j}}
-====== Extend the appender ​(Working) ​======+====== Extend the appender ======
 ===== Problem ===== ===== Problem =====
 我替老婆做了某個遊戲外掛,然後我希望能把log內容顯示在畫面上,例如:​\\ 我替老婆做了某個遊戲外掛,然後我希望能把log內容顯示在畫面上,例如:​\\
行 6: 行 6:
 我想透過log4j去通知畫面更新而不是再另開一個api;本篇文章主要告訴大家extend log4j appender的方法去達到這個目的。 我想透過log4j去通知畫面更新而不是再另開一個api;本篇文章主要告訴大家extend log4j appender的方法去達到這個目的。
 ===== How to? ===== ===== How to? =====
-原先我的Subject是目前工作的狀態,而Observer則是UI。而UI實作以下介面,Subject有變動會通知它:​+原先我的Subject是目前工作的狀態,負責通知的是執行工作的controller;而Observer則是UI實作以下介面,Subject有變動會通知它:​
 <code java> <code java>
 public interface IStateChangedListener { public interface IStateChangedListener {
行 13: 行 13:
  
 public class MessageTable extends JTable implements IStateChangedListener { public class MessageTable extends JTable implements IStateChangedListener {
- // + // skip
 } }
 </​code>​ </​code>​
-===== Reference ===== +接著新增一個名為NotificationAppender的Log4j Appender,要做以下事情:​ 
-  ​* [[https://​gist.github.com/​kengelke/​4664612|GitHub ​CachingSingletonAppender]]+  - Extend AppenderSkeleton。 
 +  - 負責Observer的註冊與通知。 
 +<code java> 
 +public class NotificationAppender extends AppenderSkeleton {
  
 + protected static List<​IStateChangedListener>​ mStateChangedListenerList = new ArrayList<>​();​
  
 + @Override
 + protected void append(LoggingEvent arg0) {
 + notify(arg0.getLevel().toString(),​ arg0.getMessage().toString());​
 + }
 +
 + public static 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 static 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.MESSAGETABBLE.Threshold=DEBUG
 +</​code>​
 +===== Additional Properties =====
 +extend的appender如果需要特別的設定,例如:​
 +<code java>
 +log4j.appender.MESSAGETABBLE.DumpConsole=true
 +</​code>​
 +在appender中,可以加入set code去達到此需求:​
 +<code java>
 + public void setDumpConsole(boolean value){
 + System.out.println(value);​
 + }
 +</​code>​
 +
 +
 +===== Reference =====
 +  * [[https://​gist.github.com/​kengelke/​4664612|GitHub - CachingSingletonAppender]]
 +  * [[http://​stackoverflow.com/​questions/​6072389/​how-to-create-a-own-appender-in-log4j|how-to-create-a-own-appender-in-log4j]]
  
 +=====    =====
 +----
 +\\
 +~~DISQUS~~