You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2009/08/12 22:06:07 UTC

svn commit: r803688 - in /cxf/trunk: api/src/main/java/org/apache/cxf/annotations/ rt/core/src/main/java/org/apache/cxf/feature/ rt/core/src/main/java/org/apache/cxf/interceptor/ rt/core/src/main/java/org/apache/cxf/service/factory/ systests/src/test/j...

Author: dkulp
Date: Wed Aug 12 20:06:07 2009
New Revision: 803688

URL: http://svn.apache.org/viewvc?rev=803688&view=rev
Log:
Add a logging annotation
Add ability to log to stderr/stdout/file to logging stuff

Added:
    cxf/trunk/api/src/main/java/org/apache/cxf/annotations/Logging.java   (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractLoggingInterceptor.java   (with props)
Modified:
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/LoggingFeature.java
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingOutInterceptor.java
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/aegis/AegisJaxWsImpl.java

Added: cxf/trunk/api/src/main/java/org/apache/cxf/annotations/Logging.java
URL: http://svn.apache.org/viewvc/cxf/trunk/api/src/main/java/org/apache/cxf/annotations/Logging.java?rev=803688&view=auto
==============================================================================
--- cxf/trunk/api/src/main/java/org/apache/cxf/annotations/Logging.java (added)
+++ cxf/trunk/api/src/main/java/org/apache/cxf/annotations/Logging.java Wed Aug 12 20:06:07 2009
@@ -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.cxf.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Enables message Logging
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.TYPE })
+public @interface Logging {
+    /**
+     * The size limit at which messages are truncated in the log 
+     */
+    int limit() default 65536;
+ 
+    /**
+     * the locations where the messages are logged.   The default is
+     * <logger> which means to log to the java.util.logging.Logger, 
+     * but <stdout>, <stderr>, and a "file:/.." URI are acceptable. 
+     */
+    String inLocation() default "<logger>";
+    String outLocation() default "<logger>";
+}
+

Propchange: cxf/trunk/api/src/main/java/org/apache/cxf/annotations/Logging.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/api/src/main/java/org/apache/cxf/annotations/Logging.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/LoggingFeature.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/LoggingFeature.java?rev=803688&r1=803687&r2=803688&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/LoggingFeature.java (original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/LoggingFeature.java Wed Aug 12 20:06:07 2009
@@ -19,6 +19,7 @@
 package org.apache.cxf.feature;
 
 import org.apache.cxf.Bus;
+import org.apache.cxf.annotations.Logging;
 import org.apache.cxf.interceptor.InterceptorProvider;
 import org.apache.cxf.interceptor.LoggingInInterceptor;
 import org.apache.cxf.interceptor.LoggingOutInterceptor;
@@ -39,22 +40,41 @@
   </pre>
  */
 public class LoggingFeature extends AbstractFeature {
-    private static final int DEFAULT_LIMIT = 100 * 1024;
+    private static final int DEFAULT_LIMIT = 64 * 1024;
     private static final LoggingInInterceptor IN = new LoggingInInterceptor(DEFAULT_LIMIT);
     private static final LoggingOutInterceptor OUT = new LoggingOutInterceptor(DEFAULT_LIMIT);
     
-    int limit = DEFAULT_LIMIT;
     
+    String inLocation;
+    String outLocation;
+    
+    int limit = DEFAULT_LIMIT;
+
+    public LoggingFeature() {
+        
+    }
+
+    public LoggingFeature(Logging annotation) {
+        inLocation = annotation.inLocation();
+        outLocation = annotation.outLocation();
+        limit = annotation.limit();
+    }
+
     @Override
     protected void initializeProvider(InterceptorProvider provider, Bus bus) {
-        if (limit == DEFAULT_LIMIT) {
+        if (limit == DEFAULT_LIMIT && inLocation == null && outLocation == null) {
             provider.getInInterceptors().add(IN);
+            provider.getInFaultInterceptors().add(IN);
             provider.getOutInterceptors().add(OUT);
             provider.getOutFaultInterceptors().add(OUT);
         } else {
             LoggingInInterceptor in = new LoggingInInterceptor(limit);
+            in.setOutputLocation(inLocation);
             LoggingOutInterceptor out = new LoggingOutInterceptor(limit);
+            out.setOutputLocation(outLocation);
+            
             provider.getInInterceptors().add(in);
+            provider.getInFaultInterceptors().add(in);
             provider.getOutInterceptors().add(out);
             provider.getOutFaultInterceptors().add(out);
         }

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractLoggingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractLoggingInterceptor.java?rev=803688&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractLoggingInterceptor.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractLoggingInterceptor.java Wed Aug 12 20:06:07 2009
@@ -0,0 +1,104 @@
+/**
+ * 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.cxf.interceptor;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+
+/**
+ * A simple logging handler which outputs the bytes of the message to the
+ * Logger.
+ */
+public abstract class AbstractLoggingInterceptor extends AbstractPhaseInterceptor<Message> {
+
+    protected static final Logger LOG = LogUtils.getL7dLogger(LoggingInInterceptor.class);
+
+    protected int limit = 100 * 1024;
+    protected PrintWriter writer;
+    
+    
+    public AbstractLoggingInterceptor(String phase) {
+        super(phase);
+    }
+
+    public void setOutputLocation(String s) {
+        if (s == null || "<logger>".equals(s)) {
+            writer = null;
+        } else if ("<stdout>".equals(s)) {
+            writer = new PrintWriter(System.out, true);
+        } else if ("<stderr>".equals(s)) {
+            writer = new PrintWriter(System.err, true);  
+        } else {
+            try {
+                URI uri = new URI(s);
+                File file = new File(uri);
+                writer = new PrintWriter(new FileWriter(file, true), true);
+            } catch (Exception ex) {
+                LOG.log(Level.WARNING, "Error configuring log location " + s, ex);
+            }
+        }
+    }
+    
+    public void setPrintWriter(PrintWriter w) {
+        writer = w;
+    }
+    
+    public PrintWriter getPrintWriter() {
+        return writer;
+    }
+    
+    public void setLimit(int lim) {
+        limit = lim;
+    }
+    
+    public int getLimit() {
+        return limit;
+    }    
+
+
+    /**
+     * Transform the string before display. The implementation in this class 
+     * does nothing. Override this method if you want to change the contents of the 
+     * logged message before it is delivered to the output. 
+     * For example, you can use this to mask out sensitive information.
+     * @param originalLogString the raw log message.
+     * @return transformed data
+     */
+    protected String transform(String originalLogString) {
+        return originalLogString;
+    } 
+
+    protected void log(String message) {
+        message = transform(message);
+        if (writer != null) {
+            writer.println(message);
+        } else if (LOG.isLoggable(Level.INFO)) {
+            LOG.info(message);
+        }
+    }
+    
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractLoggingInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractLoggingInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java?rev=803688&r1=803687&r2=803688&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java (original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java Wed Aug 12 20:06:07 2009
@@ -22,26 +22,18 @@
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.logging.Level;
-import java.util.logging.Logger;
 
-import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.io.CachedOutputStream;
 import org.apache.cxf.message.Message;
-import org.apache.cxf.phase.AbstractPhaseInterceptor;
 import org.apache.cxf.phase.Phase;
 
 /**
  * A simple logging handler which outputs the bytes of the message to the
  * Logger.
  */
-public class LoggingInInterceptor extends AbstractPhaseInterceptor<Message> {
+public class LoggingInInterceptor extends AbstractLoggingInterceptor {
 
-    private static final Logger LOG = LogUtils.getL7dLogger(LoggingInInterceptor.class);
-
-    private int limit = 100 * 1024;
-    private PrintWriter writer;
-    
     
     public LoggingInInterceptor() {
         super(Phase.RECEIVE);
@@ -61,41 +53,13 @@
         this.writer = w;
     }
     
-    public void setPrintWriter(PrintWriter w) {
-        writer = w;
-    }
-    
-    public PrintWriter getPrintWriter() {
-        return writer;
-    }
-    
-    public void setLimit(int lim) {
-        limit = lim;
-    }
-    
-    public int getLimit() {
-        return limit;
-    }    
-
     public void handleMessage(Message message) throws Fault {
         if (writer != null || LOG.isLoggable(Level.INFO)) {
             logging(message);
         }
     }
 
-    /**
-     * Transform the string before display. The implementation in this class 
-     * does nothing. Override this method if you want to change the contents of the 
-     * logged message before it is delivered to the output. 
-     * For example, you can use this to mask out sensitive information.
-     * @param originalLogString the raw log message.
-     * @return transformed data
-     */
-    protected String transform(String originalLogString) {
-        return originalLogString;
-    } 
-
-    private void logging(Message message) throws Fault {
+    protected void logging(Message message) throws Fault {
         String id = (String)message.getExchange().get(LoggingMessage.ID_KEY);
         if (id == null) {
             id = LoggingMessage.nextId();
@@ -149,11 +113,6 @@
                 throw new Fault(e);
             }
         }
-
-        if (writer != null) {
-            writer.println(transform(buffer.toString()));
-        } else if (LOG.isLoggable(Level.INFO)) {
-            LOG.info(transform(buffer.toString()));
-        }
+        log(buffer.toString());
     }
 }

Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingOutInterceptor.java?rev=803688&r1=803687&r2=803688&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingOutInterceptor.java (original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingOutInterceptor.java Wed Aug 12 20:06:07 2009
@@ -22,26 +22,18 @@
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.util.logging.Level;
-import java.util.logging.Logger;
 
-import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.io.CacheAndWriteOutputStream;
 import org.apache.cxf.io.CachedOutputStream;
 import org.apache.cxf.io.CachedOutputStreamCallback;
 import org.apache.cxf.message.Message;
-import org.apache.cxf.phase.AbstractPhaseInterceptor;
 import org.apache.cxf.phase.Phase;
 
 /**
  * 
  */
-public class LoggingOutInterceptor extends AbstractPhaseInterceptor {
+public class LoggingOutInterceptor extends AbstractLoggingInterceptor {
    
-    private static final Logger LOG = LogUtils.getL7dLogger(LoggingOutInterceptor.class); 
-
-    private int limit = 100 * 1024;
-    private PrintWriter writer;
-    
     public LoggingOutInterceptor(String phase) {
         super(phase);
         addBefore(StaxOutInterceptor.class.getName());
@@ -59,20 +51,12 @@
         this.writer = w;
     }
     
-    public void setLimit(int lim) {
-        limit = lim;
-    }
-    
-    public int getLimit() {
-        return limit;
-    }    
 
     public void handleMessage(Message message) throws Fault {
         final OutputStream os = message.getContent(OutputStream.class);
         if (os == null) {
             return;
         }
-
         if (LOG.isLoggable(Level.INFO) || writer != null) {
             // Write the output while caching it for the log message
             final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os);
@@ -81,18 +65,6 @@
         }
     }
     
-    /**
-     * Transform the string before display. The implementation in this class 
-     * does nothing. Override this method if you want to change the contents of the 
-     * logged message before it is delivered to the output. 
-     * For example, you can use this to masking out sensitive information.
-     * @param originalLogString the raw log message.
-     * @return transformed data
-     */
-    protected String transform(String originalLogString) {
-        return originalLogString;
-    } 
-
     class LoggingCallback implements CachedOutputStreamCallback {
         
         private final Message message;
@@ -154,11 +126,7 @@
                 //ignore
             }
 
-            if (writer != null) {
-                writer.println(transform(buffer.toString()));
-            } else if (LOG.isLoggable(Level.INFO)) {
-                LOG.info(transform(buffer.toString()));
-            }
+            log(buffer.toString());
             try {
                 //empty out the cache
                 cos.lockOutputStream();

Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java?rev=803688&r1=803687&r2=803688&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java (original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/service/factory/AnnotationsFactoryBeanListener.java Wed Aug 12 20:06:07 2009
@@ -26,6 +26,7 @@
 import org.apache.cxf.Bus;
 import org.apache.cxf.annotations.FastInfoset;
 import org.apache.cxf.annotations.GZIP;
+import org.apache.cxf.annotations.Logging;
 import org.apache.cxf.annotations.SchemaValidation;
 import org.apache.cxf.annotations.WSDLDocumentation;
 import org.apache.cxf.annotations.WSDLDocumentation.Placement;
@@ -34,6 +35,7 @@
 import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.endpoint.Server;
 import org.apache.cxf.feature.AbstractFeature;
+import org.apache.cxf.feature.LoggingFeature;
 import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.interceptor.FIStaxInInterceptor;
 import org.apache.cxf.interceptor.FIStaxOutInterceptor;
@@ -71,17 +73,21 @@
         case ENDPOINT_SELECTED: {
             Class<?> cls = (Class<?>)args[2];
             Endpoint ep = (Endpoint)args[1];
+            Bus bus = factory.getBus();
             addSchemaValidationSupport(ep, cls.getAnnotation(SchemaValidation.class));
             addFastInfosetSupport(ep, cls.getAnnotation(FastInfoset.class));
-            addGZipSupport(ep, factory.getBus(), cls.getAnnotation(GZIP.class));
+            addGZipSupport(ep, bus, cls.getAnnotation(GZIP.class));
+            addLoggingSupport(ep, bus, cls.getAnnotation(Logging.class));
             break; 
         }
         case SERVER_CREATED: {
             Class<?> cls = (Class<?>)args[2];
             Server server = (Server)args[0];
-            addGZipSupport(server.getEndpoint(), factory.getBus(), cls.getAnnotation(GZIP.class));
+            Bus bus = factory.getBus();
+            addGZipSupport(server.getEndpoint(), bus, cls.getAnnotation(GZIP.class));
             addSchemaValidationSupport(server.getEndpoint(), cls.getAnnotation(SchemaValidation.class));
             addFastInfosetSupport(server.getEndpoint(), cls.getAnnotation(FastInfoset.class));
+            addLoggingSupport(server.getEndpoint(), bus, cls.getAnnotation(Logging.class));
             WSDLDocumentation doc = cls.getAnnotation(WSDLDocumentation.class);
             if (doc != null) {
                 addDocumentation(server, WSDLDocumentation.Placement.SERVICE, doc);
@@ -118,6 +124,13 @@
         }
     }
 
+    private void addLoggingSupport(Endpoint endpoint, Bus bus, Logging annotation) {
+        if (annotation != null) {
+            LoggingFeature lf = new LoggingFeature(annotation);
+            lf.initialize(endpoint, bus);
+        }
+    }
+
     private void addGZipSupport(Endpoint ep, Bus bus, GZIP annotation) {
         if (annotation != null) {
             try {

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/aegis/AegisJaxWsImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/aegis/AegisJaxWsImpl.java?rev=803688&r1=803687&r2=803688&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/aegis/AegisJaxWsImpl.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/aegis/AegisJaxWsImpl.java Wed Aug 12 20:06:07 2009
@@ -23,11 +23,11 @@
 
 import javax.jws.WebService;
 
-import org.apache.cxf.feature.Features;
+import org.apache.cxf.annotations.Logging;
 import org.apache.cxf.systest.aegis.bean.Item;
 
-@Features(features = "org.apache.cxf.feature.LoggingFeature")
-@WebService (endpointInterface = "org.apache.cxf.systest.aegis.AegisJaxWs")
+@Logging
+@WebService(endpointInterface = "org.apache.cxf.systest.aegis.AegisJaxWs")
 public class AegisJaxWsImpl implements AegisJaxWs {
     
     Map<Integer, Item> items = new HashMap<Integer, Item>();