You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ph...@apache.org on 2013/07/09 16:03:45 UTC

svn commit: r1501276 - in /qpid/proton/trunk: proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/ proton-j/ proton-j/proton-api/ proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/ proton-j/proton-api/src/main/java/org/...

Author: philharveyonline
Date: Tue Jul  9 14:03:44 2013
New Revision: 1501276

URL: http://svn.apache.org/r1501276
Log:
PROTON-343: initial implementation of logging, including the central class ProtonLogger
and category logger implementations for java.util.logging (the default), standard out and SLF4J.
Still to do:
- Implementations in proton-jni and proton-c
- Define the full set of logging functions in EngineLogger et al.
- Modify existing Proton classes to actually use the new logging classes.

Added:
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineLogger.java
      - copied, changed from r1501274, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/CategoryAwareProtonLogger.java
      - copied, changed from r1501274, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/CategoryLoggerDiscovery.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/JULCategoryLogger.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonCategoryLogger.java
      - copied, changed from r1501274, qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonLogLevel.java
      - copied, changed from r1501274, qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonLogger.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/SLF4JCategoryLogger.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/StdOutCategoryLogger.java
      - copied, changed from r1501274, qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/logging/
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/logging/CategoryLoggerDiscoveryTest.java
    qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/EngineFactoryImplTest.java
      - copied, changed from r1501274, qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java
    qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/logging/
    qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/logging/LoggingCustomisationTest.java
Modified:
    qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNIConnection.java
    qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNIEngineFactory.java
    qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNITransport.java
    qpid/proton/trunk/proton-j/pom.xml
    qpid/proton/trunk/proton-j/proton-api/pom.xml
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Connection.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Transport.java
    qpid/proton/trunk/proton-j/proton/pom.xml
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ConnectionImpl.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/EngineFactoryImpl.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportImpl.java

Modified: qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNIConnection.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNIConnection.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNIConnection.java (original)
+++ qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNIConnection.java Tue Jul  9 14:03:44 2013
@@ -34,6 +34,7 @@ import org.apache.qpid.proton.codec.jni.
 import org.apache.qpid.proton.engine.Connection;
 import org.apache.qpid.proton.engine.Delivery;
 import org.apache.qpid.proton.engine.EndpointState;
+import org.apache.qpid.proton.engine.EngineLogger;
 import org.apache.qpid.proton.engine.Link;
 import org.apache.qpid.proton.engine.Session;
 import org.apache.qpid.proton.jni.Proton;
@@ -307,4 +308,15 @@ public class JNIConnection implements Co
     {
         throw new ProtonUnsupportedOperationException();
     }
+
+    public EngineLogger getEngineLogger()
+    {
+        //TODO: implement
+        return null;
+    }
+
+    public void setEngineLogger(EngineLogger engineLogger)
+    {
+        //TODO: implement
+    }
 }

Modified: qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNIEngineFactory.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNIEngineFactory.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNIEngineFactory.java (original)
+++ qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNIEngineFactory.java Tue Jul  9 14:03:44 2013
@@ -21,6 +21,7 @@ package org.apache.qpid.proton.engine.jn
 import org.apache.qpid.proton.ProtonCEquivalent;
 import org.apache.qpid.proton.engine.Connection;
 import org.apache.qpid.proton.engine.EngineFactory;
+import org.apache.qpid.proton.engine.EngineLogger;
 import org.apache.qpid.proton.engine.SslDomain;
 import org.apache.qpid.proton.engine.SslPeerDetails;
 import org.apache.qpid.proton.engine.Transport;
@@ -67,4 +68,14 @@ public class JNIEngineFactory extends JN
         };
     }
 
+    public EngineLogger getEngineLogger()
+    {
+        //TODO: implement
+        return null;
+    }
+
+    public void setEngineLogger(EngineLogger engineLogger)
+    {
+        //TODO: implement
+    }
 }

Modified: qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNITransport.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNITransport.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNITransport.java (original)
+++ qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/engine/jni/JNITransport.java Tue Jul  9 14:03:44 2013
@@ -377,4 +377,15 @@ public class JNITransport implements Tra
         free();
         super.finalize();
     }
+
+    public EngineLogger getEngineLogger()
+    {
+        //TODO: implement
+        return null;
+    }
+
+    public void setEngineLogger(EngineLogger engineLogger)
+    {
+        //TODO: implement
+    }
 }

Modified: qpid/proton/trunk/proton-j/pom.xml
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/pom.xml?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/pom.xml (original)
+++ qpid/proton/trunk/proton-j/pom.xml Tue Jul  9 14:03:44 2013
@@ -34,6 +34,12 @@
       <version>${junit-version}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <version>1.9.5</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <modules>

Modified: qpid/proton/trunk/proton-j/proton-api/pom.xml
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/pom.xml?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/pom.xml (original)
+++ qpid/proton/trunk/proton-j/proton-api/pom.xml Tue Jul  9 14:03:44 2013
@@ -29,4 +29,14 @@
     <url>http://svn.apache.org/viewvc/qpid/proton/</url>
   </scm>
 
+  <dependencies>
+    <dependency>
+      <!-- used to build SLF4JCategoryLogger, but marked 'optional' so application code does
+           not require it (unless it explicitly chooses to use the SLF4JCategoryLogger) -->
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>1.7.5</version>
+      <optional>true</optional>
+    </dependency>
+  </dependencies>
 </project>

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Connection.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Connection.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Connection.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Connection.java Tue Jul  9 14:03:44 2013
@@ -95,4 +95,7 @@ public interface Connection extends Endp
     Map<Symbol,Object> getRemoteProperties();
 
     void setProperties(Map<Symbol,Object> properties);
+
+    EngineLogger getEngineLogger();
+    void setEngineLogger(EngineLogger engineLogger);
 }

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java Tue Jul  9 14:03:44 2013
@@ -26,4 +26,11 @@ public interface EngineFactory extends P
     Transport createTransport();
     SslDomain createSslDomain();
     SslPeerDetails createSslPeerDetails(String hostname, int port);
+
+    /**
+     * Sets the engine logger used by all Engine objects subsequently
+     * created by this factory.
+     */
+    void setEngineLogger(EngineLogger logger);
+    EngineLogger getEngineLogger();
 }

Copied: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineLogger.java (from r1501274, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineLogger.java?p2=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineLogger.java&p1=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java&r1=1501274&r2=1501276&rev=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineLogger.java Tue Jul  9 14:03:44 2013
@@ -18,12 +18,14 @@
  */
 package org.apache.qpid.proton.engine;
 
-import org.apache.qpid.proton.ProtonFactory;
+import java.nio.ByteBuffer;
 
-public interface EngineFactory extends ProtonFactory
+import org.apache.qpid.proton.amqp.transport.FrameBody;
+
+// TODO add MessengerLogger, DriverLogger interfaces etc that follow the same pattern
+public interface EngineLogger
 {
-    Connection createConnection();
-    Transport createTransport();
-    SslDomain createSslDomain();
-    SslPeerDetails createSslPeerDetails(String hostname, int port);
+    // TODO add more methods for bytes, frames etc
+
+    void outgoingBytes(int channel, FrameBody frameBody, ByteBuffer payload);
 }

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Transport.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Transport.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Transport.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Transport.java Tue Jul  9 14:03:44 2013
@@ -173,4 +173,7 @@ public interface Transport extends Endpo
     int getMaxFrameSize();
 
     void setMaxFrameSize(int size);
+
+    EngineLogger getEngineLogger();
+    void setEngineLogger(EngineLogger engineLogger);
 }

Copied: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/CategoryAwareProtonLogger.java (from r1501274, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/CategoryAwareProtonLogger.java?p2=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/CategoryAwareProtonLogger.java&p1=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java&r1=1501274&r2=1501276&rev=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/CategoryAwareProtonLogger.java Tue Jul  9 14:03:44 2013
@@ -16,14 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.qpid.proton.engine;
+package org.apache.qpid.proton.logging;
 
-import org.apache.qpid.proton.ProtonFactory;
-
-public interface EngineFactory extends ProtonFactory
+/**
+ * A Proton logger that delegates the logging of strings to a {@link ProtonCategoryLogger}.
+ */
+public interface CategoryAwareProtonLogger
 {
-    Connection createConnection();
-    Transport createTransport();
-    SslDomain createSslDomain();
-    SslPeerDetails createSslPeerDetails(String hostname, int port);
+    ProtonCategoryLogger getCategoryLogger();
+    void setCategoryLogger(ProtonCategoryLogger logger);
 }

Added: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/CategoryLoggerDiscovery.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/CategoryLoggerDiscovery.java?rev=1501276&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/CategoryLoggerDiscovery.java (added)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/CategoryLoggerDiscovery.java Tue Jul  9 14:03:44 2013
@@ -0,0 +1,116 @@
+/*
+ * 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.proton.logging;
+
+/**
+ * Returns a {@link ProtonCategoryLogger} based on the built-in default, a statically overridden one,
+ * or an instance specific one (in that order).
+ *
+ * Thread-safe.
+ */
+class CategoryLoggerDiscovery
+{
+    public static final String PROTON_DEFAULT_CATEGORY_LOGGER_PROP = "proton.default_category_logger";
+    public static final String PROTON_CATEGORY_LOGGER_JUL = "JUL";
+    public static final String PROTON_CATEGORY_LOGGER_SLF4J = "SLF4J";
+    public static final String PROTON_CATEGORY_LOGGER_STDOUT = "STDOUT";
+
+    private static final ProtonCategoryLogger DEFAULT_LOGGER;
+    static
+    {
+        String loggerType = System.getProperty(PROTON_DEFAULT_CATEGORY_LOGGER_PROP, PROTON_CATEGORY_LOGGER_JUL);
+        if(PROTON_CATEGORY_LOGGER_JUL.equals(loggerType))
+        {
+            DEFAULT_LOGGER = new JULCategoryLogger();
+        }
+        else if(PROTON_CATEGORY_LOGGER_SLF4J.equals(loggerType))
+        {
+            DEFAULT_LOGGER = new SLF4JCategoryLogger();
+        }
+        else if(PROTON_CATEGORY_LOGGER_STDOUT.equals(loggerType))
+        {
+            DEFAULT_LOGGER = new StdOutCategoryLogger();
+        }
+        else
+        {
+            try
+            {
+                Class<?> clazz = Class.forName(loggerType);
+                if(!ProtonCategoryLogger.class.isAssignableFrom(clazz))
+                {
+                    throw new IllegalArgumentException("Provided class name must be a " +
+                                                       ProtonCategoryLogger.class.getName() + ": " + loggerType);
+                }
+
+                Object obj = clazz.newInstance();
+                DEFAULT_LOGGER = (ProtonCategoryLogger) obj;
+            }
+            catch (ClassNotFoundException e)
+            {
+                throw new RuntimeException(e);
+            }
+            catch (InstantiationException e)
+            {
+                throw new RuntimeException(e);
+            }
+            catch (IllegalAccessException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private static volatile ProtonCategoryLogger _overriddenDefaultLogger = null;
+
+    private volatile ProtonCategoryLogger _logger = null;
+
+    static void setDefault(ProtonCategoryLogger defaultDelegate)
+    {
+        _overriddenDefaultLogger = defaultDelegate;
+    }
+
+    void setLogger(ProtonCategoryLogger logger)
+    {
+        _logger = logger;
+    }
+
+    static ProtonCategoryLogger getEffectiveDefaultLogger()
+    {
+        if(_overriddenDefaultLogger != null)
+        {
+            return _overriddenDefaultLogger;
+        }
+        else
+        {
+            return DEFAULT_LOGGER;
+        }
+    }
+
+    ProtonCategoryLogger getEffectiveLogger()
+    {
+        if(_logger != null)
+        {
+            return _logger;
+        }
+        else
+        {
+            return getEffectiveDefaultLogger();
+        }
+    }
+}

Added: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/JULCategoryLogger.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/JULCategoryLogger.java?rev=1501276&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/JULCategoryLogger.java (added)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/JULCategoryLogger.java Tue Jul  9 14:03:44 2013
@@ -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.proton.logging;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * Uses java.util.logging
+ */
+public class JULCategoryLogger implements ProtonCategoryLogger
+{
+    private static final Map<ProtonLogLevel, Level> _protonLevelsToJavaLevels = new HashMap<ProtonLogLevel, Level>();
+    static
+    {
+        _protonLevelsToJavaLevels.put(ProtonLogLevel.TRACE, Level.FINER);
+        _protonLevelsToJavaLevels.put(ProtonLogLevel.DEBUG, Level.FINE);
+        _protonLevelsToJavaLevels.put(ProtonLogLevel.INFO, Level.INFO);
+        _protonLevelsToJavaLevels.put(ProtonLogLevel.WARN, Level.WARNING);
+        _protonLevelsToJavaLevels.put(ProtonLogLevel.ERROR, Level.SEVERE);
+    }
+
+    @Override
+    public boolean isEnabled(String category, ProtonLogLevel level)
+    {
+        Level julLevel = _protonLevelsToJavaLevels.get(level);
+        return Logger.getLogger(category).isLoggable(julLevel);
+    }
+
+    @Override
+    public void log(String category, ProtonLogLevel level, String message)
+    {
+        Level julLevel = _protonLevelsToJavaLevels.get(level);
+        Logger.getLogger(category).log(julLevel, message);
+    }
+}

Copied: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonCategoryLogger.java (from r1501274, qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonCategoryLogger.java?p2=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonCategoryLogger.java&p1=qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java&r1=1501274&r2=1501276&rev=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonCategoryLogger.java Tue Jul  9 14:03:44 2013
@@ -1,5 +1,4 @@
 /*
- *
  * 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
@@ -16,17 +15,18 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
-package org.apache.qpid.proton.engine.impl;
-
-import org.apache.qpid.proton.framing.TransportFrame;
+package org.apache.qpid.proton.logging;
 
 /**
- * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ * A Service Provider Interface (SPI) that logs strings.
+ *
+ * Deemed an SPI because Proton's clients may implement it but only Proton's internals should ever
+ * invoke it.
  */
-public interface ProtocolTracer
+public interface ProtonCategoryLogger
 {
-    public void receivedFrame(TransportFrame transportFrame);
-    public void sentFrame(TransportFrame transportFrame);
+    boolean isEnabled(String category, ProtonLogLevel level);
+
+    void log(String category, ProtonLogLevel level, String message);
 }

Copied: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonLogLevel.java (from r1501274, qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonLogLevel.java?p2=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonLogLevel.java&p1=qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java&r1=1501274&r2=1501276&rev=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonLogLevel.java Tue Jul  9 14:03:44 2013
@@ -1,5 +1,4 @@
 /*
- *
  * 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
@@ -16,17 +15,29 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
-package org.apache.qpid.proton.engine.impl;
-
-import org.apache.qpid.proton.framing.TransportFrame;
+package org.apache.qpid.proton.logging;
 
 /**
- * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ * The level of a log message
  */
-public interface ProtocolTracer
+public enum ProtonLogLevel
 {
-    public void receivedFrame(TransportFrame transportFrame);
-    public void sentFrame(TransportFrame transportFrame);
+    /** potentially byte-by-byte output */
+    TRACE,
+
+    DEBUG,
+
+    /** Typical example: a normal lifecycle event has occurred on an endpoint */
+    INFO,
+
+    /** May indicate a problem */
+    WARN,
+
+    /**
+     * Indicates a problem which is either (1) invalid input or (2) a Proton internal error.
+     */
+    ERROR,
+
+    ;
 }

Added: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonLogger.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonLogger.java?rev=1501276&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonLogger.java (added)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/ProtonLogger.java Tue Jul  9 14:03:44 2013
@@ -0,0 +1,97 @@
+/*
+ * 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.proton.logging;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.proton.amqp.transport.FrameBody;
+import org.apache.qpid.proton.engine.EngineLogger;
+
+/**
+ * An Engine Logger that delegates to a {@link ProtonCategoryLogger}.
+ *
+ * Thread-safe.
+ *
+ * The default {@link ProtonCategoryLogger} can be controlled using the system property
+ * {@value org.apache.qpid.proton.logging.CategoryLoggerDiscovery#PROTON_DEFAULT_CATEGORY_LOGGER_PROP}, specifying the class name
+ * of a particular implementation to use. Additionally, convenience values can be used for the following:
+ *
+ * <ul>
+ *  <li>{@value org.apache.qpid.proton.logging.CategoryLoggerDiscovery#PROTON_CATEGORY_LOGGER_JUL} : java.util.logging</li>
+ *  <li>{@value org.apache.qpid.proton.logging.CategoryLoggerDiscovery#PROTON_CATEGORY_LOGGER_SLF4J} : SLF4J</li>
+ *  <li>{@value org.apache.qpid.proton.logging.CategoryLoggerDiscovery#PROTON_CATEGORY_LOGGER_STDOUT} : StdOut</li>
+ * </ul>
+ */
+public class ProtonLogger implements EngineLogger, CategoryAwareProtonLogger
+{
+    private static final String BYTES_OUT_CATEGORY = "proton.bytes.out";
+
+    private final CategoryLoggerDiscovery _categoryLoggerDiscovery = new CategoryLoggerDiscovery();
+
+    public static ProtonCategoryLogger getDefaultCategoryLogger()
+    {
+        return CategoryLoggerDiscovery.getEffectiveDefaultLogger();
+    }
+
+    /**
+     * Sets the default category logger, or restores it to the built-in default if
+     * the supplied logger is null.
+     */
+    public static void setDefaultCategoryLogger(ProtonCategoryLogger categoryLogger)
+    {
+        CategoryLoggerDiscovery.setDefault(categoryLogger);
+    }
+
+    /**
+     * Constructor that uses the default {@link ProtonCategoryLogger}.
+     */
+    public ProtonLogger()
+    {
+    }
+
+    public ProtonLogger(ProtonCategoryLogger categoryLogger)
+    {
+        setCategoryLogger(categoryLogger);
+    }
+
+    @Override
+    public void outgoingBytes(int channel, FrameBody frameBody, ByteBuffer payload)
+    {
+        ProtonCategoryLogger logger = _categoryLoggerDiscovery.getEffectiveLogger();
+        if(logger.isEnabled(BYTES_OUT_CATEGORY, ProtonLogLevel.TRACE))
+        {
+            logger.log(
+                    BYTES_OUT_CATEGORY,
+                    ProtonLogLevel.TRACE,
+                    "PHTODO generate outgoingBytes message from " + frameBody);
+        }
+    }
+
+    @Override
+    public ProtonCategoryLogger getCategoryLogger()
+    {
+        return _categoryLoggerDiscovery.getEffectiveLogger();
+    }
+
+    @Override
+    public void setCategoryLogger(ProtonCategoryLogger logger)
+    {
+        _categoryLoggerDiscovery.setLogger(logger);
+    }
+}

Added: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/SLF4JCategoryLogger.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/SLF4JCategoryLogger.java?rev=1501276&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/SLF4JCategoryLogger.java (added)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/SLF4JCategoryLogger.java Tue Jul  9 14:03:44 2013
@@ -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.proton.logging;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SLF4JCategoryLogger implements ProtonCategoryLogger
+{
+    @Override
+    public boolean isEnabled(String category, ProtonLogLevel level)
+    {
+        Logger logger = LoggerFactory.getLogger(category);
+
+        switch(level)
+        {
+            case TRACE:
+                return logger.isTraceEnabled();
+            case DEBUG:
+                return logger.isDebugEnabled();
+            case INFO:
+                return logger.isInfoEnabled();
+            case WARN:
+                return logger.isWarnEnabled();
+            case ERROR:
+                return logger.isErrorEnabled();
+            default:
+                throw new RuntimeException("Unsupported log level: " + level);
+        }
+    }
+
+    @Override
+    public void log(String category, ProtonLogLevel level, String message)
+    {
+        Logger logger = LoggerFactory.getLogger(category);
+
+        switch(level)
+        {
+            case TRACE:
+                logger.trace(message);
+                break;
+            case DEBUG:
+                logger.debug(message);
+                break;
+            case INFO:
+                logger.info(message);
+                break;
+            case WARN:
+                logger.warn(message);
+                break;
+            case ERROR:
+                logger.error(message);
+                break;
+            default:
+                throw new RuntimeException("Unsupported log level: " + level);
+        }
+    }
+}

Copied: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/StdOutCategoryLogger.java (from r1501274, qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/StdOutCategoryLogger.java?p2=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/StdOutCategoryLogger.java&p1=qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java&r1=1501274&r2=1501276&rev=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/logging/StdOutCategoryLogger.java Tue Jul  9 14:03:44 2013
@@ -1,5 +1,4 @@
 /*
- *
  * 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
@@ -16,25 +15,24 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
-package org.apache.qpid.proton.engine.impl;
+package org.apache.qpid.proton.logging;
 
-import org.apache.qpid.proton.engine.Connection;
-import org.apache.qpid.proton.engine.Transport;
+import java.util.Date;
 
-class TransportFactoryImpl extends TransportFactory
+public class StdOutCategoryLogger implements ProtonCategoryLogger
 {
-    TransportFactoryImpl()
+
+    @Override
+    public boolean isEnabled(String category, ProtonLogLevel level)
     {
+        return true;
     }
 
-    @SuppressWarnings("deprecation") // TODO remove once the constructor is made non-public (and therefore non-deprecated)
-    public Transport transport(Connection c)
+    @Override
+    public void log(String category, ProtonLogLevel level, String message)
     {
-        TransportImpl t = new TransportImpl();
-        t.bind(c);
-        return t;
+        System.out.println(String.format("%1$tF %1$tT.%tL [%s] [%s] %s",
+                                         new Date(), level, category, message));
     }
-
 }

Added: qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/logging/CategoryLoggerDiscoveryTest.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/logging/CategoryLoggerDiscoveryTest.java?rev=1501276&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/logging/CategoryLoggerDiscoveryTest.java (added)
+++ qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/logging/CategoryLoggerDiscoveryTest.java Tue Jul  9 14:03:44 2013
@@ -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.proton.logging;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+
+public class CategoryLoggerDiscoveryTest
+{
+    private final CategoryLoggerDiscovery _discovery = new CategoryLoggerDiscovery();
+
+    @Test
+    public void testDefaultLogger_isJavaUtilLogging()
+    {
+        assertThat(_discovery.getEffectiveLogger(), is(JULCategoryLogger.class));
+    }
+
+    @Test
+    public void testSetDefaultDelegateBeforeCreatingLogger()
+    {
+        ProtonCategoryLogger categoryLogger = mock(ProtonCategoryLogger.class);
+        CategoryLoggerDiscovery.setDefault(categoryLogger);
+
+        assertSame(categoryLogger, (new CategoryLoggerDiscovery()).getEffectiveLogger());
+    }
+
+    @Test
+    public void testSetDefaultDelegateAfterCreatingLogger()
+    {
+        ProtonCategoryLogger categoryLogger = mock(ProtonCategoryLogger.class);
+        CategoryLoggerDiscovery.setDefault(categoryLogger);
+
+        assertSame(categoryLogger, _discovery.getEffectiveLogger());
+    }
+
+    @Test
+    public void testSetDelegate_takesPrecedenceOverDefault()
+    {
+        ProtonCategoryLogger delegate = mock(ProtonCategoryLogger.class);
+        _discovery.setLogger(delegate);
+
+        CategoryLoggerDiscovery.setDefault(mock(ProtonCategoryLogger.class));
+
+        assertSame(delegate, _discovery.getEffectiveLogger());
+    }
+}

Modified: qpid/proton/trunk/proton-j/proton/pom.xml
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/pom.xml?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/pom.xml (original)
+++ qpid/proton/trunk/proton-j/proton/pom.xml Tue Jul  9 14:03:44 2013
@@ -58,13 +58,6 @@
       <artifactId>bcpkix-jdk15on</artifactId>
       <version>1.47</version>
     </dependency>
-
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-      <version>1.9.5</version>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 
   <scm>

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ConnectionImpl.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ConnectionImpl.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ConnectionImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ConnectionImpl.java Tue Jul  9 14:03:44 2013
@@ -27,12 +27,13 @@ import java.util.List;
 import java.util.Map;
 import org.apache.qpid.proton.amqp.Symbol;
 import org.apache.qpid.proton.engine.*;
+import org.apache.qpid.proton.logging.ProtonLogger;
 import org.apache.qpid.proton.amqp.transport.Open;
 
 public class ConnectionImpl extends EndpointImpl implements ProtonJConnection
 {
-
     public static final int MAX_CHANNELS = 255;
+
     private List<SessionImpl> _sessions = new ArrayList<SessionImpl>();
     private EndpointImpl _transportTail;
     private EndpointImpl _transportHead;
@@ -63,14 +64,23 @@ public class ConnectionImpl extends Endp
     private Map<Symbol, Object> _properties;
     private Map<Symbol, Object> _remoteProperties;
 
+    private EngineLogger _engineLogger;
+
     private static final Symbol[] EMPTY_SYMBOL_ARRAY = new Symbol[0];
 
     /**
      * @deprecated This constructor's visibility will be reduced to the default scope in a future release.
+     * Intended to only be used by tests.
      * Client code outside this module should use a {@link EngineFactory} instead
      */
     @Deprecated public ConnectionImpl()
     {
+        _engineLogger = new ProtonLogger();
+    }
+
+    ConnectionImpl(EngineLogger engineLogger)
+    {
+        _engineLogger = engineLogger;
     }
 
     public SessionImpl session()
@@ -513,4 +523,15 @@ public class ConnectionImpl extends Endp
             }
         }
     }
+
+    @Override
+    public EngineLogger getEngineLogger()
+    {
+        return _engineLogger;
+    }
+
+    public void setEngineLogger(EngineLogger engineLogger)
+    {
+        _engineLogger = engineLogger;
+    }
 }

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/EngineFactoryImpl.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/EngineFactoryImpl.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/EngineFactoryImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/EngineFactoryImpl.java Tue Jul  9 14:03:44 2013
@@ -20,27 +20,31 @@ package org.apache.qpid.proton.engine.im
 
 import org.apache.qpid.proton.ProtonFactoryImpl;
 import org.apache.qpid.proton.engine.EngineFactory;
+import org.apache.qpid.proton.engine.EngineLogger;
 import org.apache.qpid.proton.engine.ProtonJConnection;
 import org.apache.qpid.proton.engine.ProtonJSslDomain;
 import org.apache.qpid.proton.engine.ProtonJSslPeerDetails;
 import org.apache.qpid.proton.engine.ProtonJTransport;
 import org.apache.qpid.proton.engine.impl.ssl.SslDomainImpl;
 import org.apache.qpid.proton.engine.impl.ssl.SslPeerDetailsImpl;
+import org.apache.qpid.proton.logging.ProtonLogger;
 
 public class EngineFactoryImpl extends ProtonFactoryImpl implements EngineFactory
 {
+    private EngineLogger _logger = new ProtonLogger();
+
     @SuppressWarnings("deprecation") // TODO remove once the constructor is made non-public (and therefore non-deprecated)
     @Override
     public ProtonJConnection createConnection()
     {
-        return new ConnectionImpl();
+        return new ConnectionImpl(_logger);
     }
 
     @SuppressWarnings("deprecation") // TODO remove once the constructor is made non-public (and therefore non-deprecated)
     @Override
     public ProtonJTransport createTransport()
     {
-        return new TransportImpl();
+        return new TransportImpl(_logger);
     }
 
     @SuppressWarnings("deprecation") // TODO remove once the constructor is made non-public (and therefore non-deprecated)
@@ -57,4 +61,19 @@ public class EngineFactoryImpl extends P
         return new SslPeerDetailsImpl(hostname, port);
     }
 
+    @Override
+    public void setEngineLogger(EngineLogger logger)
+    {
+        if(logger == null)
+        {
+            throw new NullPointerException();
+        }
+        _logger = logger;
+    }
+
+    @Override
+    public EngineLogger getEngineLogger()
+    {
+        return _logger;
+    }
 }

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ProtocolTracer.java Tue Jul  9 14:03:44 2013
@@ -20,11 +20,15 @@
  */
 package org.apache.qpid.proton.engine.impl;
 
+import org.apache.qpid.proton.engine.EngineLogger;
 import org.apache.qpid.proton.framing.TransportFrame;
 
 /**
  * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ *
+ * @deprecated superseded by {@link EngineLogger}. TODO replace uses of this class with an EngineLogger instead.
  */
+@Deprecated
 public interface ProtocolTracer
 {
     public void receivedFrame(TransportFrame transportFrame);

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java Tue Jul  9 14:03:44 2013
@@ -29,10 +29,11 @@ class TransportFactoryImpl extends Trans
     {
     }
 
+    @Override
     @SuppressWarnings("deprecation") // TODO remove once the constructor is made non-public (and therefore non-deprecated)
     public Transport transport(Connection c)
     {
-        TransportImpl t = new TransportImpl();
+        TransportImpl t = new TransportImpl(c.getEngineLogger());
         t.bind(c);
         return t;
     }

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportImpl.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportImpl.java?rev=1501276&r1=1501275&r2=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportImpl.java Tue Jul  9 14:03:44 2013
@@ -49,6 +49,7 @@ import org.apache.qpid.proton.codec.Writ
 import org.apache.qpid.proton.engine.Connection;
 import org.apache.qpid.proton.engine.EndpointState;
 import org.apache.qpid.proton.engine.EngineFactory;
+import org.apache.qpid.proton.engine.EngineLogger;
 import org.apache.qpid.proton.engine.ProtonJTransport;
 import org.apache.qpid.proton.engine.Sasl;
 import org.apache.qpid.proton.engine.Ssl;
@@ -61,6 +62,7 @@ import org.apache.qpid.proton.engine.Tra
 import org.apache.qpid.proton.engine.impl.ssl.ProtonSslEngineProvider;
 import org.apache.qpid.proton.engine.impl.ssl.SslImpl;
 import org.apache.qpid.proton.framing.TransportFrame;
+import org.apache.qpid.proton.logging.ProtonLogger;
 
 public class TransportImpl extends EndpointImpl
     implements ProtonJTransport, FrameBody.FrameBodyHandler<Integer>,
@@ -105,27 +107,47 @@ public class TransportImpl extends Endpo
 
     private boolean _init;
 
+    private EngineLogger _engineLogger;
+
     /**
      * @deprecated This constructor's visibility will be reduced to the default scope in a future release.
      * Client code outside this module should use a {@link EngineFactory} instead
      */
-    @Deprecated public TransportImpl()
+    @Deprecated public TransportImpl(EngineLogger engineLogger)
     {
-        this(DEFAULT_MAX_FRAME_SIZE);
+        this(engineLogger, DEFAULT_MAX_FRAME_SIZE);
     }
 
+
     /**
      * Creates a transport with the given maximum frame size.
      * Note that the maximumFrameSize also determines the size of the output buffer.
      */
-    TransportImpl(int maxFrameSize)
+    TransportImpl(EngineLogger engineLogger, int maxFrameSize)
     {
         AMQPDefinedTypes.registerAllTypes(_decoder, _encoder);
 
+        _engineLogger = engineLogger;
         _maxFrameSize = maxFrameSize;
 
     }
 
+    /**
+     * This constructor is intended to only be used by tests because it uses a hard-coded logger implementation
+     */
+    TransportImpl()
+    {
+        this(new ProtonLogger());
+    }
+
+    /**
+     * This constructor is intended to only be used by tests because it uses a hard-coded logger implementation
+     */
+    TransportImpl(int maxFrameSize)
+    {
+        this(new ProtonLogger(), maxFrameSize);
+    }
+
     private void init()
     {
         if(!_init)
@@ -138,11 +160,13 @@ public class TransportImpl extends Endpo
         }
     }
 
+    @Override
     public int getMaxFrameSize()
     {
         return _maxFrameSize;
     }
 
+    @Override
     public void setMaxFrameSize(int maxFrameSize)
     {
         if(_init)
@@ -896,6 +920,7 @@ public class TransportImpl extends Endpo
             }
             _protocolTracer.sentFrame(new TransportFrame(channel, frameBody, Binary.create(originalPayload)));
         }
+        _engineLogger.outgoingBytes(channel, frameBody, payload);
 
         int payloadSize = Math.min(payload == null ? 0 : payload.remaining(), _maxFrameSize - (buffer.position() - oldPosition));
         if(payloadSize > 0)
@@ -1240,4 +1265,16 @@ public class TransportImpl extends Endpo
             _transfer.setMore(true);
         }
     }
+
+    @Override
+    public EngineLogger getEngineLogger()
+    {
+        return _engineLogger;
+    }
+
+    @Override
+    public void setEngineLogger(EngineLogger engineLogger)
+    {
+        _engineLogger = engineLogger;
+    }
 }

Copied: qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/EngineFactoryImplTest.java (from r1501274, qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/EngineFactoryImplTest.java?p2=qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/EngineFactoryImplTest.java&p1=qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java&r1=1501274&r2=1501276&rev=1501276&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/TransportFactoryImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/EngineFactoryImplTest.java Tue Jul  9 14:03:44 2013
@@ -1,5 +1,4 @@
 /*
- *
  * 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
@@ -16,25 +15,43 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
 package org.apache.qpid.proton.engine.impl;
 
-import org.apache.qpid.proton.engine.Connection;
-import org.apache.qpid.proton.engine.Transport;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.mock;
 
-class TransportFactoryImpl extends TransportFactory
+import org.apache.qpid.proton.engine.EngineFactory;
+import org.apache.qpid.proton.engine.EngineLogger;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EngineFactoryImplTest
 {
-    TransportFactoryImpl()
+    private final EngineLogger _engineLogger = mock(EngineLogger.class);
+
+    private final EngineFactory _engineFactory = new EngineFactoryImpl();
+
+    @Before
+    public void setUp()
     {
+        _engineFactory.setEngineLogger(_engineLogger);
     }
 
-    @SuppressWarnings("deprecation") // TODO remove once the constructor is made non-public (and therefore non-deprecated)
-    public Transport transport(Connection c)
+    @Test
+    public void testCreateConnection_usesLogger()
     {
-        TransportImpl t = new TransportImpl();
-        t.bind(c);
-        return t;
+
+        assertSame(
+                _engineLogger,
+                _engineFactory.createConnection().getEngineLogger());
     }
 
+    @Test
+    public void testCreateTransport_usesLogger()
+    {
+        assertSame(
+                _engineLogger,
+                _engineFactory.createTransport().getEngineLogger());
+    }
 }

Added: qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/logging/LoggingCustomisationTest.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/logging/LoggingCustomisationTest.java?rev=1501276&view=auto
==============================================================================
--- qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/logging/LoggingCustomisationTest.java (added)
+++ qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/logging/LoggingCustomisationTest.java Tue Jul  9 14:03:44 2013
@@ -0,0 +1,117 @@
+/*
+ * 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.proton.systemtests.logging;
+
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.containsString;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.proton.amqp.transport.Open;
+import org.apache.qpid.proton.engine.Connection;
+import org.apache.qpid.proton.engine.EngineFactory;
+import org.apache.qpid.proton.logging.CategoryAwareProtonLogger;
+import org.apache.qpid.proton.logging.JULCategoryLogger;
+import org.apache.qpid.proton.logging.ProtonCategoryLogger;
+import org.apache.qpid.proton.logging.ProtonLogLevel;
+import org.apache.qpid.proton.logging.ProtonLogger;
+import org.apache.qpid.proton.systemtests.engine.ProtonFactoryTestFixture;
+import org.hamcrest.CoreMatchers;
+import org.junit.After;
+import org.junit.Ignore;
+import org.junit.Test;
+
+@Ignore("TODO reinstate test once proton-jni supports logging") // TODO reinstate test
+public class LoggingCustomisationTest
+{
+    private EngineFactory _engineFactory = new ProtonFactoryTestFixture().getFactory1();
+    private final RememberingLogger _customCategoryLogger = new RememberingLogger();
+
+    @After
+    public void restoreDefaultCategoryLogger()
+    {
+        ProtonLogger.setDefaultCategoryLogger(null);
+    }
+
+    @Test
+    public void testDefaultCategoryLoggerUsesJavaUtilLogging()
+    {
+        CategoryAwareProtonLogger engineLogger = (CategoryAwareProtonLogger)_engineFactory.getEngineLogger();
+        assertThat(engineLogger.getCategoryLogger(), is(JULCategoryLogger.class));
+    }
+
+    @Test
+    public void testConfigureNewEngineLoggerWithCustomCategoryLogger()
+    {
+        // 1. Application code configures the factory's EngineLogger to use a custom category logger
+
+        ProtonLogger engineLogger = new ProtonLogger(_customCategoryLogger);
+        _engineFactory.setEngineLogger(engineLogger);
+
+        // 2. Application code invokes Engine methods, causing logging to occur
+        // (for convenience, this test just directly invokes the logger)
+
+        Connection connection = _engineFactory.createConnection();
+        assertSame(engineLogger, connection.getEngineLogger());
+        engineLogger.outgoingBytes(0, new Open(), ByteBuffer.allocate(0));
+
+        assertThat(_customCategoryLogger._message, containsString("Open"));
+        assertThat(_customCategoryLogger._category, CoreMatchers.notNullValue());
+    }
+
+    @Test
+    public void testConfigureSystemWideDefaultCategoryLogger()
+    {
+        ProtonLogger.setDefaultCategoryLogger(_customCategoryLogger);
+        Connection connection = _engineFactory.createConnection();
+        CategoryAwareProtonLogger engineLogger = (CategoryAwareProtonLogger) connection.getEngineLogger();
+        assertSame(_customCategoryLogger, engineLogger.getCategoryLogger());
+    }
+
+    @Test
+    public void testConfigureEngineLoggerPerConnection()
+    {
+        Connection connection = _engineFactory.createConnection();
+        ProtonLogger loggerForThisConnection = new ProtonLogger();
+        connection.setEngineLogger(loggerForThisConnection);
+        assertSame(loggerForThisConnection, connection.getEngineLogger());
+    }
+
+    private class RememberingLogger implements ProtonCategoryLogger
+    {
+        private String _category;
+        private String _message;
+
+        @Override
+        public void log(String category, ProtonLogLevel level, String message)
+        {
+            _category = category;
+            _message = message;
+        }
+
+        @Override
+        public boolean isEnabled(String category, ProtonLogLevel level)
+        {
+            return true;
+        }
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org