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 018 package org.apache.logging.log4j.core.appender.mom; 019 020 import java.io.Serializable; 021 import javax.jms.JMSException; 022 import javax.jms.Message; 023 import javax.jms.MessageProducer; 024 025 import org.apache.logging.log4j.core.Filter; 026 import org.apache.logging.log4j.core.Layout; 027 import org.apache.logging.log4j.core.LogEvent; 028 import org.apache.logging.log4j.core.appender.AbstractAppender; 029 import org.apache.logging.log4j.core.appender.AppenderLoggingException; 030 import org.apache.logging.log4j.core.config.plugins.Plugin; 031 import org.apache.logging.log4j.core.config.plugins.PluginAliases; 032 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute; 033 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; 034 import org.apache.logging.log4j.core.config.plugins.PluginElement; 035 import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; 036 import org.apache.logging.log4j.core.layout.SerializedLayout; 037 import org.apache.logging.log4j.core.net.JndiManager; 038 039 /** 040 * Generic JMS Appender plugin for both queues and topics. This Appender replaces the previous split ones. However, 041 * configurations set up for the 2.0 version of the JMS appenders will still work. 042 */ 043 @Plugin(name = "JMS", category = "Core", elementType = "appender", printObject = true) 044 @PluginAliases({"JMSQueue", "JMSTopic"}) 045 public class JmsAppender extends AbstractAppender { 046 047 private static final long serialVersionUID = 1L; 048 private final JmsManager manager; 049 private final MessageProducer producer; 050 051 protected JmsAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout, 052 final boolean ignoreExceptions, final JmsManager manager) 053 throws JMSException { 054 super(name, filter, layout, ignoreExceptions); 055 this.manager = manager; 056 this.producer = this.manager.createMessageProducer(); 057 } 058 059 @Override 060 public void append(final LogEvent event) { 061 try { 062 final Message message = this.manager.createMessage(getLayout().toSerializable(event)); 063 message.setJMSTimestamp(event.getTimeMillis()); 064 this.producer.send(message); 065 } catch (final JMSException e) { 066 throw new AppenderLoggingException(e); 067 } 068 } 069 070 @PluginBuilderFactory 071 public static Builder newBuilder() { 072 return new Builder(); 073 } 074 075 public static class Builder implements org.apache.logging.log4j.core.util.Builder<JmsAppender> { 076 077 @PluginBuilderAttribute 078 @Required(message = "A name for the JmsAppender must be specified") 079 private String name; 080 081 @PluginBuilderAttribute 082 private String factoryName; 083 084 @PluginBuilderAttribute 085 private String providerUrl; 086 087 @PluginBuilderAttribute 088 private String urlPkgPrefixes; 089 090 @PluginBuilderAttribute 091 private String securityPrincipalName; 092 093 @PluginBuilderAttribute(sensitive = true) 094 private String securityCredentials; 095 096 @PluginBuilderAttribute 097 @Required(message = "A javax.jms.ConnectionFactory JNDI name must be specified") 098 private String factoryBindingName; 099 100 @PluginBuilderAttribute 101 @PluginAliases({"queueBindingName", "topicBindingName"}) 102 @Required(message = "A javax.jms.Destination JNDI name must be specified") 103 private String destinationBindingName; 104 105 @PluginBuilderAttribute 106 private String username; 107 108 @PluginBuilderAttribute(sensitive = true) 109 private String password; 110 111 @PluginElement("Layout") 112 private Layout<? extends Serializable> layout = SerializedLayout.createLayout(); 113 114 @PluginElement("Filter") 115 private Filter filter; 116 117 @PluginBuilderAttribute 118 private boolean ignoreExceptions = true; 119 120 private Builder() { 121 } 122 123 public Builder setName(final String name) { 124 this.name = name; 125 return this; 126 } 127 128 public Builder setFactoryName(final String factoryName) { 129 this.factoryName = factoryName; 130 return this; 131 } 132 133 public Builder setProviderUrl(final String providerUrl) { 134 this.providerUrl = providerUrl; 135 return this; 136 } 137 138 public Builder setUrlPkgPrefixes(final String urlPkgPrefixes) { 139 this.urlPkgPrefixes = urlPkgPrefixes; 140 return this; 141 } 142 143 public Builder setSecurityPrincipalName(final String securityPrincipalName) { 144 this.securityPrincipalName = securityPrincipalName; 145 return this; 146 } 147 148 public Builder setSecurityCredentials(final String securityCredentials) { 149 this.securityCredentials = securityCredentials; 150 return this; 151 } 152 153 public Builder setFactoryBindingName(final String factoryBindingName) { 154 this.factoryBindingName = factoryBindingName; 155 return this; 156 } 157 158 public Builder setDestinationBindingName(final String destinationBindingName) { 159 this.destinationBindingName = destinationBindingName; 160 return this; 161 } 162 163 public Builder setUsername(final String username) { 164 this.username = username; 165 return this; 166 } 167 168 public Builder setPassword(final String password) { 169 this.password = password; 170 return this; 171 } 172 173 public Builder setLayout(final Layout<? extends Serializable> layout) { 174 this.layout = layout; 175 return this; 176 } 177 178 public Builder setFilter(final Filter filter) { 179 this.filter = filter; 180 return this; 181 } 182 183 public Builder setIgnoreExceptions(final boolean ignoreExceptions) { 184 this.ignoreExceptions = ignoreExceptions; 185 return this; 186 } 187 188 @Override 189 public JmsAppender build() { 190 final JndiManager jndiManager = JndiManager.getJndiManager(factoryName, providerUrl, urlPkgPrefixes, 191 securityPrincipalName, securityCredentials, null); 192 final JmsManager jmsManager = JmsManager.getJmsManager(name, jndiManager, factoryBindingName, 193 destinationBindingName, username, password); 194 try { 195 return new JmsAppender(name, filter, layout, ignoreExceptions, jmsManager); 196 } catch (final JMSException e) { 197 LOGGER.error("Error creating JmsAppender [{}].", name, e); 198 return null; 199 } 200 } 201 } 202 203 }