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 }