001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.activemq.util; 018 019 import java.io.Serializable; 020 import java.util.ArrayList; 021 import java.util.Iterator; 022 import java.util.List; 023 024 import javax.jms.Connection; 025 import javax.jms.Destination; 026 import javax.jms.JMSException; 027 import javax.jms.Message; 028 import javax.jms.MessageProducer; 029 import javax.jms.Session; 030 import javax.naming.NamingException; 031 032 import org.apache.log4j.AppenderSkeleton; 033 import org.apache.log4j.spi.LoggingEvent; 034 035 /** 036 * An abstract base class for implementation inheritence for a log4j JMS 037 * appender 038 * 039 * @version $Revision: 565003 $ 040 */ 041 public abstract class JmsLogAppenderSupport extends AppenderSkeleton { 042 043 public static final int JMS_PUBLISH_ERROR_CODE = 61616; 044 045 private Connection connection; 046 private Session session; 047 private MessageProducer producer; 048 private boolean allowTextMessages = true; 049 private String subjectPrefix = "log4j."; 050 051 public JmsLogAppenderSupport() { 052 } 053 054 public Connection getConnection() throws JMSException, NamingException { 055 if (connection == null) { 056 connection = createConnection(); 057 } 058 return connection; 059 } 060 061 public void setConnection(Connection connection) { 062 this.connection = connection; 063 } 064 065 public Session getSession() throws JMSException, NamingException { 066 if (session == null) { 067 session = createSession(); 068 } 069 return session; 070 } 071 072 public void setSession(Session session) { 073 this.session = session; 074 } 075 076 public MessageProducer getProducer() throws JMSException, NamingException { 077 if (producer == null) { 078 producer = createProducer(); 079 } 080 return producer; 081 } 082 083 public void setProducer(MessageProducer producer) { 084 this.producer = producer; 085 } 086 087 public void close() { 088 List<JMSException> errors = new ArrayList<JMSException>(); 089 if (producer != null) { 090 try { 091 producer.close(); 092 } catch (JMSException e) { 093 errors.add(e); 094 } 095 } 096 if (session != null) { 097 try { 098 session.close(); 099 } catch (JMSException e) { 100 errors.add(e); 101 } 102 } 103 if (connection != null) { 104 try { 105 connection.close(); 106 } catch (JMSException e) { 107 errors.add(e); 108 } 109 } 110 for (Iterator<JMSException> iter = errors.iterator(); iter.hasNext();) { 111 JMSException e = iter.next(); 112 getErrorHandler().error("Error closing JMS resources: " + e, e, JMS_PUBLISH_ERROR_CODE); 113 } 114 } 115 116 public boolean requiresLayout() { 117 return false; 118 } 119 120 public void activateOptions() { 121 try { 122 // lets ensure we're all created 123 getProducer(); 124 } catch (Exception e) { 125 getErrorHandler().error("Could not create JMS resources: " + e, e, JMS_PUBLISH_ERROR_CODE); 126 } 127 } 128 129 // Implementation methods 130 // ------------------------------------------------------------------------- 131 protected abstract Connection createConnection() throws JMSException, NamingException; 132 133 protected Session createSession() throws JMSException, NamingException { 134 return getConnection().createSession(false, Session.AUTO_ACKNOWLEDGE); 135 } 136 137 protected MessageProducer createProducer() throws JMSException, NamingException { 138 return getSession().createProducer(null); 139 } 140 141 protected void append(LoggingEvent event) { 142 try { 143 Message message = createMessage(event); 144 Destination destination = getDestination(event); 145 getProducer().send(destination, message); 146 } catch (Exception e) { 147 getErrorHandler().error("Could not send message due to: " + e, e, JMS_PUBLISH_ERROR_CODE, event); 148 } 149 } 150 151 protected Message createMessage(LoggingEvent event) throws JMSException, NamingException { 152 Message answer = null; 153 Object value = event.getMessage(); 154 if (allowTextMessages && value instanceof String) { 155 answer = getSession().createTextMessage((String)value); 156 } else { 157 answer = getSession().createObjectMessage((Serializable)value); 158 } 159 answer.setStringProperty("level", event.getLevel().toString()); 160 answer.setIntProperty("levelInt", event.getLevel().toInt()); 161 answer.setStringProperty("threadName", event.getThreadName()); 162 return answer; 163 } 164 165 protected Destination getDestination(LoggingEvent event) throws JMSException, NamingException { 166 String name = subjectPrefix + event.getLoggerName(); 167 return getSession().createTopic(name); 168 } 169 }