summaryrefslogtreecommitdiff
path: root/qpid/java/broker/src/main/java/org/apache/qpid/server/logging
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java/broker/src/main/java/org/apache/qpid/server/logging')
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java59
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/CompositeStartupMessageLogger.java51
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java74
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogActor.java66
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogMessage.java26
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogSubject.java36
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/NullRootMessageLogger.java47
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/RootMessageLogger.java75
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/SystemOutMessageLogger.java51
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPChannelActor.java64
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPConnectionActor.java54
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractActor.java71
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/BrokerActor.java53
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java125
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/GenericActor.java85
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java114
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/QueueActor.java55
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/SubscriptionActor.java46
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java825
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Binding_logmessages.properties22
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties38
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties34
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ConfigStore_logmessages.properties27
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Connection_logmessages.properties24
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Exchange_logmessages.properties24
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties33
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/MessageStore_logmessages.properties28
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Queue_logmessages.properties26
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Subscription_logmessages.properties24
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/TransactionLog_logmessages.properties33
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties26
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/AbstractLogSubject.java63
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java49
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java56
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java107
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java36
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java107
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubject.java36
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java36
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubject.java55
40 files changed, 2861 insertions, 0 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java
new file mode 100644
index 0000000000..545f2adea2
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging;
+
+import org.apache.qpid.server.configuration.ServerConfiguration;
+
+public abstract class AbstractRootMessageLogger implements RootMessageLogger
+{
+ public static final String DEFAULT_LOG_HIERARCHY_PREFIX = "qpid.message.";
+
+ private boolean _enabled = true;
+
+ public AbstractRootMessageLogger()
+ {
+
+ }
+
+ public AbstractRootMessageLogger(ServerConfiguration config)
+ {
+ _enabled = config.getStatusUpdatesEnabled();
+ }
+
+ public boolean isEnabled()
+ {
+ return _enabled;
+ }
+
+ public boolean isMessageEnabled(LogActor actor, LogSubject subject, String logHierarchy)
+ {
+ return _enabled;
+ }
+
+ public boolean isMessageEnabled(LogActor actor, String logHierarchy)
+ {
+ return _enabled;
+ }
+
+ public abstract void rawMessage(String message, String logHierarchy);
+
+ public abstract void rawMessage(String message, Throwable throwable, String logHierarchy);
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/CompositeStartupMessageLogger.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/CompositeStartupMessageLogger.java
new file mode 100644
index 0000000000..e0a51b3a3e
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/CompositeStartupMessageLogger.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging;
+
+public class CompositeStartupMessageLogger extends AbstractRootMessageLogger
+{
+ private RootMessageLogger[] _loggers;
+
+ public CompositeStartupMessageLogger(RootMessageLogger[] loggers)
+ {
+ super();
+ _loggers = loggers;
+ }
+
+ @Override
+ public void rawMessage(String message, String logHierarchy)
+ {
+ for(RootMessageLogger l : _loggers)
+ {
+ l.rawMessage(message, logHierarchy);
+ }
+ }
+
+ @Override
+ public void rawMessage(String message, Throwable throwable, String logHierarchy)
+ {
+ for(RootMessageLogger l : _loggers)
+ {
+ l.rawMessage(message, throwable, logHierarchy);
+ }
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java
new file mode 100644
index 0000000000..a0285ebfc4
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+
+public class Log4jMessageLogger extends AbstractRootMessageLogger
+{
+ public static final Level LEVEL = Level.toLevel("INFO");
+
+ public Log4jMessageLogger()
+ {
+ super();
+ }
+
+ public Log4jMessageLogger(ServerConfiguration config)
+ {
+ super(config);
+ }
+
+ @Override
+ public boolean isMessageEnabled(LogActor actor, LogSubject subject, String logHierarchy)
+ {
+ return isMessageEnabled(actor, logHierarchy);
+ }
+
+ @Override
+ public boolean isMessageEnabled(LogActor actor, String logHierarchy)
+ {
+ if(isEnabled())
+ {
+ Logger logger = Logger.getLogger(logHierarchy);
+ return logger.isEnabledFor(LEVEL);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public void rawMessage(String message, String logHierarchy)
+ {
+ rawMessage(message, null, logHierarchy);
+ }
+
+ @Override
+ public void rawMessage(String message, Throwable throwable, String logHierarchy)
+ {
+ Logger logger = Logger.getLogger(logHierarchy);
+
+ logger.log(LEVEL, message, throwable);
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogActor.java
new file mode 100644
index 0000000000..18f03c2716
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogActor.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging;
+
+/**
+ * LogActor the entity that is stored as in a ThreadLocal and used to perform logging.
+ *
+ * The actor is responsible for formatting its display name for the log entry.
+ *
+ * The actor performs the requested logging.
+ */
+public interface LogActor
+{
+ /**
+ * Logs the specified LogMessage about the LogSubject
+ *
+ * Currently logging has a global setting however this will later be revised and
+ * as such the LogActor will need to take into consideration any new configuration
+ * as a means of enabling the logging of LogActors and LogSubjects.
+ *
+ * @param subject The subject that is being logged
+ * @param message The message to log
+ */
+ public void message(LogSubject subject, LogMessage message);
+
+ /**
+ * Logs the specified LogMessage against this actor
+ *
+ * Currently logging has a global setting however this will later be revised and
+ * as such the LogActor will need to take into consideration any new configuration
+ * as a means of enabling the logging of LogActors and LogSubjects.
+ *
+ * @param message The message to log
+ */
+ public void message(LogMessage message);
+
+ /**
+ *
+ * @return the RootMessageLogger that is currently in use by this LogActor.
+ */
+ RootMessageLogger getRootMessageLogger();
+
+ /**
+ *
+ * @return the String representing this LogActor
+ */
+ public String getLogMessage();
+} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogMessage.java
new file mode 100644
index 0000000000..fa18435fab
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogMessage.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging;
+
+public interface LogMessage
+{
+ String getLogHierarchy();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogSubject.java
new file mode 100644
index 0000000000..09a277e520
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogSubject.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging;
+
+/**
+ * Each LogSubject that wishes to be logged will implement this to provide their
+ * own display representation.
+ *
+ */
+public interface LogSubject
+{
+ /**
+ * Provides the log message as as String.
+ *
+ * @returns String the display representation of this LogSubject
+ */
+ public String toLogString();
+} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/NullRootMessageLogger.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/NullRootMessageLogger.java
new file mode 100644
index 0000000000..db8b24e90e
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/NullRootMessageLogger.java
@@ -0,0 +1,47 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging;
+
+public class NullRootMessageLogger extends AbstractRootMessageLogger
+{
+
+ @Override
+ public boolean isMessageEnabled(LogActor actor, LogSubject subject, String logHeirarchy)
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isMessageEnabled(LogActor actor, String logHierarchy)
+ {
+ return false;
+ }
+
+ public void rawMessage(String message, String logHierarchy)
+ {
+ // drop message
+ }
+
+ public void rawMessage(String message, Throwable throwable, String logHierarchy)
+ {
+ // drop message
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/RootMessageLogger.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/RootMessageLogger.java
new file mode 100644
index 0000000000..1431dd1da9
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/RootMessageLogger.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging;
+
+/**
+ * The RootMessageLogger is used by the LogActors to query if
+ * logging is enabled for the requested message and to provide the actual
+ * message that should be logged.
+ */
+public interface RootMessageLogger
+{
+ /**
+ * Determine whether the MessageLogger is enabled
+ *
+ * @return boolean true if enabled.
+ */
+ boolean isEnabled();
+
+ /**
+ * Determine if the LogSubject and the LogActor should be
+ * generating log messages.
+ * @param actor The actor requesting the logging
+ * @param subject The subject of this log request
+ * @param logHierarchy The log hierarchy for this request
+ *
+ * @return boolean true if the message should be logged.
+ */
+ boolean isMessageEnabled(LogActor actor, LogSubject subject, String logHierarchy);
+
+ /**
+ * Determine if the LogActor should be generating log messages.
+ *
+ * @param actor The actor requesting the logging
+ * @param logHierarchy The log hierarchy for this request
+ *
+ * @return boolean true if the message should be logged.
+ */
+ boolean isMessageEnabled(LogActor actor, String logHierarchy);
+
+ /**
+ * Log the raw message to the configured logger.
+ *
+ * @param message The message to log
+ * @param logHierarchy The log hierarchy for this request
+ */
+ public void rawMessage(String message, String logHierarchy);
+
+ /**
+ * Log the raw message to the configured logger.
+ * Along with a formated stack trace from the Throwable.
+ *
+ * @param message The message to log
+ * @param throwable Optional Throwable that should provide stact trace
+ * @param logHierarchy The log hierarchy for this request
+ */
+ void rawMessage(String message, Throwable throwable, String logHierarchy);
+} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/SystemOutMessageLogger.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/SystemOutMessageLogger.java
new file mode 100644
index 0000000000..b384b3fde3
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/SystemOutMessageLogger.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging;
+
+
+public class SystemOutMessageLogger extends AbstractRootMessageLogger
+{
+ @Override
+ public boolean isMessageEnabled(LogActor actor, LogSubject subject, String logHeirarchy)
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isMessageEnabled(LogActor actor, String logHierarchy)
+ {
+ return true;
+ }
+
+ public void rawMessage(String message, String logHierarchy)
+ {
+ rawMessage(message, null, logHierarchy);
+ }
+
+ public void rawMessage(String message, Throwable throwable, String logHierarchy)
+ {
+ System.out.println(message);
+ if (throwable != null)
+ {
+ throwable.printStackTrace(System.out);
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPChannelActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPChannelActor.java
new file mode 100644
index 0000000000..9c7ffcc5f8
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPChannelActor.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging.actors;
+
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.subjects.ChannelLogSubject;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+
+import java.text.MessageFormat;
+
+/**
+ * An AMQPChannelActor represtents a connection through the AMQP port with an
+ * associated Channel.
+ *
+ * <p/>
+ * This is responsible for correctly formatting the LogActor String in the log
+ * <p/>
+ * [con:1(user@127.0.0.1/)/ch:1]
+ * <p/>
+ * To do this it requires access to the IO Layers as well as a Channel
+ */
+public class AMQPChannelActor extends AbstractActor
+{
+ private final ChannelLogSubject _logString;
+
+ /**
+ * Create a new ChannelActor
+ *
+ * @param channel The Channel for this LogActor
+ * @param rootLogger The root Logger that this LogActor should use
+ */
+ public AMQPChannelActor(AMQChannel channel, RootMessageLogger rootLogger)
+ {
+ super(rootLogger);
+
+
+ _logString = new ChannelLogSubject(channel);
+ }
+
+ public String getLogMessage()
+ {
+ return _logString.toLogString();
+ }
+}
+
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPConnectionActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPConnectionActor.java
new file mode 100644
index 0000000000..1b4bc91bc1
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPConnectionActor.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging.actors;
+
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.subjects.ConnectionLogSubject;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+
+
+
+/**
+ * An AMQPConnectionActor represtents a connectionthrough the AMQP port.
+ * <p/>
+ * This is responsible for correctly formatting the LogActor String in the log
+ * <p/>
+ * [ con:1(user@127.0.0.1/) ]
+ * <p/>
+ * To do this it requires access to the IO Layers.
+ */
+public class AMQPConnectionActor extends AbstractActor
+{
+ private ConnectionLogSubject _logSubject;
+
+ public AMQPConnectionActor(AMQProtocolSession session, RootMessageLogger rootLogger)
+ {
+ super(rootLogger);
+
+ _logSubject = new ConnectionLogSubject(session);
+ }
+
+ public String getLogMessage()
+ {
+ return _logSubject.toLogString();
+ }
+}
+
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractActor.java
new file mode 100644
index 0000000000..e0bf180cc4
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractActor.java
@@ -0,0 +1,71 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.actors;
+
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.LogMessage;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.logging.RootMessageLogger;
+
+public abstract class AbstractActor implements LogActor
+{
+ public final String _msgPrefix = System.getProperty("qpid.logging.prefix","");
+
+ protected RootMessageLogger _rootLogger;
+
+ public AbstractActor(RootMessageLogger rootLogger)
+ {
+ if(rootLogger == null)
+ {
+ throw new NullPointerException("RootMessageLogger cannot be null");
+ }
+ _rootLogger = rootLogger;
+ }
+
+ public void message(LogSubject subject, LogMessage message)
+ {
+ if (_rootLogger.isMessageEnabled(this, subject, message.getLogHierarchy()))
+ {
+ _rootLogger.rawMessage(_msgPrefix + getLogMessage() + subject.toLogString() + message, message.getLogHierarchy());
+ }
+ }
+
+ public void message(LogMessage message)
+ {
+ if (_rootLogger.isMessageEnabled(this, message.getLogHierarchy()))
+ {
+ _rootLogger.rawMessage(_msgPrefix + getLogMessage() + message, message.getLogHierarchy());
+ }
+ }
+
+ public RootMessageLogger getRootMessageLogger()
+ {
+ return _rootLogger;
+ }
+
+ public String toString()
+ {
+ return getLogMessage();
+ }
+
+ abstract public String getLogMessage();
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/BrokerActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/BrokerActor.java
new file mode 100644
index 0000000000..9e77452228
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/BrokerActor.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.actors;
+
+import org.apache.qpid.server.logging.RootMessageLogger;
+
+public class BrokerActor extends AbstractActor
+{
+ private final String _logString;
+
+ /**
+ * Create a new BrokerActor
+ *
+ * @param logger
+ */
+ public BrokerActor(RootMessageLogger logger)
+ {
+ super(logger);
+
+ _logString = "[Broker] ";
+ }
+
+ public BrokerActor(String name, RootMessageLogger logger)
+ {
+ super(logger);
+
+ _logString = "[Broker(" + name + ")] ";
+ }
+
+ public String getLogMessage()
+ {
+ return _logString;
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java
new file mode 100644
index 0000000000..2ebbfeb734
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java
@@ -0,0 +1,125 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.actors;
+
+import org.apache.qpid.server.logging.LogActor;
+
+import java.util.EmptyStackException;
+import java.util.Stack;
+
+/**
+ * The CurrentActor is a ThreadLocal wrapper that allows threads in the broker
+ * to retrieve an actor to perform logging. This approach is used so for two
+ * reasons:
+ * 1) We do not have to pass a logging actor around the system
+ * 2) We can set new actors at the point we have enough information. i.e.
+ * - Set a low level ConnectionActor when processing bytes from the wire.
+ * - Set a ChannelActor when we are processing the frame
+ * - Set a SubscriptionActor when we are handling the subscription.
+ * <p/>
+ * The code performing the logging need not worry about what type of actor is
+ * currently set so can perform its logging. The resulting log entry though will
+ * contain customised details from the the currently set Actor.
+ * <p/>
+ * The Actor model also allows the pre-creation of fixed messages so the
+ * performance impact of the additional logging data is minimised.
+ * <p/>
+ * This class does not perform any checks to ensure that there is an Actor set
+ * when calling remove or get. As a result the application developer must ensure
+ * that they have called set before they attempt to use the actor via get or
+ * remove the set actor.
+ * <p/>
+ * The checking of the return via get should not be done as the logging is
+ * desired. It is preferable to cause the NullPointerException to highlight the
+ * programming error rather than miss a log message.
+ * <p/>
+ * The same is true for the remove. A NPE will occur if no set has been called
+ * highlighting the programming error.
+ */
+public class CurrentActor
+{
+ /** The ThreadLocal variable with initialiser */
+ private static final ThreadLocal<Stack<LogActor>> _currentActor = new ThreadLocal<Stack<LogActor>>()
+ {
+ // Initialise the CurrentActor to be an empty List
+ protected Stack<LogActor> initialValue()
+ {
+ return new Stack<LogActor>();
+ }
+ };
+
+ private static LogActor _defaultActor;
+
+ /**
+ * Set a new {@link LogActor} to be the Current Actor
+ * <p/>
+ * This pushes the Actor in to the LIFO Queue
+ *
+ * @param actor The new LogActor
+ */
+ public static void set(LogActor actor)
+ {
+ Stack<LogActor> stack = _currentActor.get();
+ stack.push(actor);
+ }
+
+ /**
+ * Remove all {@link LogActor}s
+ */
+ public static void removeAll()
+ {
+ Stack<LogActor> stack = _currentActor.get();
+ stack.clear();
+ }
+
+ /**
+ * Remove the current {@link LogActor}.
+ * <p/>
+ * Calling remove without calling set will result in an EmptyStackException.
+ */
+ public static void remove()
+ {
+ Stack<LogActor> stack = _currentActor.get();
+ stack.pop();
+ }
+
+ /**
+ * Return the current head of the list of {@link LogActor}s.
+ *
+ * @return Current LogActor
+ */
+ public static LogActor get()
+ {
+ try
+ {
+ return _currentActor.get().peek();
+ }
+ catch (EmptyStackException ese)
+ {
+ return _defaultActor;
+ }
+ }
+
+ public static void setDefault(LogActor defaultActor)
+ {
+ _defaultActor = defaultActor;
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/GenericActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/GenericActor.java
new file mode 100644
index 0000000000..9afc76ce78
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/GenericActor.java
@@ -0,0 +1,85 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.server.logging.actors;
+
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+
+public class GenericActor extends AbstractActor
+{
+
+ private static RootMessageLogger _defaultMessageLogger;
+
+ private LogSubject _logSubject;
+
+ public static RootMessageLogger getDefaultMessageLogger()
+ {
+ return _defaultMessageLogger;
+ }
+
+ public static void setDefaultMessageLogger(RootMessageLogger defaultMessageLogger)
+ {
+ _defaultMessageLogger = defaultMessageLogger;
+ }
+
+ public GenericActor(LogSubject logSubject, RootMessageLogger rootLogger)
+ {
+ super(rootLogger);
+ _logSubject = logSubject;
+ }
+
+ public String getLogMessage()
+ {
+ return _logSubject.toLogString();
+ }
+
+ public static LogActor getInstance(final String logMessage, RootMessageLogger rootLogger)
+ {
+ return new GenericActor(new LogSubject()
+ {
+ public String toLogString()
+ {
+ return logMessage;
+ }
+
+ }, rootLogger);
+ }
+
+ public static LogActor getInstance(final String subjectMessage)
+ {
+ return new GenericActor(new LogSubject()
+ {
+ public String toLogString()
+ {
+ return "[" + subjectMessage + "] ";
+ }
+
+ }, _defaultMessageLogger);
+ }
+
+ public static LogActor getInstance(LogSubject logSubject)
+ {
+ return new GenericActor(logSubject, _defaultMessageLogger);
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java
new file mode 100644
index 0000000000..2825fa1b75
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java
@@ -0,0 +1,114 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.actors;
+
+import org.apache.qpid.server.logging.LogMessage;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.logging.RootMessageLogger;
+
+import java.text.MessageFormat;
+
+/**
+ * NOTE: This actor is not thread safe.
+ *
+ * Sharing of a ManagementActor instance between threads may result in an
+ * incorrect actor value being logged.
+ *
+ * This is due to the fact that calls to message will dynamically query the
+ * thread name and use that to set the log format during each message() call.
+ *
+ * This is currently not an issue as each MBean operation creates a new Actor
+ * that is unique for each operation.
+ */
+public class ManagementActor extends AbstractActor
+{
+ String _lastThreadName = null;
+
+ /**
+ * LOG FORMAT for the ManagementActor,
+ * Uses a MessageFormat call to insert the requried values according to
+ * these indicies:
+ *
+ * 0 - Connection ID
+ * 1 - User ID
+ * 2 - IP
+ */
+ public static final String MANAGEMENT_FORMAT = "mng:{0}({1})";
+
+ /**
+ * The logString to be used for logging
+ */
+ private String _logString;
+
+ /** @param rootLogger The RootLogger to use for this Actor */
+ public ManagementActor(RootMessageLogger rootLogger)
+ {
+ super(rootLogger);
+ }
+
+ private void updateLogString()
+ {
+ String currentName = Thread.currentThread().getName();
+
+ String actor;
+ // Record the last thread name so we don't have to recreate the log string
+ if (!currentName.equals(_lastThreadName))
+ {
+ _lastThreadName = currentName;
+
+ // Management Thread names have this format.
+ //RMI TCP Connection(2)-169.24.29.116
+ // This is true for both LocalAPI and JMX Connections
+ // However to be defensive lets test.
+
+ String[] split = currentName.split("\\(");
+ if (split.length == 2)
+ {
+ String connectionID = split[1].split("\\)")[0];
+ String ip = currentName.split("-")[1];
+
+ actor = MessageFormat.format(MANAGEMENT_FORMAT,
+ connectionID,
+ ip);
+ }
+ else
+ {
+ // This is a precautionary path as it is not expected to occur
+ // however rather than adjusting the thread name of the two
+ // tests that will use this it is safer all round to do this.
+ // it is also currently used by tests :
+ // AMQBrokerManagerMBeanTest
+ // ExchangeMBeanTest
+ actor = currentName;
+ }
+
+ _logString = "[" + actor + "] ";
+
+ }
+ }
+
+ public String getLogMessage()
+ {
+ updateLogString();
+ return _logString;
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/QueueActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/QueueActor.java
new file mode 100644
index 0000000000..3364365b61
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/QueueActor.java
@@ -0,0 +1,55 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.actors;
+
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.subjects.QueueLogSubject;
+import org.apache.qpid.server.queue.AMQQueue;
+
+import java.text.MessageFormat;
+
+/**
+ * This Actor is used when while the queue is performing an asynchronous process
+ * of its queue.
+ */
+public class QueueActor extends AbstractActor
+{
+ private QueueLogSubject _logSubject;
+
+ /**
+ * Create an QueueLogSubject that Logs in the following format.
+ *
+ * @param queue The queue that this Actor is working for
+ * @param rootLogger the Root logger to use.
+ */
+ public QueueActor(AMQQueue queue, RootMessageLogger rootLogger)
+ {
+ super(rootLogger);
+
+ _logSubject = new QueueLogSubject(queue);
+ }
+
+ public String getLogMessage()
+ {
+ return _logSubject.toLogString();
+ }
+}
+
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/SubscriptionActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/SubscriptionActor.java
new file mode 100644
index 0000000000..a2dbf2f6ee
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/SubscriptionActor.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.actors;
+
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.subjects.SubscriptionLogSubject;
+import org.apache.qpid.server.subscription.Subscription;
+
+/**
+ * The subscription actor provides formatted logging for actions that are
+ * performed by the subsciption. Such as STATE changes.
+ */
+public class SubscriptionActor extends AbstractActor
+{
+ private SubscriptionLogSubject _logSubject;
+
+ public SubscriptionActor(RootMessageLogger logger, Subscription subscription)
+ {
+ super(logger);
+
+ _logSubject = new SubscriptionLogSubject(subscription);
+ }
+
+ public String getLogMessage()
+ {
+ return _logSubject.toLogString();
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java
new file mode 100644
index 0000000000..a823fb7cb1
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java
@@ -0,0 +1,825 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging.management;
+
+import static org.apache.log4j.xml.QpidLog4JConfigurator.LOCK;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.apache.qpid.management.common.mbeans.LoggingManagement;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.util.FileUtils;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.xml.Log4jEntityResolver;
+import org.apache.log4j.xml.QpidLog4JConfigurator;
+import org.apache.log4j.xml.QpidLog4JConfigurator.QpidLog4JSaxErrorHandler;
+import org.apache.log4j.xml.QpidLog4JConfigurator.IllegalLoggerLevelException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import javax.management.JMException;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+
+/** MBean class for BrokerLoggingManagerMBean. It implements all the management features exposed for managing logging. */
+@MBeanDescription("Logging Management Interface")
+public class LoggingManagementMBean extends AMQManagedObject implements LoggingManagement
+{
+
+ private static final Logger _logger = Logger.getLogger(LoggingManagementMBean.class);
+ private String _log4jConfigFileName;
+ private int _log4jLogWatchInterval;
+ private static final String INHERITED = "INHERITED";
+ private static final String[] LEVELS = new String[]{Level.ALL.toString(), Level.TRACE.toString(),
+ Level.DEBUG.toString(), Level.INFO.toString(),
+ Level.WARN.toString(), Level.ERROR.toString(),
+ Level.FATAL.toString(),Level.OFF.toString(),
+ INHERITED};
+ static TabularType _loggerLevelTabularType;
+ static CompositeType _loggerLevelCompositeType;
+
+ static
+ {
+ try
+ {
+ OpenType[] loggerLevelItemTypes = new OpenType[]{SimpleType.STRING, SimpleType.STRING};
+
+ _loggerLevelCompositeType = new CompositeType("LoggerLevelList", "Logger Level Data",
+ COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]),
+ COMPOSITE_ITEM_DESCRIPTIONS.toArray(new String[COMPOSITE_ITEM_DESCRIPTIONS.size()]),
+ loggerLevelItemTypes);
+
+ _loggerLevelTabularType = new TabularType("LoggerLevel", "List of loggers with levels",
+ _loggerLevelCompositeType,
+ TABULAR_UNIQUE_INDEX.toArray(new String[TABULAR_UNIQUE_INDEX.size()]));
+ }
+ catch (OpenDataException e)
+ {
+ _logger.error("Tabular data setup for viewing logger levels was incorrect.");
+ _loggerLevelTabularType = null;
+ }
+ }
+
+ public LoggingManagementMBean(String log4jConfigFileName, int log4jLogWatchInterval) throws JMException
+ {
+ super(LoggingManagement.class, LoggingManagement.TYPE);
+ _log4jConfigFileName = log4jConfigFileName;
+ _log4jLogWatchInterval = log4jLogWatchInterval;
+ }
+
+ public String getObjectInstanceName()
+ {
+ return LoggingManagement.TYPE;
+ }
+
+ public Integer getLog4jLogWatchInterval()
+ {
+ return _log4jLogWatchInterval;
+ }
+
+ public String[] getAvailableLoggerLevels()
+ {
+ return LEVELS;
+ }
+ @SuppressWarnings("unchecked")
+ public synchronized boolean setRuntimeLoggerLevel(String logger, String level)
+ {
+ //check specified level is valid
+ Level newLevel;
+ try
+ {
+ newLevel = getLevel(level);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+
+ //check specified logger exists
+ Enumeration loggers = LogManager.getCurrentLoggers();
+ Boolean loggerExists = false;
+
+ while(loggers.hasMoreElements())
+ {
+ Logger log = (Logger) loggers.nextElement();
+ if (log.getName().equals(logger))
+ {
+ loggerExists = true;
+ break;
+ }
+ }
+
+ if(!loggerExists)
+ {
+ return false;
+ }
+
+ //set the logger to the new level
+ _logger.info("Setting level to " + level + " for logger: " + logger);
+
+ Logger log = Logger.getLogger(logger);
+ log.setLevel(newLevel);
+
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public synchronized TabularData viewEffectiveRuntimeLoggerLevels()
+ {
+ if (_loggerLevelTabularType == null)
+ {
+ _logger.warn("TabluarData type not set up correctly");
+ return null;
+ }
+
+ _logger.info("Getting levels for currently active log4j loggers");
+
+ Enumeration loggers = LogManager.getCurrentLoggers();
+
+ TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType);
+
+ Logger logger;
+ String loggerName;
+ String level;
+
+ try
+ {
+ while(loggers.hasMoreElements()){
+ logger = (Logger) loggers.nextElement();
+
+ loggerName = logger.getName();
+ level = logger.getEffectiveLevel().toString();
+
+ Object[] itemData = {loggerName, level};
+ CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType,
+ COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), itemData);
+ loggerLevelList.put(loggerData);
+ }
+ }
+ catch (OpenDataException e)
+ {
+ _logger.warn("Unable to create logger level list due to :" + e);
+ return null;
+ }
+
+ return loggerLevelList;
+
+ }
+
+ public synchronized String getRuntimeRootLoggerLevel()
+ {
+ Logger rootLogger = Logger.getRootLogger();
+
+ return rootLogger.getLevel().toString();
+ }
+
+ public synchronized boolean setRuntimeRootLoggerLevel(String level)
+ {
+ Level newLevel;
+ try
+ {
+ newLevel = getLevel(level);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+
+ if(newLevel == null)
+ {
+ //A null Level reference implies inheritance. Setting the runtime RootLogger
+ //to null is catastrophic (and prevented by Log4J at startup and runtime anyway).
+ return false;
+ }
+
+ _logger.info("Setting RootLogger level to " + level);
+
+ Logger log = Logger.getRootLogger();
+ log.setLevel(newLevel);
+
+ return true;
+ }
+
+ //method to convert from a string to a log4j Level, throws exception if the given value is invalid
+ private Level getLevel(String level) throws Exception
+ {
+ if("null".equalsIgnoreCase(level) || INHERITED.equalsIgnoreCase(level))
+ {
+ //the string "null" or "inherited" signals to inherit from a parent logger,
+ //using a null Level reference for the logger.
+ return null;
+ }
+
+ Level newLevel = Level.toLevel(level);
+
+ //above Level.toLevel call returns a DEBUG Level if the request fails. Check the result.
+ if (newLevel.equals(Level.DEBUG) && !(level.equalsIgnoreCase("debug")))
+ {
+ //received DEBUG but we did not ask for it, the Level request failed.
+ throw new Exception("Invalid level name");
+ }
+
+ return newLevel;
+ }
+
+ //method to parse the XML configuration file, validating it in the process, and returning a DOM Document of the content.
+ private static synchronized Document parseConfigFile(String fileName) throws IOException
+ {
+ try
+ {
+ LOCK.lock();
+
+ //check file was specified, exists, and is readable
+ if(fileName == null)
+ {
+ _logger.warn("Provided log4j XML configuration filename is null");
+ throw new IOException("Provided log4j XML configuration filename is null");
+ }
+
+ File configFile = new File(fileName);
+
+ if (!configFile.exists())
+ {
+ _logger.warn("The log4j XML configuration file could not be found: " + fileName);
+ throw new IOException("The log4j XML configuration file could not be found");
+ }
+ else if (!configFile.canRead())
+ {
+ _logger.warn("The log4j XML configuration file is not readable: " + fileName);
+ throw new IOException("The log4j XML configuration file is not readable");
+ }
+
+ //parse it
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder;
+ Document doc;
+
+ ErrorHandler errHandler = new QpidLog4JSaxErrorHandler();
+ try
+ {
+ docFactory.setValidating(true);
+ docBuilder = docFactory.newDocumentBuilder();
+ docBuilder.setErrorHandler(errHandler);
+ docBuilder.setEntityResolver(new Log4jEntityResolver());
+ doc = docBuilder.parse(fileName);
+ }
+ catch (ParserConfigurationException e)
+ {
+ _logger.warn("Unable to parse the log4j XML file due to possible configuration error: " + e);
+ //recommended that MBeans should use java.* and javax.* exceptions only
+ throw new IOException("Unable to parse the log4j XML file due to possible configuration error: " + e.getMessage());
+ }
+ catch (SAXException e)
+ {
+ _logger.warn("The specified log4j XML file is invalid: " + e);
+ //recommended that MBeans should use standard java.* and javax.* exceptions only
+ throw new IOException("The specified log4j XML file is invalid: " + e.getMessage());
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Unable to parse the specified log4j XML file" + e);
+ throw new IOException("Unable to parse the specified log4j XML file: " + e.getMessage());
+ }
+
+ return doc;
+ }
+ finally
+ {
+ LOCK.unlock();
+ }
+ }
+
+
+ private static synchronized boolean writeUpdatedConfigFile(String log4jConfigFileName, Document doc) throws IOException
+ {
+ try
+ {
+ LOCK.lock();
+
+ File log4jConfigFile = new File(log4jConfigFileName);
+
+ if (!log4jConfigFile.canWrite())
+ {
+ _logger.warn("Specified log4j XML configuration file is not writable: " + log4jConfigFile);
+ throw new IOException("Specified log4j XML configuration file is not writable");
+ }
+
+ Transformer transformer = null;
+ try
+ {
+ transformer = TransformerFactory.newInstance().newTransformer();
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Could not create an XML transformer: " +e);
+ return false;
+ }
+
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "log4j.dtd");
+ DOMSource source = new DOMSource(doc);
+
+ File tmp;
+ Random r = new Random();
+ do
+ {
+ tmp = new File(log4jConfigFile.getPath() + r.nextInt() + ".tmp");
+ }
+ while(tmp.exists());
+
+ tmp.deleteOnExit();
+
+ try
+ {
+ StreamResult result = new StreamResult(tmp);
+ transformer.transform(source, result);
+ }
+ catch (TransformerException e)
+ {
+ _logger.warn("Could not transform the XML into new file: " +e);
+ throw new IOException("Could not transform the XML into new file: " +e);
+ }
+
+ // Swap temp file in to replace existing configuration file.
+ File old = new File(log4jConfigFile.getAbsoluteFile() + ".old");
+ if (old.exists())
+ {
+ old.delete();
+ }
+
+ if(!log4jConfigFile.renameTo(old))
+ {
+ //unable to rename the existing file to the backup name
+ _logger.error("Could not backup the existing log4j XML file");
+ throw new IOException("Could not backup the existing log4j XML file");
+ }
+
+ if(!tmp.renameTo(log4jConfigFile))
+ {
+ //failed to rename the new file to the required filename
+
+ if(!old.renameTo(log4jConfigFile))
+ {
+ //unable to return the backup to required filename
+ _logger.error("Could not rename the new log4j configuration file into place, and unable to restore original file");
+ throw new IOException("Could not rename the new log4j configuration file into place, and unable to restore original file");
+ }
+
+ _logger.error("Could not rename the new log4j configuration file into place");
+ throw new IOException("Could not rename the new log4j configuration file into place");
+ }
+
+ return true;
+ }
+ finally
+ {
+ LOCK.unlock();
+ }
+ }
+
+
+ /* The log4j XML configuration file DTD defines three possible element
+ * combinations for specifying optional logger+level settings.
+ * Must account for the following:
+ *
+ * <category name="x"> <priority value="y"/> </category> OR
+ * <category name="x"> <level value="y"/> </category> OR
+ * <logger name="x"> <level value="y"/> </logger>
+ *
+ * Noting also that the level/priority child element is optional too,
+ * and not the only possible child element.
+ */
+
+ public static synchronized Map<String,String> retrieveConfigFileLoggersLevels(String fileName) throws IOException
+ {
+ try
+ {
+ LOCK.lock();
+
+ Document doc = parseConfigFile(fileName);
+
+ HashMap<String,String> loggerLevelList = new HashMap<String,String>();
+
+ //retrieve the 'category' element nodes
+ NodeList categoryElements = doc.getElementsByTagName("category");
+
+ String categoryName;
+ String priority = null;
+
+ for (int i = 0; i < categoryElements.getLength(); i++)
+ {
+ Element categoryElement = (Element) categoryElements.item(i);
+ categoryName = categoryElement.getAttribute("name");
+
+ //retrieve the category's mandatory 'priority' or 'level' element's value.
+ //It may not be the only child node, so request by tag name.
+ NodeList priorityElements = categoryElement.getElementsByTagName("priority");
+ NodeList levelElements = categoryElement.getElementsByTagName("level");
+
+ if (priorityElements.getLength() != 0)
+ {
+ Element priorityElement = (Element) priorityElements.item(0);
+ priority = priorityElement.getAttribute("value");
+ }
+ else if (levelElements.getLength() != 0)
+ {
+ Element levelElement = (Element) levelElements.item(0);
+ priority = levelElement.getAttribute("value");
+ }
+ else
+ {
+ //there is no exiting priority or level to view, move onto next category/logger
+ continue;
+ }
+
+ loggerLevelList.put(categoryName, priority);
+ }
+
+ //retrieve the 'logger' element nodes
+ NodeList loggerElements = doc.getElementsByTagName("logger");
+
+ String loggerName;
+ String level;
+
+ for (int i = 0; i < loggerElements.getLength(); i++)
+ {
+ Element loggerElement = (Element) loggerElements.item(i);
+ loggerName = loggerElement.getAttribute("name");
+
+ //retrieve the logger's mandatory 'level' element's value
+ //It may not be the only child node, so request by tag name.
+ NodeList levelElements = loggerElement.getElementsByTagName("level");
+
+ Element levelElement = (Element) levelElements.item(0);
+ level = levelElement.getAttribute("value");
+
+ loggerLevelList.put(loggerName, level);
+ }
+
+ return loggerLevelList;
+ }
+ finally
+ {
+ LOCK.unlock();
+ }
+ }
+
+ public synchronized TabularData viewConfigFileLoggerLevels() throws IOException
+ {
+ try
+ {
+ LOCK.lock();
+
+ if (_loggerLevelTabularType == null)
+ {
+ _logger.warn("TabluarData type not set up correctly");
+ return null;
+ }
+
+ _logger.info("Getting logger levels from log4j configuration file");
+
+ TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType);
+
+ Map<String,String> levels = retrieveConfigFileLoggersLevels(_log4jConfigFileName);
+
+ for (Map.Entry<String,String> entry : levels.entrySet())
+ {
+ String loggerName = entry.getKey();
+ String level = entry.getValue();
+
+ try
+ {
+ Object[] itemData = {loggerName, level.toUpperCase()};
+ CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType,
+ COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), itemData);
+ loggerLevelList.put(loggerData);
+ }
+ catch (OpenDataException e)
+ {
+ _logger.warn("Unable to create logger level list due to :" + e);
+ return null;
+ }
+ }
+
+ return loggerLevelList;
+ }
+ finally
+ {
+ LOCK.unlock();
+ }
+ }
+
+ public synchronized boolean setConfigFileLoggerLevel(String logger, String level) throws IOException
+ {
+ try
+ {
+ LOCK.lock();
+
+ //check that the specified level is a valid log4j Level
+ try
+ {
+ getLevel(level);
+ }
+ catch (Exception e)
+ {
+ //it isnt a valid level
+ return false;
+ }
+
+ _logger.info("Setting level to " + level + " for logger '" + logger
+ + "' in log4j xml configuration file: " + _log4jConfigFileName);
+
+ Document doc = parseConfigFile(_log4jConfigFileName);
+
+ //retrieve the 'category' and 'logger' element nodes
+ NodeList categoryElements = doc.getElementsByTagName("category");
+ NodeList loggerElements = doc.getElementsByTagName("logger");
+
+ //collect them into a single elements list
+ List<Element> logElements = new ArrayList<Element>();
+
+ for (int i = 0; i < categoryElements.getLength(); i++)
+ {
+ logElements.add((Element) categoryElements.item(i));
+ }
+ for (int i = 0; i < loggerElements.getLength(); i++)
+ {
+ logElements.add((Element) loggerElements.item(i));
+ }
+
+ //try to locate the specified logger/category in the elements retrieved
+ Element logElement = null;
+ for (Element e : logElements)
+ {
+ if (e.getAttribute("name").equals(logger))
+ {
+ logElement = e;
+ break;
+ }
+ }
+
+ if (logElement == null)
+ {
+ //no loggers/categories with given name found, does not exist to update
+ _logger.warn("Specified logger does not exist in the configuration file: " +logger);
+ return false;
+ }
+
+ //retrieve the optional 'priority' or 'level' sub-element value.
+ //It may not be the only child node, so request by tag name.
+ NodeList priorityElements = logElement.getElementsByTagName("priority");
+ NodeList levelElements = logElement.getElementsByTagName("level");
+
+ Element levelElement = null;
+ if (priorityElements.getLength() != 0)
+ {
+ levelElement = (Element) priorityElements.item(0);
+ }
+ else if (levelElements.getLength() != 0)
+ {
+ levelElement = (Element) levelElements.item(0);
+ }
+ else
+ {
+ //there is no exiting priority or level element to update
+ return false;
+ }
+
+ //update the element with the new level/priority
+ levelElement.setAttribute("value", level.toLowerCase());
+
+ //output the new file
+ return writeUpdatedConfigFile(_log4jConfigFileName, doc);
+ }
+ finally
+ {
+ LOCK.unlock();
+ }
+ }
+
+
+ /* The log4j XML configuration file DTD defines 2 possible element
+ * combinations for specifying the optional root logger level settings
+ * Must account for the following:
+ *
+ * <root> <priority value="y"/> </root> OR
+ * <root> <level value="y"/> </root>
+ *
+ * Noting also that the level/priority child element is optional too,
+ * and not the only possible child element.
+ */
+
+ public static synchronized String retrieveConfigFileRootLoggerLevel(String fileName) throws IOException
+ {
+ try
+ {
+ LOCK.lock();
+
+ Document doc = parseConfigFile(fileName);
+
+ //retrieve the optional 'root' element node
+ NodeList rootElements = doc.getElementsByTagName("root");
+
+ if (rootElements.getLength() == 0)
+ {
+ //there is no root logger definition
+ return "N/A";
+ }
+
+ Element rootElement = (Element) rootElements.item(0);
+
+ //retrieve the optional 'priority' or 'level' element value.
+ //It may not be the only child node, so request by tag name.
+ NodeList priorityElements = rootElement.getElementsByTagName("priority");
+ NodeList levelElements = rootElement.getElementsByTagName("level");
+ String priority = null;
+
+ if (priorityElements.getLength() != 0)
+ {
+ Element priorityElement = (Element) priorityElements.item(0);
+ priority = priorityElement.getAttribute("value");
+ }
+ else if(levelElements.getLength() != 0)
+ {
+ Element levelElement = (Element) levelElements.item(0);
+ priority = levelElement.getAttribute("value");
+ }
+
+ if(priority != null)
+ {
+ return priority;
+ }
+ else
+ {
+ return "N/A";
+ }
+ }
+ finally
+ {
+ LOCK.unlock();
+ }
+ }
+
+ public synchronized String getConfigFileRootLoggerLevel() throws IOException
+ {
+ return retrieveConfigFileRootLoggerLevel(_log4jConfigFileName).toUpperCase();
+ }
+
+ public synchronized boolean setConfigFileRootLoggerLevel(String level) throws IOException
+ {
+ try
+ {
+ LOCK.lock();
+
+ //check that the specified level is a valid log4j Level
+ try
+ {
+ Level newLevel = getLevel(level);
+ if(newLevel == null)
+ {
+ //A null Level reference implies inheritance. Setting the config file RootLogger
+ //to "null" or "inherited" just ensures it defaults to DEBUG at startup as Log4J
+ //prevents this catastrophic situation at startup and runtime anyway.
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ //it isnt a valid level
+ return false;
+ }
+
+ _logger.info("Setting level to " + level + " for the Root logger in " +
+ "log4j xml configuration file: " + _log4jConfigFileName);
+
+ Document doc = parseConfigFile(_log4jConfigFileName);
+
+ //retrieve the optional 'root' element node
+ NodeList rootElements = doc.getElementsByTagName("root");
+
+ if (rootElements.getLength() == 0)
+ {
+ return false;
+ }
+
+ Element rootElement = (Element) rootElements.item(0);
+
+ //retrieve the optional 'priority' or 'level' sub-element value.
+ //It may not be the only child node, so request by tag name.
+ NodeList priorityElements = rootElement.getElementsByTagName("priority");
+ NodeList levelElements = rootElement.getElementsByTagName("level");
+
+ Element levelElement = null;
+ if (priorityElements.getLength() != 0)
+ {
+ levelElement = (Element) priorityElements.item(0);
+ }
+ else if (levelElements.getLength() != 0)
+ {
+ levelElement = (Element) levelElements.item(0);
+ }
+ else
+ {
+ //there is no exiting priority/level to update
+ return false;
+ }
+
+ //update the element with the new level/priority
+ levelElement.setAttribute("value", level);
+
+ //output the new file
+ return writeUpdatedConfigFile(_log4jConfigFileName, doc);
+ }
+ finally
+ {
+ LOCK.unlock();
+ }
+ }
+
+ public synchronized void reloadConfigFile() throws IOException
+ {
+ try
+ {
+ LOCK.lock();
+
+ QpidLog4JConfigurator.configure(_log4jConfigFileName);
+ _logger.info("Applied log4j configuration from: " + _log4jConfigFileName);
+ }
+ catch (IllegalLoggerLevelException e)
+ {
+ _logger.warn("The log4j configuration reload request was aborted: " + e);
+ //recommended that MBeans should use standard java.* and javax.* exceptions only
+ throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
+ }
+ catch (ParserConfigurationException e)
+ {
+ _logger.warn("The log4j configuration reload request was aborted: " + e);
+ throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
+ }
+ catch (SAXException e)
+ {
+ _logger.warn("The log4j configuration reload request was aborted: " + e);
+ //recommended that MBeans should use standard java.* and javax.* exceptions only
+ throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
+ }
+ catch (IOException e)
+ {
+ _logger.warn("The log4j configuration reload request was aborted: " + e);
+ throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
+ }
+ finally
+ {
+ LOCK.unlock();
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Binding_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Binding_logmessages.properties
new file mode 100644
index 0000000000..808ec7918f
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Binding_logmessages.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+#
+CREATED = BND-1001 : Create[ : Arguments : {0}]
+DELETED = BND-1002 : Deleted
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties
new file mode 100644
index 0000000000..5d1e85fe41
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties
@@ -0,0 +1,38 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+
+# 0 - Version
+# 1 = Build
+STARTUP = BRK-1001 : Startup : Version: {0} Build: {1}
+# 0 - Transport
+# 1 - Port
+LISTENING = BRK-1002 : Starting : Listening on {0} port {1,number,#}
+# 0 - Transport
+# 1 - Port
+SHUTTING_DOWN = BRK-1003 : Shuting down : {0} port {1,number,#}
+READY = BRK-1004 : Qpid Broker Ready
+STOPPED = BRK-1005 : Stopped
+# 0 - path
+CONFIG = BRK-1006 : Using configuration : {0}
+# 0 - path
+LOG_CONFIG = BRK-1007 : Using logging configuration : {0}
+
+STATS_DATA = BRK-1008 : {0,choice,0#delivered|1#received} : {1,number,#.###} kB/s peak : {2,number,#} bytes total
+STATS_MSGS = BRK-1009 : {0,choice,0#delivered|1#received} : {1,number,#.###} msg/s peak : {2,number,#} msgs total \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties
new file mode 100644
index 0000000000..ed8c0d0ce9
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties
@@ -0,0 +1,34 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+
+CREATE = CHN-1001 : Create
+# 0 - flow
+FLOW = CHN-1002 : Flow {0}
+CLOSE = CHN-1003 : Close
+# 0 - bytes allowed in prefetch
+# 1 - number of messagse.
+PREFETCH_SIZE = CHN-1004 : Prefetch Size (bytes) {0,number} : Count {1,number}
+# 0 - queue causing flow control
+FLOW_ENFORCED = CHN-1005 : Flow Control Enforced (Queue {0})
+FLOW_REMOVED = CHN-1006 : Flow Control Removed
+# Channel Transactions
+# 0 - time in milliseconds
+OPEN_TXN = CHN-1007 : Open Transaction : {0,number} ms
+IDLE_TXN = CHN-1008 : Idle Transaction : {0,number} ms
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ConfigStore_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ConfigStore_logmessages.properties
new file mode 100644
index 0000000000..3bc5074777
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ConfigStore_logmessages.properties
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+
+# 0 - name
+CREATED = CFG-1001 : Created : {0}
+# 0 - path
+STORE_LOCATION = CFG-1002 : Store location : {0}
+CLOSE = CFG-1003 : Closed
+RECOVERY_START = CFG-1004 : Recovery Start
+RECOVERY_COMPLETE = CFG-1005 : Recovery Complete
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Connection_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Connection_logmessages.properties
new file mode 100644
index 0000000000..81ae6f3bd0
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Connection_logmessages.properties
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+
+# 0 - Client id
+# 1 - Protocol Version
+OPEN = CON-1001 : Open[ : Client ID : {0}][ : Protocol Version : {1}]
+CLOSE = CON-1002 : Close \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Exchange_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Exchange_logmessages.properties
new file mode 100644
index 0000000000..b9890d9f27
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Exchange_logmessages.properties
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+
+# 0 - type
+# 1 - name
+CREATED = EXH-1001 : Create :[ Durable] Type: {0} Name: {1}
+DELETED = EXH-1002 : Deleted \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties
new file mode 100644
index 0000000000..ab77476da2
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+#
+STARTUP = MNG-1001 : Startup
+# 0 - Service
+# 1 - Port
+LISTENING = MNG-1002 : Starting : {0} : Listening on port {1,number,#}
+# 0 - Service
+# 1 - Port
+SHUTTING_DOWN = MNG-1003 : Shutting down : {0} : port {1,number,#}
+READY = MNG-1004 : Ready[ : Using the platform JMX Agent]
+STOPPED = MNG-1005 : Stopped
+# 0 - Path
+SSL_KEYSTORE = MNG-1006 : Using SSL Keystore : {0}
+OPEN = MNG-1007 : Open : User {0}
+CLOSE = MNG-1008 : Close \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/MessageStore_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/MessageStore_logmessages.properties
new file mode 100644
index 0000000000..a2cedeb22a
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/MessageStore_logmessages.properties
@@ -0,0 +1,28 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+#
+# 0 - name
+CREATED = MST-1001 : Created : {0}
+# 0 - path
+STORE_LOCATION = MST-1002 : Store location : {0}
+CLOSED = MST-1003 : Closed
+RECOVERY_START = MST-1004 : Recovery Start
+RECOVERED = MST-1005 : Recovered {0,number} messages
+RECOVERY_COMPLETE = MST-1006 : Recovery Complete \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Queue_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Queue_logmessages.properties
new file mode 100644
index 0000000000..538bf994ea
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Queue_logmessages.properties
@@ -0,0 +1,26 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+#
+# 0 - owner
+# 1 - priority
+CREATED = QUE-1001 : Create :[ Owner: {0}][ AutoDelete][ Durable][ Transient][ Priority: {1,number,#}]
+DELETED = QUE-1002 : Deleted
+OVERFULL = QUE-1003 : Overfull : Size : {0,number} bytes, Capacity : {1,number}
+UNDERFULL = QUE-1004 : Underfull : Size : {0,number} bytes, Resume Capacity : {1,number}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Subscription_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Subscription_logmessages.properties
new file mode 100644
index 0000000000..ef5f885b50
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Subscription_logmessages.properties
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+#
+CREATE = SUB-1001 : Create[ : Durable][ : Arguments : {0}]
+CLOSE = SUB-1002 : Close
+# 0 - The current subscription state
+STATE = SUB-1003 : State : {0} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/TransactionLog_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/TransactionLog_logmessages.properties
new file mode 100644
index 0000000000..fadc2e2098
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/TransactionLog_logmessages.properties
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+#
+#
+# 0 - name
+CREATED = TXN-1001 : Created : {0}
+# 0 - path
+STORE_LOCATION = TXN-1002 : Store location : {0}
+CLOSED = TXN-1003 : Closed
+# 0 - queue name
+RECOVERY_START = TXN-1004 : Recovery Start[ : {0}]
+# 0 - count
+# 1 - queue count
+RECOVERED = TXN-1005 : Recovered {0,number} messages for queue {1}
+# 0 - queue name
+RECOVERY_COMPLETE = TXN-1006 : Recovery Complete[ : {0}]
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
new file mode 100644
index 0000000000..3e640c7929
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
@@ -0,0 +1,26 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Default File used for all non-defined locales.
+#
+# 0 - name
+CREATED = VHT-1001 : Created : {0}
+CLOSED = VHT-1002 : Closed
+
+STATS_DATA = VHT-1003 : {0} : {1,choice,0#delivered|1#received} : {2,number,#.###} kB/s peak : {3,number,#} bytes total
+STATS_MSGS = VHT-1004 : {0} : {1,choice,0#delivered|1#received} : {2,number,#.###} msg/s peak : {3,number,#} msgs total` \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/AbstractLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/AbstractLogSubject.java
new file mode 100644
index 0000000000..779db01601
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/AbstractLogSubject.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.subjects;
+
+import org.apache.qpid.server.logging.LogSubject;
+
+import java.text.MessageFormat;
+
+/**
+ * The LogSubjects all have a similar requriement to format their output and
+ * provide the String value.
+ *
+ * This Abstract LogSubject provides this basic functionality, allowing the
+ * actual LogSubjects to provide their formating and data.
+ */
+public abstract class AbstractLogSubject implements LogSubject
+{
+ /**
+ * The logString that will be returned via toLogString
+ */
+ protected String _logString;
+
+ /**
+ * Set the toString logging of this LogSubject. Based on a format provided
+ * by format and the var args.
+ * @param format The Message to format
+ * @param args The values to put in to the message.
+ */
+ protected void setLogStringWithFormat(String format, Object... args)
+ {
+ _logString = "[" + MessageFormat.format(format, args) + "] ";
+ }
+
+ /**
+ * toLogString is how the Logging infrastructure will get the text for this
+ * LogSubject
+ *
+ * @return String representing this LogSubject
+ */
+ public String toLogString()
+ {
+ return _logString;
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java
new file mode 100644
index 0000000000..088b59ae68
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java
@@ -0,0 +1,49 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.subjects;
+
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.AMQQueue;
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.BINDING_FORMAT;
+
+public class BindingLogSubject extends AbstractLogSubject
+{
+
+ /**
+ * Create a BindingLogSubject that Logs in the following format.
+ *
+ * [ vh(/)/ex(amq.direct)/qu(testQueue)/bd(testQueue) ]
+ *
+ * @param routingKey
+ * @param exchange
+ * @param queue
+ */
+ public BindingLogSubject(String routingKey, Exchange exchange,
+ AMQQueue queue)
+ {
+ setLogStringWithFormat(BINDING_FORMAT, queue.getVirtualHost().getName(),
+ exchange.getTypeShortString(),
+ exchange.getNameShortString(),
+ queue.getNameShortString(),
+ routingKey);
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
new file mode 100644
index 0000000000..f28873940b
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
@@ -0,0 +1,56 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.subjects;
+
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_FORMAT;
+
+public class ChannelLogSubject extends AbstractLogSubject
+{
+
+ public ChannelLogSubject(AMQChannel channel)
+ {
+ AMQProtocolSession session = channel.getProtocolSession();
+
+ /**
+ * LOG FORMAT used by the AMQPConnectorActor follows
+ * ChannelLogSubject.CHANNEL_FORMAT :
+ * con:{0}({1}@{2}/{3})/ch:{4}
+ *
+ * Uses a MessageFormat call to insert the required values according to
+ * these indices:
+ *
+ * 0 - Connection ID
+ * 1 - User ID
+ * 2 - IP
+ * 3 - Virtualhost
+ * 4 - Channel ID
+ */
+ setLogStringWithFormat(CHANNEL_FORMAT,
+ session.getSessionID(),
+ session.getPrincipal().getName(),
+ session.getRemoteAddress(),
+ session.getVirtualHost().getName(),
+ channel.getChannelId());
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java
new file mode 100644
index 0000000000..a697029d24
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java
@@ -0,0 +1,107 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.subjects;
+
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+
+import java.text.MessageFormat;
+
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SOCKET_FORMAT;
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.USER_FORMAT;
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTION_FORMAT;
+
+/** The Connection LogSubject */
+public class ConnectionLogSubject extends AbstractLogSubject
+{
+
+ public ConnectionLogSubject(AMQProtocolSession session)
+ {
+ _session = session;
+ }
+
+ // The Session this Actor is representing
+ private AMQProtocolSession _session;
+
+ // Used to stop re-creating the _logString when we reach our final format
+ private boolean _upToDate = false;
+
+ /**
+ * Update the LogString as the Connection process proceeds.
+ *
+ * When the Session has an authorized ID add that to the string.
+ *
+ * When the Session then gains a Vhost add that to the string, at this point
+ * we can set upToDate = true as the _logString will not need to be updated
+ * from this point onwards.
+ */
+ private void updateLogString()
+ {
+ if (!_upToDate)
+ {
+ if (_session.getPrincipal() != null)
+ {
+ if (_session.getVirtualHost() != null)
+ {
+ /**
+ * LOG FORMAT used by the AMQPConnectorActor follows
+ * ConnectionLogSubject.CONNECTION_FORMAT :
+ * con:{0}({1}@{2}/{3})
+ *
+ * Uses a MessageFormat call to insert the required values
+ * according to these indices:
+ *
+ * 0 - Connection ID 1 - User ID 2 - IP 3 - Virtualhost
+ */
+ _logString = "[" + MessageFormat.format(CONNECTION_FORMAT,
+ _session.getSessionID(),
+ _session.getPrincipal().getName(),
+ _session.getRemoteAddress(),
+ _session.getVirtualHost().getName())
+ + "] ";
+
+ _upToDate = true;
+ }
+ else
+ {
+ _logString = "[" + MessageFormat.format(USER_FORMAT,
+ _session.getSessionID(),
+ _session.getPrincipal().getName(),
+ _session.getRemoteAddress())
+ + "] ";
+
+ }
+ }
+ else
+ {
+ _logString = "[" + MessageFormat.format(SOCKET_FORMAT,
+ _session.getSessionID(),
+ _session.getRemoteAddress())
+ + "] ";
+ }
+ }
+ }
+
+ public String toLogString()
+ {
+ updateLogString();
+ return super.toLogString();
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java
new file mode 100644
index 0000000000..6ab44a92b9
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.subjects;
+
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.EXCHANGE_FORMAT;
+
+public class ExchangeLogSubject extends AbstractLogSubject
+{
+
+ /** Create an ExchangeLogSubject that Logs in the following format. */
+ public ExchangeLogSubject(Exchange exchange, VirtualHost vhost)
+ {
+ setLogStringWithFormat(EXCHANGE_FORMAT, vhost.getName(),
+ exchange.getTypeShortString(), exchange.getNameShortString());
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java
new file mode 100644
index 0000000000..ff2bb90140
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java
@@ -0,0 +1,107 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.server.logging.subjects;
+
+/**
+ * LogSubjectFormat class contains a list of formatting string
+ * that can be statically imported where needed.
+ * The formatting strings are to be used via a MessageFormat call
+ * to insert the required values at the corresponding place holder
+ * indices.
+ *
+ */
+
+public class LogSubjectFormat
+{
+
+ /**
+ * LOG FORMAT for the Subscription Log Subject
+ * 0 - Subscription ID
+ */
+ public static final String SUBSCRIPTION_FORMAT = "sub:{0}";
+
+ /**
+ * LOG FORMAT for Connection Log Subject - SOCKET format
+ * 0 - Connection ID
+ * 1 - Remote Address
+ */
+ public static final String SOCKET_FORMAT = "con:{0}({1})";
+
+ /**
+ * LOG FORMAT for Connection Log Subject - USER format
+ * 0 - Connection ID
+ * 1 - User ID
+ * 2 - IP
+ */
+ public static final String USER_FORMAT = "con:{0}({1}@{2})";
+
+ /**
+ * LOG FORMAT for the Connection Log Subject - CON format
+ * 0 - Connection ID
+ * 1 - User ID
+ * 2 - IP
+ * 3 - Virtualhost
+ */
+ public static final String CONNECTION_FORMAT = "con:{0}({1}@{2}/{3})";
+
+ /**
+ * LOG FORMAT for the Channel LogSubject
+ * 0 - Connection ID
+ * 1 - User ID
+ * 2 - IP
+ * 3 - Virtualhost
+ * 4 - Channel ID
+ */
+ public static final String CHANNEL_FORMAT = CONNECTION_FORMAT + "/ch:{4}";
+
+ /**
+ * LOG FORMAT for the Exchange LogSubject,
+ * 0 - Virtualhost Name
+ * 1 - Exchange Type
+ * 2 - Exchange Name
+ */
+ public static final String EXCHANGE_FORMAT = "vh(/{0})/ex({1}/{2})";
+
+ /**
+ * LOG FORMAT for a Binding LogSubject
+ * 0 - Virtualhost Name
+ * 1 - Exchange Type
+ * 2 - Exchange Name
+ * 3 - Queue Name
+ * 4 - Binding RoutingKey
+ */
+ public static final String BINDING_FORMAT = "vh(/{0})/ex({1}/{2})/qu({3})/rk({4})";
+
+ /**
+ * LOG FORMAT for the MessagesStore LogSubject
+ * 0 - Virtualhost Name
+ * 1 - Message Store Type
+ */
+ public static final String STORE_FORMAT = "vh(/{0})/ms({1})";
+
+ /**
+ * LOG FORMAT for the Queue LogSubject,
+ * 0 - Virtualhost name
+ * 1 - queue name
+ */
+ public static final String QUEUE_FORMAT = "vh(/{0})/qu({1})";
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubject.java
new file mode 100644
index 0000000000..3fce13bcb5
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubject.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.subjects;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.store.MessageStore;
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.STORE_FORMAT;
+
+public class MessageStoreLogSubject extends AbstractLogSubject
+{
+
+ /** Create an ExchangeLogSubject that Logs in the following format. */
+ public MessageStoreLogSubject(VirtualHost vhost, MessageStore store)
+ {
+ setLogStringWithFormat(STORE_FORMAT, vhost.getName(),
+ store.getClass().getSimpleName());
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java
new file mode 100644
index 0000000000..bfe12f1a60
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.subjects;
+
+import org.apache.qpid.server.queue.AMQQueue;
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.QUEUE_FORMAT;
+
+public class QueueLogSubject extends AbstractLogSubject
+{
+
+ /** Create an QueueLogSubject that Logs in the following format. */
+ public QueueLogSubject(AMQQueue queue)
+ {
+ setLogStringWithFormat(QUEUE_FORMAT,
+ queue.getVirtualHost().getName(),
+ queue.getName());
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubject.java
new file mode 100644
index 0000000000..8b57647046
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubject.java
@@ -0,0 +1,55 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.subjects;
+
+import org.apache.qpid.server.subscription.Subscription;
+
+import java.text.MessageFormat;
+
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SUBSCRIPTION_FORMAT;
+
+public class SubscriptionLogSubject extends AbstractLogSubject
+{
+
+ /**
+ * Create an QueueLogSubject that Logs in the following format.
+ *
+ * @param subscription
+ */
+ public SubscriptionLogSubject(Subscription subscription)
+ {
+ // Delegate the formating of the Queue to the QueueLogSubject. So final
+ // log string format is:
+ // [ sub:<id>(vh(<vhost>)/qu(<queue>)) ]
+
+ String queueString = new QueueLogSubject(subscription.getQueue()).toLogString();
+
+ _logString = "[" + MessageFormat.format(SUBSCRIPTION_FORMAT,
+ subscription.getSubscriptionID())
+ + "("
+ // queueString is [vh(/{0})/qu({1}) ] so need to trim
+ // ^ ^^
+ + queueString.substring(1,queueString.length() - 3)
+ + ")"
+ + "] ";
+
+ }
+}