2012-10-19 65 views
1

我对Web服务世界相当陌生,但具有log4j的知识。使用log4j将日志发送到Java中的Web服务

我需要实现的功能是将日志消息发送到Web服务,而不是使用Web服务附加程序发送到文件。

我通过在上搜索来阅读GoogleWebServiceAppenderlog4j类之一,但我无法验证这一点。

log4j.appender.CONSOLE=main.WSAppender 
log4j.appender.CONSOLE.endpoint=http://localhost:8080/Logging/services/logging?w‌​sdl 
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 
log4j.appender.CONSOLE.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) :: %m%n 
WSAppender.java extends AppenderSkeleton, can't resolve endpoint, hostname in append()  

if (endpoint == null) { 
    System.out.println("no endpoint set. Check configuration file"); 
    System.out.println("[" + hostname + "] " + this.layout.format(event)); 
    return; 
} 
+0

到目前为止,您有没有尝试使用过的任何代码?如果你需要一些帮助,你将需要首先展示一些研究。使用一些代码,它会给我们一些地方开始,而不是为你实现这个。告诉我们你卡在哪里。你唯一的另一个希望是,如果有人出现,谁知道这里面和外面,并愿意发布一个完整的解决方案。祝你好运! – jmort253

+0

你好,你对克雷格的评论让我觉得你应该一次采取这一步。你收到什么错误信息?你在资源链接中获得了多少?你提供的细节越多,帮助就越容易,而且你会得到更好的答案。希望这可以帮助! – jmort253

+0

我猜测log4j.properties文件没有被拾取,我在eclipse中使用了axis2实现,并且可以看到已经存在的文件。所以我在上面添加了它。基本上端点需要从某个地方挑选,因为错误消息显而易见,“端点”无法解析为变量 –

回答

6

当你扩展类AppenderSkeleton我假设你应该初始化你应该覆盖public void activateOptions()方法的webservice类。我写过DatabaseAppender和JmsAppender log4j记录器,我总是发现我必须初始化db连接或jms连接,或者在你的情况下使用public void activateOptions()方法中的webservice属性。

然后像往常一样在append(LoggingEvent)方法,你只需调用web服务。

我可能会建议实施一个BlockingQueue来存储所有的LoggingEvent对象,这样如果您收到日志消息的涌入,它们将排队并异步发送到Web服务。

更新到包括模板的Log4j类

尝试使用下面的模板。我在重要部分添加了评论。基本上在activateOptions和processEvent方法是你初始化你的“连接”并发送你的事件对象的地方。可以是DB,JMS,WebService等等。

package mypackage; 

     import java.util.concurrent.BlockingQueue; 
     import java.util.concurrent.LinkedBlockingQueue; 
     import java.util.concurrent.TimeUnit; 
     import org.apache.log4j.AppenderSkeleton; 
     import org.apache.log4j.helpers.LogLog; 
     import org.apache.log4j.spi.LoggingEvent; 

     public class WebServiceAppender extends AppenderSkeleton { 

      private static final BlockingQueue<LoggingEvent> loggingEventQueue = new LinkedBlockingQueue<LoggingEvent>(); 
      private static WebServiceAppender instance; 
      private static Thread thread = null; 

      //Your custom properties for your web service 

      private String property1; 
      private String property2; 
      private String property3; 

      static { 
       thread = new Thread(new Runnable() { 
        public void run() { 
         processQueue(); 
        } 
       }); 

       thread.setDaemon(true); 
       thread.start(); 
      } 

      private static void processQueue() { 
       while(true) { 
        try { 
         LoggingEvent event = loggingEventQueue.poll(1L, TimeUnit.SECONDS); 
         if (event != null) { 
          instance.processEvent(event); 
         } 
        } 
        catch(InterruptedException e) { 
         // No operations. 
        } 
       } 
      } 

      private final void processEvent(LoggingEvent loggingEvent) { 
       if(loggingEvent != null) { 
        //Send the loggingEvent object or you can 
        //get data out of it and package it in another 
        //java class and send that, to your web service. 

        //Web Service is invoked here 
       } 
      } 

      public synchronized void close() { 
       // The synchronized modifier avoids concurrent append and close operations 

        if(this.closed) { 
         return; 
       } 

       closeWS(); 
       thread.interrupt(); 

       LogLog.debug("Closing appender [" + name + "]."); 
       this.closed = true; 
      } 

      private void closeWS() { 
       try { 
        //Close the webservice connection 
        //or whatever here. 
       } 
       catch(Exception ex) { 
        LogLog.error("Error while closing WebServiceAppender [" + name + "].", ex); 
       } 
      } 

      public boolean requiresLayout() { 
       //Does not need a layout because 
       //we are sending serialized events 
       //to an external source 
       return false; 
      } 

      @Override 
      public void activateOptions() { 
       instance = this; 
       try { 
        LogLog.debug("Getting web service properties."); 

        if(property1 != null) { 
         //Do something with your property 
        } 

        if(property2 != null) { 
         //Do something with your property 
        } 

        if(property3 != null) { 
         //Do something with your property 
        } 

        //Initialize your web-service connection and objects here 
        LogLog.debug("Web Service created."); 
       } 
       catch(Exception ex) { 
        LogLog.error("Error while activating options for WebServiceAppender [" + name + "].", ex); 
       } 
      } 

      /* 
      * These methods are set from the log4j properties file like: 
      * log4j.appender.WS=mypackage.WebServiceAppender 
      * log4j.appender.WS.property1=bla 
      * log4j.appender.WS.property2=ble 
      * log4j.appender.WS.property3=blo 
      */ 

      public final String getProperty1() { 
       return property1; 
      } 

      public final String getProperty2() { 
       return property2; 
      } 

      public final String getProperty3() { 
       return property3; 
      } 

      public final void setProperty1(String property1) { 
       this.property1 = property1; 
      } 

      public final void setProperty2(String property2) { 
       this.property2 = property2; 
      } 

      public final void setProperty3(String property3) { 
       this.property3 = property3; 
      } 

      @Override 
      protected void append(LoggingEvent event) { 
       loggingEventQueue.add(event); 
      } 

      @Override 
      public void finalize() { 
       close(); 
       super.finalize(); 
      } 
     } 
+0

这有帮助,但我是Queue的新手,会尝试学习并实施您的建议。另外我想知道'JMSAppender'是否可用于将日志发送到Web服务 –

+0

可能不是,JMSAppender只是通过JMS连接将日志发送到JMS主题。如果你想我可以更新我的答案,并包括代码与存根(stub)来制作一个自定义的appender。 –

+0

非常感谢代码,这将帮助我快速构建应用程序! –

2

我建议你看看这篇文章:http://www.ibm.com/developerworks/webservices/library/ws-log4j/index.html

它详细说明如何使用的WebServiceAppender。

啊,Google!

+0

感谢@craigmj,我首先检查了这篇文章,但我感到困惑,因为有代码片段,而且我正在迷失,因为我把所有的东西放在哪里 –

+0

嗨克雷格,虽然这个链接可能会有所帮助,但如果链接断裂,你的答案将毫无用处。堆栈溢出的最佳答案包含的例子和解释不仅有助于原始提问者,而且还有助于未来很多未来的访问者。请考虑制作一个[编辑]来改进你的答案。这不仅能够帮助其他人,还能让你获得更多赞赏!祝你好运!:) – jmort253

+0

嗨@ jmort253,这是一个很好的观点。但是很少复制整个DeveloperWorks文章,人们会如何解决这个问题? (因为在这种情况下,DW文章是相当详细的...) – craigmj

相关问题