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 018package org.apache.log4j.net; 019 020import org.apache.log4j.Logger; 021import org.apache.log4j.PropertyConfigurator; 022import org.apache.log4j.spi.LoggingEvent; 023import org.apache.log4j.xml.DOMConfigurator; 024 025import javax.jms.JMSException; 026import javax.jms.ObjectMessage; 027import javax.jms.Session; 028import javax.jms.Topic; 029import javax.jms.TopicConnection; 030import javax.jms.TopicConnectionFactory; 031import javax.jms.TopicSession; 032import javax.jms.TopicSubscriber; 033import javax.naming.Context; 034import javax.naming.InitialContext; 035import javax.naming.NameNotFoundException; 036import javax.naming.NamingException; 037import java.io.BufferedReader; 038import java.io.InputStreamReader; 039 040/** 041 * A simple application that consumes logging events sent by a {@link 042 * JMSAppender}. 043 * 044 * 045 * @author Ceki Gülcü 046 * */ 047public class JMSSink implements javax.jms.MessageListener { 048 049 static Logger logger = Logger.getLogger(JMSSink.class); 050 051 static public void main(String[] args) throws Exception { 052 if(args.length != 5) { 053 usage("Wrong number of arguments."); 054 } 055 056 String tcfBindingName = args[0]; 057 String topicBindingName = args[1]; 058 String username = args[2]; 059 String password = args[3]; 060 061 062 String configFile = args[4]; 063 064 if(configFile.endsWith(".xml")) { 065 DOMConfigurator.configure(configFile); 066 } else { 067 PropertyConfigurator.configure(configFile); 068 } 069 070 new JMSSink(tcfBindingName, topicBindingName, username, password); 071 072 BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); 073 // Loop until the word "exit" is typed 074 System.out.println("Type \"exit\" to quit JMSSink."); 075 while(true){ 076 String s = stdin.readLine( ); 077 if (s.equalsIgnoreCase("exit")) { 078 System.out.println("Exiting. Kill the application if it does not exit " 079 + "due to daemon threads."); 080 return; 081 } 082 } 083 } 084 085 public JMSSink( String tcfBindingName, String topicBindingName, String username, 086 String password) { 087 088 try { 089 Context ctx = new InitialContext(); 090 TopicConnectionFactory topicConnectionFactory; 091 topicConnectionFactory = (TopicConnectionFactory) lookup(ctx, 092 tcfBindingName); 093 094 TopicConnection topicConnection = 095 topicConnectionFactory.createTopicConnection(username, 096 password); 097 topicConnection.start(); 098 099 TopicSession topicSession = topicConnection.createTopicSession(false, 100 Session.AUTO_ACKNOWLEDGE); 101 102 Topic topic = (Topic)ctx.lookup(topicBindingName); 103 104 TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic); 105 106 topicSubscriber.setMessageListener(this); 107 108 } catch(JMSException e) { 109 logger.error("Could not read JMS message.", e); 110 } catch(NamingException e) { 111 logger.error("Could not read JMS message.", e); 112 } catch(RuntimeException e) { 113 logger.error("Could not read JMS message.", e); 114 } 115 } 116 117 public void onMessage(javax.jms.Message message) { 118 LoggingEvent event; 119 Logger remoteLogger; 120 121 try { 122 if(message instanceof ObjectMessage) { 123 ObjectMessage objectMessage = (ObjectMessage) message; 124 event = (LoggingEvent) objectMessage.getObject(); 125 remoteLogger = Logger.getLogger(event.getLoggerName()); 126 remoteLogger.callAppenders(event); 127 } else { 128 logger.warn("Received message is of type "+message.getJMSType() 129 +", was expecting ObjectMessage."); 130 } 131 } catch(JMSException jmse) { 132 logger.error("Exception thrown while processing incoming message.", 133 jmse); 134 } 135 } 136 137 138 protected static Object lookup(Context ctx, String name) throws NamingException { 139 try { 140 return ctx.lookup(name); 141 } catch(NameNotFoundException e) { 142 logger.error("Could not find name ["+name+"]."); 143 throw e; 144 } 145 } 146 147 static void usage(String msg) { 148 System.err.println(msg); 149 System.err.println("Usage: java " + JMSSink.class.getName() 150 + " TopicConnectionFactoryBindingName TopicBindingName username password configFile"); 151 System.exit(1); 152 } 153}