You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ps...@apache.org on 2003/09/22 05:54:03 UTC

cvs commit: jakarta-log4j-sandbox build.properties.sample build.xml

psmith      2003/09/21 20:54:03

  Modified:    .        build.properties.sample build.xml
  Added:       src/java/org/apache/log4j/net IMAppender.java
                        DefaultEvaluator.java
  Log:
  Addition of the IMAppender to the log4j sandbox, kindly
  donated to the ASF by Rafael Luque Leiva and Ruth Zamorano.
  
  This appender requires the Smack library, which is
  required to be setup in the build.properties (see build.properties.samples).
  
  Revision  Changes    Path
  1.1                  jakarta-log4j-sandbox/src/java/org/apache/log4j/net/IMAppender.java
  
  Index: IMAppender.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of  source code must  retain the above copyright  notice,
   *    this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright notice,
   *    this list of conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * 3. The end-user documentation included with the redistribution, if any, must
   *    include  the following  acknowledgment:  "This product includes  software
   *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.net;
  
  import org.apache.log4j.AppenderSkeleton;
  import org.apache.log4j.Layout;
  import org.apache.log4j.helpers.CyclicBuffer;
  import org.apache.log4j.helpers.LogLog;
  import org.apache.log4j.helpers.OptionConverter;
  import org.apache.log4j.spi.ErrorCode;
  import org.apache.log4j.spi.LoggingEvent;
  import org.apache.log4j.spi.TriggeringEventEvaluator;
  
  import org.jivesoftware.smack.Chat;
  import org.jivesoftware.smack.GroupChat;
  import org.jivesoftware.smack.SSLXMPPConnection;
  import org.jivesoftware.smack.XMPPConnection;
  
  
  /**
   * IMAppender appends logging requests through instant
   * messaging network.
   *
   * <p>More info about the IMAppender in the article
   * "Instant logging: Harness the power of log4j with Jabber"
   * (developerWorks, August 2003) at
   * <http://www-106.ibm.com/developerworks/java/library/j-instlog/></p>
   *
   * @author Rafael Luque
   * @author Ruth Zamorano
   */
  public class IMAppender extends AppenderSkeleton {
    // ----------------------------------------------- Variables
    private String host;
    private int port = 5222;
    private String username;
    private String password;
    private String recipient;
    private boolean chatroom = false;
    private String nickname;
    private boolean SSL = false;
    private int bufferSize = 16;
    protected TriggeringEventEvaluator evaluator;
    protected CyclicBuffer cb;
    protected XMPPConnection con;
    protected Chat chat;
    protected GroupChat groupchat;
  
    // -------------------------------------------- Constructors
  
    /**
     * The default constructor will instantiate the appender
     * with a default TriggeringEventEvaluator that will
     * trigger on events with level ERROR or higher.
     */
    public IMAppender() {
      this(new DefaultEvaluator());
    }
  
    public IMAppender(TriggeringEventEvaluator evaluator) {
      this.evaluator = evaluator;
    }
  
    // ------------------------------- Setter and getter methods
    public String getHost() {
      return this.host;
    }
  
    public void setHost(String host) {
      this.host = host;
    }
  
    public int getPort() {
      return this.port;
    }
  
    public void setPort(int port) {
      this.port = port;
    }
  
    public String getUsername() {
      return this.username;
    }
  
    public void setUsername(String username) {
      this.username = username;
    }
  
    public String getPassword() {
      return this.password;
    }
  
    public void setPassword(String password) {
      this.password = password;
    }
  
    public String getRecipient() {
      return this.recipient;
    }
  
    public void setRecipient(String recipient) {
      this.recipient = recipient;
    }
  
    public boolean isChatroom() {
      return this.chatroom;
    }
  
    public void setChatroom(boolean chatroom) {
      this.chatroom = chatroom;
    }
  
    public String getNickname() {
      return this.nickname;
    }
  
    public void setNickname(String nickname) {
      this.nickname = nickname;
    }
  
    public boolean isSSL() {
      return this.SSL;
    }
  
    public void setSSL(boolean SSL) {
      this.SSL = SSL;
    }
  
    public int getBufferSize() {
      return this.bufferSize;
    }
  
    public void setBufferSize(int bufferSize) {
      this.bufferSize = bufferSize;
    }
  
    /**
     * The <b>EvaluatorClass</b> option takes a string value
     * representing the name of the class implementing the
     * {@link TriggeringEventEvaluator} interface. A corresponding
     * object will be instantiated and assigned as the triggering
     * event evaluator for the SMTPAppender.
     */
    public void setEvaluatorClass(String value) {
      evaluator =
        (TriggeringEventEvaluator) OptionConverter.instantiateByClassName(
          value, TriggeringEventEvaluator.class, evaluator);
    }
  
    public String getEvaluatorClass() {
      return (evaluator == null) ? null : evaluator.getClass().getName();
    }
  
    // ---------------------------------- Log4j callback methods
  
    /**
     * Options are activated and become effective only
     * after calling this method.
     */
    public void activateOptions() {
      try {
        cb = new CyclicBuffer(bufferSize);
  
        // Create a connection to the XMPP server
        LogLog.debug("Establishing connection with XMPP server");
  
        if (SSL) {
          con = new SSLXMPPConnection(host, port);
        } else {
          con = new XMPPConnection(host, port);
        }
  
        // Most servers require you to login 
        // before performing other tasks
        LogLog.debug("About to login as [" + username + "/" + password + "]");
        con.login(username, password);
  
        // Start a conversation with IMAddress
        if (chatroom) {
          LogLog.debug("About to create ChatGroup");
          groupchat = con.createGroupChat(recipient);
          LogLog.debug("About to join room");
          groupchat.join((nickname != null) ? nickname : username);
        } else {
          chat = con.createChat(recipient);
        }
      } catch (Exception e) {
        errorHandler.error(
          "Error while activating options" + " for appender named [" + name
          + "]", e, ErrorCode.GENERIC_FAILURE);
      }
    }
  
    /**
     * Close this IMAppender. Closing all resources used
     * by the appender. A closed appender cannot be re-opened.
     */
    public synchronized void close() {
      if (this.closed) {
        return;
      }
  
      LogLog.debug("Closing appender [" + name + "]");
      this.closed = true;
  
      // Closes the connection by setting presence to unavailable 
      // then closing the stream to the XMPP server. 
      if (con != null) {
        con.close();
      }
  
      // Help GC
      con = null;
      chat = null;
      groupchat = null;
    }
  
    /**
     * This method called by {@link AppenderSkeleton#doAppend}
     * method does most of the real appending work. Adds the event
     * to a buffer and checks if the event triggers a message to
     * be sent.
     */
    public void append(LoggingEvent event) {
      // check pre-conditions
      if (!checkEntryConditions()) {
        return;
      }
  
      cb.add(event);
  
      if (evaluator.isTriggeringEvent(event)) {
        sendBuffer();
      }
    }
  
    /**
     * Send the contents of the cyclic buffer as an IM message.
     */
    protected void sendBuffer() {
      try {
        StringBuffer buf = new StringBuffer();
  
        int len = cb.length();
  
        for (int i = 0; i < len; i++) {
          LoggingEvent event = cb.get();
          buf.append(layout.format(event));
  
          // if layout doesn't handle exception, 
          // the appender has to do it
          if (layout.ignoresThrowable()) {
            String[] s = event.getThrowableStrRep();
  
            if (s != null) {
              for (int j = 0; j < s.length; j++) {
                buf.append(Layout.LINE_SEP);
                buf.append(s[j]);
              }
            }
          }
        }
  
        if (chatroom) {
          groupchat.sendMessage(buf.toString());
        } else {
          chat.sendMessage(buf.toString());
        }
      } catch (Exception e) {
        errorHandler.error(
          "Could not send message in IMAppender [" + name + "]", e,
          ErrorCode.GENERIC_FAILURE);
      }
    }
  
    /**
     * This method determines if there is a sense in attempting
     * to append.
     *
     * <p>It checks whether there is an output chat available
     * and also if there is a set layout. If these checks fail,
     * then the boolean value <code>false</code> is returned.
     */
    protected boolean checkEntryConditions() {
      if ((this.chat == null) && (this.groupchat == null)) {
        errorHandler.error("Chat object not configured");
  
        return false;
      }
  
      if (this.layout == null) {
        errorHandler.error("No layout set for appender named [" + name + "]");
  
        return false;
      }
  
      return true;
    }
  
    /**
     * The IMAppender requires a layout. Hence, this method
     * returns <code>true</code>.
     */
    public boolean requiresLayout() {
      return true;
    }
  }
  
  
  
  1.1                  jakarta-log4j-sandbox/src/java/org/apache/log4j/net/DefaultEvaluator.java
  
  Index: DefaultEvaluator.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of  source code must  retain the above copyright  notice,
   *    this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright notice,
   *    this list of conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * 3. The end-user documentation included with the redistribution, if any, must
   *    include  the following  acknowledgment:  "This product includes  software
   *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.net;
  
  import org.apache.log4j.Level;
  import org.apache.log4j.spi.LoggingEvent;
  import org.apache.log4j.spi.TriggeringEventEvaluator;
  
  
  /**
   * <code>DefaultEvaluator</code> implements the single method
   * <code>TriggeringEventEvaluator</code> interface. This class
   * allows the <code>IMAppender</code> to decide when to perform the
   * message delivery.
   *
   * @author Rafael Luque
   * @author Ruth Zamorano
   */
  public class DefaultEvaluator implements TriggeringEventEvaluator {
    /**
     * This method returns <code>true</code> if the event level
     * has ERROR level or higher. Otherwise it returns
     * <code>false</code>.
     */
    public boolean isTriggeringEvent(LoggingEvent event) {
      return event.getLevel().isGreaterOrEqual(Level.ERROR);
    }
  }
  
  
  
  1.7       +2 -0      jakarta-log4j-sandbox/build.properties.sample
  
  Index: build.properties.sample
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j-sandbox/build.properties.sample,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- build.properties.sample	27 Aug 2003 07:58:46 -0000	1.6
  +++ build.properties.sample	22 Sep 2003 03:54:03 -0000	1.7
  @@ -22,3 +22,5 @@
   # Jalopy OPTIONAL; required to run the jalpoy targets
   jalopy.lib=d:/development/code-opensource/other/jalopy-b10/lib
   
  +# Smack jar OPTIONAL; required to build the org.apache.log4j.net.IMAppender
  +smack.jar=../smack-1.2.0/smack.jar
  
  
  
  1.13      +29 -1     jakarta-log4j-sandbox/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j-sandbox/build.xml,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- build.xml	28 Aug 2003 01:34:10 -0000	1.12
  +++ build.xml	22 Sep 2003 03:54:03 -0000	1.13
  @@ -46,6 +46,7 @@
       <pathelement location="${build.home}/classes"/>
       <pathelement location="${log4j.jar}"/>
       <pathelement location="${servlet.jar}"/>
  +    <pathelement location="${smack.jar}"/>
     </path>
   
   
  @@ -84,7 +85,23 @@
       <tstamp />
     </target>
   
  -  <target name="build" depends="init, build.core, build.servlet"/>
  +	<target name="imCheck">
  +		<available classname="org.jivesoftware.smack.XMPPConnection" property="im-jar-present">
  +			<classpath>
  +				<pathelement location="${smack.jar}"/>
  +			</classpath>
  +		</available>
  +	</target>
  +
  +	<target name="imNoJar" unless="im-jar-present">
  +			<echo >Smack library not found, the IMAppender will not be included in the build/jar</echo>
  +	</target>
  +
  +  <target name="im" depends="imCheck, imNoJar" if="im-jar-present">
  +    <echo message="Smack IM jar is present."/>
  +  </target>
  +
  +  <target name="build" depends="init, build.core, build.servlet, build.im"/>
   
     <target name="build.core" depends="init">
       <mkdir dir="${javac.dest}" />
  @@ -118,6 +135,17 @@
       </javac>
     </target>
   
  +  <target name="build.im" depends="init, im" if="im-jar-present">
  +    <javac srcdir="${java.source.dir}"
  +            destdir="${javac.dest}"
  +            debug="${build.debug}"
  +            deprecation="${build.deprecation}"
  +            optimize="${build.optimize}"
  +            verbose="${build.verbose}">
  +      <include name="**/net/**/*.java"/>
  +      <classpath refid="compile.classpath"/>
  +    </javac>
  +  </target>
     <!-- ================================================================= -->
     <!-- Remove all build generated files.                                 -->
     <!-- ================================================================= -->
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: log4j-dev-help@jakarta.apache.org