cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache CXF Documentation > Debugging and Logging
Date Sun, 16 Jan 2011 15:35:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2036/9/1/_/styles/combined.css?spaceKey=CXF20DOC&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CXF20DOC/Debugging+and+Logging">Debugging
and Logging</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~mazzag">Glen
Mazza</a>
    </h4>
        <div id="versionComment">
        <b>Comment:</b>
        not clear what sonar, fisheye, and curl have to do with web service debugging or analysis.<br
/>
    </div>
        <br/>
                         <h4>Changes (5)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >[SOAP UI|http://soapui.org] can also
be used for debugging. In addition to viewing messages, it allows you send messages and load
test your services. It also has plugins for the [Eclipse IDE|http://soapui.org/IDE-Plugins/eclipse-plugin.html],
[NetBeans IDE|http://www.soapui.org/IDE-Plugins/netbean.html] and [IntelliJ IDEA|http://www.soapui.org/IDE-Plugins/intellij.html].
<br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h1.
Helpful Tools and Utilities <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h1.
Other Helpful Tools <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h2. WSDL Viewer <br></td></tr>
            <tr><td class="diff-changed-lines" >[WSDL Viewer|http://tomi.vanek.sk/index.php?page=wsdl-viewer]
is a small tool to visualize <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">the
web-service</span> <span class="diff-added-words"style="background-color: #dfd;">web-services</span>
in a more intuitive way. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h2.
cURL <br>[cURL|http://curl.haxx.se/] is a command line tool for transferring data with
URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS,
POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP. curl supports SSL certificates,
HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password
authentication (Basic, Digest, NTLM, Negotiate, kerberos...), file transfer resume, proxy
tunneling and a busload of other useful tricks.  <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h2.
Sonar <br>[Sonar|http://www.sonarsource.org/] is an open source quality management platform,
dedicated to continuously analyze and measure source code quality, from the portfolio to the
method. Here is [CXF on Sonar|http://nemo.sonarsource.org/project/index/117804]. <br>
<br>h2. Fisheye <br> [Fisheye|http://www.atlassian.com/software/fisheye/] provides
a web interface for Subversion, Git, CVS, Perforce &amp; ClearCase source control repositories.
Here is [CXF on Fisheye|https://fisheye6.atlassian.com/browse/cxf]. <br> <br>
<br></td></tr>
            <tr><td class="diff-unchanged" >h1. ATOM logging <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <span style="font-size:2em;font-weight:bold"> Debugging and Logging </span>

<div>
<ul>
    <li><a href='#DebuggingandLogging-LoggingMessages'>Logging Messages</a></li>
<ul>
    <li><a href='#DebuggingandLogging-Configurelogginglevels.'>Configure logging
levels.</a></li>
    <li><a href='#DebuggingandLogging-UsingLog4jInsteadofjava.util.logging'>Using
Log4j Instead of java.util.logging</a></li>
    <li><a href='#DebuggingandLogging-UsingSLF4JInsteadofjava.util.logging%28since2.2.8%29'>Using
SLF4J Instead of java.util.logging (since 2.2.8)</a></li>
</ul>
    <li><a href='#DebuggingandLogging-DebuggingTools'>Debugging Tools</a></li>
<ul>
    <li><a href='#DebuggingandLogging-EclipseIDE'>Eclipse IDE</a></li>
    <li><a href='#DebuggingandLogging-NetBeansIDE'>NetBeans IDE</a></li>
    <li><a href='#DebuggingandLogging-tcpmonandtcptrace'>tcpmon and tcptrace</a></li>
    <li><a href='#DebuggingandLogging-WSMonitor'>WSMonitor</a></li>
    <li><a href='#DebuggingandLogging-NetSniffer'>NetSniffer</a></li>
    <li><a href='#DebuggingandLogging-Wireshark'>Wireshark</a></li>
    <li><a href='#DebuggingandLogging-SOAPUI'>SOAP UI</a></li>
</ul>
    <li><a href='#DebuggingandLogging-OtherHelpfulTools'>Other Helpful Tools</a></li>
<ul>
    <li><a href='#DebuggingandLogging-WSDLViewer'>WSDL Viewer</a></li>
</ul>
    <li><a href='#DebuggingandLogging-ATOMlogging'>ATOM logging</a></li>
<ul>
    <li><a href='#DebuggingandLogging-PushStyle'>Push Style</a></li>
<ul>
    <li><a href='#DebuggingandLogging-Springconfiguration'>Spring configuration</a></li>
    <li><a href='#DebuggingandLogging-Propertiesfile'>Properties file</a></li>
    <li><a href='#DebuggingandLogging-Programmingstyle'>Programming style</a></li>
</ul>
    <li><a href='#DebuggingandLogging-PollStyle'>Poll Style</a></li>
<ul>
    <li><a href='#DebuggingandLogging-Springconfiguration'>Spring configuration</a></li>
    <li><a href='#DebuggingandLogging-LinkingtoAtomendpointsfromCXFServicespage'>Linking
to Atom endpoints from CXF Services page</a></li>
</ul>
</ul>
</ul></div>

<h1><a name="DebuggingandLogging-LoggingMessages"></a>Logging Messages</h1>

<p>CXF uses <a href="http://www.oracle.com/technology/pub/articles/hunter_logging.html"
class="external-link" rel="nofollow">Java SE Logging</a> for both client- and server-side
logging of SOAP requests and responses.  Logging is activated by use of separate in/out interceptors
that can be attached to the client and/or service as required.  These interceptors can be
specified either programmatically (via Java code and/or annotations) or via use of configuration
files.</p>

<p>Configuration files are probably best.  They offer two benefits over programmatic
configuration:  </p>
<ol>
	<li>Logging requirements can be altered without needing to recompile the code</li>
	<li>No Apache CXF-specific APIs need to be added to your code, which helps it remain
interoperable with other JAX-WS compliant web service stacks</li>
</ol>


<p>Enabling message logging through configuration files is shown <a href="http://cxf.apache.org/docs/configuration.html"
class="external-link" rel="nofollow">here</a>.  </p>

<p>For programmatic configuration, the logging interceptors can be added to your service
endpoint as follows:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> javax.xml.ws.Endpoint;
<span class="code-keyword">import</span> org.apache.cxf.interceptor.LoggingInInterceptor;
<span class="code-keyword">import</span> org.apache.cxf.interceptor.LoggingOutInterceptor;
<span class="code-keyword">import</span> org.apache.cxf.jaxws.EndpointImpl;

<span class="code-object">Object</span> implementor = <span class="code-keyword">new</span>
GreeterImpl();
EndpointImpl ep = (EndpointImpl) Endpoint.publish(<span class="code-quote">"http:<span
class="code-comment">//localhost/service"</span>, implementor);
</span>
ep.getServer().getEndpoint().getInInterceptors().add(<span class="code-keyword">new</span>
LoggingInInterceptor());
ep.getServer().getEndpoint().getOutInterceptors().add(<span class="code-keyword">new</span>
LoggingOutInterceptor());
</pre>
</div></div>


<p>For web services running on CXFServlet, the below annotations can be used on either
the SEI or the SEI implementation class.  If placed on the SEI, they activate logging both
for client and server; if on the SEI implementation class, they are relevant just for server-side
logging.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> org.apache.cxf.feature.Features;

@javax.jws.WebService(portName = <span class="code-quote">"MyWebServicePort"</span>,
serviceName = <span class="code-quote">"MyWebService"</span>, ...)
@Features(features = <span class="code-quote">"org.apache.cxf.feature.LoggingFeature"</span>)
       
<span class="code-keyword">public</span> class MyWebServicePortTypeImpl <span
class="code-keyword">implements</span> MyWebServicePortType {
</pre>
</div></div>

<p>or (equivalent)</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> org.apache.cxf.interceptor.InInterceptors;
<span class="code-keyword">import</span> org.apache.cxf.interceptor.OutInterceptors;

@javax.jws.WebService(portName = <span class="code-quote">"WebServicePort"</span>,
serviceName = <span class="code-quote">"WebServiceService"</span>, ...)
@InInterceptors(interceptors = <span class="code-quote">"org.apache.cxf.interceptor.LoggingInInterceptor"</span>)
@OutInterceptors(interceptors = <span class="code-quote">"org.apache.cxf.interceptor.LoggingOutInterceptor"</span>)
<span class="code-keyword">public</span> class WebServicePortTypeImpl <span
class="code-keyword">implements</span> WebServicePortType {
</pre>
</div></div>


<p>For programmatic client-side logging, the following code snippet can be used as an
example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> org.apache.cxf.endpoint.Client;
<span class="code-keyword">import</span> org.apache.cxf.frontend.ClientProxy;
<span class="code-keyword">import</span> org.apache.cxf.interceptor.LoggingInInterceptor;
<span class="code-keyword">import</span> org.apache.cxf.interceptor.LoggingOutInterceptor;

<span class="code-keyword">public</span> class WSClient {
    <span class="code-keyword">public</span> <span class="code-keyword">static</span>
void main (<span class="code-object">String</span>[] args) {
        MyService ws = <span class="code-keyword">new</span> MyService();
        MyPortType port = ws.getPort();
        
        Client client = ClientProxy.getClient(port);
        client.getInInterceptors().add(<span class="code-keyword">new</span> LoggingInInterceptor());
        client.getOutInterceptors().add(<span class="code-keyword">new</span>
LoggingOutInterceptor()); 
        
        <span class="code-comment">// make WS calls...</span>
</pre>
</div></div>

<h2><a name="DebuggingandLogging-Configurelogginglevels."></a>Configure
logging levels. </h2>

<p>In the <a href="http://svn.apache.org/viewvc/cxf/trunk/distribution/src/main/release/etc/"
class="external-link" rel="nofollow">/etc folder</a> of the CXF distribution there
is a sample Java SE logging.properties file you can use to configure logging.  For example,
if you want to change the console logging level from WARNING to FINE, you need to update two
properties in this logging.properties file as below:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
.level= FINE
java.util.logging.ConsoleHandler.level = FINE
</pre>
</div></div>

<p>Once this is done, you will need to set the <b>-Djava.util.logging.config.file</b>
property to the location of the logging.properties file.  As an example, the Ant target below
has this property set:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;target name=<span class="code-quote">"runClient"</span>&gt;</span>
   <span class="code-tag">&lt;java classname=<span class="code-quote">"client.WSClient"</span>
fork=<span class="code-quote">"true"</span>&gt;</span>	    	
      <span class="code-tag">&lt;classpath&gt;</span>
         <span class="code-tag">&lt;pathelement location=<span class="code-quote">"${build.classes.dir}"</span>/&gt;</span>
         <span class="code-tag">&lt;fileset dir=<span class="code-quote">"${env.CXF_HOME}/lib"</span>&gt;</span>
            <span class="code-tag">&lt;include name=<span class="code-quote">"*.jar"</span>/&gt;</span>
         <span class="code-tag">&lt;/fileset&gt;</span>
      <span class="code-tag">&lt;/classpath&gt;</span>
      <span class="code-tag">&lt;jvmarg value=<span class="code-quote">"-Djava.util.logging.config.file=/usr/myclientapp/logging.properties"</span>/&gt;</span>
   <span class="code-tag">&lt;/java&gt;</span>
<span class="code-tag">&lt;/target&gt;</span>
</pre>
</div></div>

<p>Alternatively, for SOAP clients, you can modify the Java-wide logging.properties
file in the JDK_HOME/jre/lib folder, or for servlet-hosted web service providers, placing
a logging.properties file in the WEB-INF/classes folder (see <a href="http://tomcat.apache.org/tomcat-6.0-doc/logging.html"
class="external-link" rel="nofollow">here</a> for more details.)</p>

<h2><a name="DebuggingandLogging-UsingLog4jInsteadofjava.util.logging"></a>Using
Log4j Instead of java.util.logging </h2>

<p>As noted above, CXF uses the <tt>java.util.logging</tt> package by default.
But it is possible to switch CXF to instead use <a href="http://logging.apache.org/log4j/"
class="external-link" rel="nofollow">Log4J</a>. This is achieved through the use
of configuration files. There are two options to bootstrapping CXF logging and each is listed
below: </p>

<ul>
	<li>Add the following system property to the classpath from which CXF is initialized:</li>
</ul>


<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
-Dorg.apache.cxf.Logger=org.apache.cxf.common.logging.Log4jLogger
</pre>
</div></div>

<ul>
	<li>Add the file <tt>META-INF/cxf/org.apache.cxf.Logger</tt> to the classpath
and make sure it contains the following content:</li>
</ul>


<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
org.apache.cxf.common.logging.Log4jLogger
</pre>
</div></div>

<h2><a name="DebuggingandLogging-UsingSLF4JInsteadofjava.util.logging%28since2.2.8%29"></a>Using
SLF4J Instead of java.util.logging (since 2.2.8)</h2>

<p>As noted above, CXF uses the <tt>java.util.logging</tt> package by default.
But it is possible to switch CXF to instead use <a href="http://www.slf4j.org/" class="external-link"
rel="nofollow">SLF4J</a>. This is achieved through the use of configuration files.
There are two options to bootstrapping CXF logging and each is listed below: </p>

<ul>
	<li>Add the following system property to the classpath from which CXF is initialized:</li>
</ul>


<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
-Dorg.apache.cxf.Logger=org.apache.cxf.common.logging.Slf4jLogger
</pre>
</div></div>

<ul>
	<li>Add the file <tt>META-INF/cxf/org.apache.cxf.Logger</tt> to the classpath
and make sure it contains the following content:</li>
</ul>


<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
org.apache.cxf.common.logging.Slf4jLogger
</pre>
</div></div>


<h1><a name="DebuggingandLogging-DebuggingTools"></a>Debugging Tools</h1>

<h2><a name="DebuggingandLogging-EclipseIDE"></a>Eclipse IDE</h2>

<p>See this <a href="http://www.jroller.com/gmazza/entry/eclipse_debug_web_services"
class="external-link" rel="nofollow">blog entry</a> for information on debugging
web services using Eclipse.  Note this is primarily for tracing/debugging source code; you
will probably still want to use one of the tools below to capture network traffic, view SOAP
requests and responses, etc.</p>

<h2><a name="DebuggingandLogging-NetBeansIDE"></a>NetBeans IDE</h2>
<p>NetBeans include a <a href="http://www.netbeans.org/features/java/debugger.html"
class="external-link" rel="nofollow">debugger</a>, <a href="http://www.netbeans.org/features/java/profiler.html"
class="external-link" rel="nofollow">profiler</a> and an HTTP monitor that can assist
in troubleshooting SOA applications.</p>

<h2><a name="DebuggingandLogging-tcpmonandtcptrace"></a>tcpmon and tcptrace</h2>
<p><a href="http://tcpmon.dev.java.net" class="external-link" rel="nofollow">tcpmon</a>
allows you to easily view messages as they go back and forth on the wire. The companion utility
<a href="http://www.tcptrace.org" class="external-link" rel="nofollow">tcptrace</a>
can be used for analysis of the dump.</p>

<h2><a name="DebuggingandLogging-WSMonitor"></a>WSMonitor</h2>
<p><a href="https://wsmonitor.dev.java.net/" class="external-link" rel="nofollow">WSMonitor</a>
in another option to Tcpmon with slightly more functionality.</p>

<h2><a name="DebuggingandLogging-NetSniffer"></a>NetSniffer</h2>
<p><a href="http://www.miray.de/products/sat.netsniffer.html" class="external-link"
rel="nofollow">NetSniffer</a> makes it possible to track the network traffic between
arbitrary devices within a LAN segment.</p>

<h2><a name="DebuggingandLogging-Wireshark"></a>Wireshark</h2>
<p><a href="http://www.wireshark.org/" class="external-link" rel="nofollow">Wireshark</a>,
a network packet analyzer, is useful for following the routing of SOAP messages.  It can also
help when you are getting an HTML error message from the server that your CXF client cannot
normally process, by allowing you to see the non-SOAP error message.  See this <a href="http://www.jroller.com/gmazza/entry/soap_calls_over_wireshark"
class="external-link" rel="nofollow">blog entry</a> for more information.</p>

<h2><a name="DebuggingandLogging-SOAPUI"></a>SOAP UI</h2>
<p><a href="http://soapui.org" class="external-link" rel="nofollow">SOAP UI</a>
can also be used for debugging. In addition to viewing messages, it allows you send messages
and load test your services. It also has plugins for the <a href="http://soapui.org/IDE-Plugins/eclipse-plugin.html"
class="external-link" rel="nofollow">Eclipse IDE</a>, <a href="http://www.soapui.org/IDE-Plugins/netbean.html"
class="external-link" rel="nofollow">NetBeans IDE</a> and <a href="http://www.soapui.org/IDE-Plugins/intellij.html"
class="external-link" rel="nofollow">IntelliJ IDEA</a>.</p>

<h1><a name="DebuggingandLogging-OtherHelpfulTools"></a>Other Helpful Tools</h1>

<h2><a name="DebuggingandLogging-WSDLViewer"></a>WSDL Viewer</h2>
<p><a href="http://tomi.vanek.sk/index.php?page=wsdl-viewer" class="external-link"
rel="nofollow">WSDL Viewer</a> is a small tool to visualize web-services in a more
intuitive way. </p>


<h1><a name="DebuggingandLogging-ATOMlogging"></a>ATOM logging</h1>

<p><b>This feature is available since CXF 2.3.0, as part of the cxf-rt-management-web
component</b></p>

<p>CXF supports collecting log events, converting them to <a href="http://tools.ietf.org/html/rfc4287"
class="external-link" rel="nofollow">ATOM Syndication Format</a> and either pushing
them to the Atom-aware consumers or making them available for polling. Logging is based on
a custom <tt>java.util.logging</tt> (JUL) handler that can be registered with
loggers extending today's publishing protocols.</p>

<p><b>CXF JAXRS and JAXWS endpoints</b> can avail of this feature.</p>

<h2><a name="DebuggingandLogging-PushStyle"></a>Push Style</h2>

<p>Push-style handler enqueues log records as they are published from loggers. After
the queue size exceeds configurable "batch size", processing of collection of these records
(in size of batch size) is triggered. Batch of log events is transformed by converter to ATOM
element and then it is pushed out by deliverer to client. Both converter and deliverer are
configurable units that allow to change transformation and transportation strategies. Next
to predefined own custom implementations can be used when necessary &#8211; see examples.
Batches are processed sequentially to allow client side to recreate stream of events. </p>

<p><b>Limitations:</b> Reliability is not supported out of the box, however
there is predefined retrying delivery strategy. Persistence is also not supported, any enqueued
and undelivered log events are lost on shutdown. Definitions of delivery endpoints is static,
subscription of callback URIs is not yet supported. </p>

<h3><a name="DebuggingandLogging-Springconfiguration"></a>Spring configuration</h3>
<p>In simplest case pushing ATOM Feeds can be declared this way:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
   <span class="code-tag">&lt;bean class=<span class="code-quote">"org.apache.cxf.management.web.logging.atom.AtomPushBean"</span>
init-method=<span class="code-quote">"init"</span>&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"url"</span>
value=<span class="code-quote">"http://somewhere.com/foo/bar"</span>/&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"level"</span>
value=<span class="code-quote">"ALL"</span> /&gt;</span>
   <span class="code-tag">&lt;/bean&gt;</span>
</pre>
</div></div>
<p>Spring bean creates ATOM push handler and registers it with root logger for all log
levels. This setup leads to logging everything CXF, Spring and others inclued. Since batch
size is not specified default value of one is used - each event is packed up as single feed
pushed out to specified URL. Default conversion strategy and default WebClient-based deliver
are used. </p>

<p>More complex example shows how to specify non-root logger and define batch size:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
   <span class="code-tag">&lt;bean class=<span class="code-quote">"org.apache.cxf.management.web.logging.atom.AtomPushBean"</span>
init-method=<span class="code-quote">"init"</span>&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"url"</span>
value=<span class="code-quote">"http://somewhere.com/foo/bar"</span>/&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"logger"</span>
value=<span class="code-quote">"org.apache.cxf.jaxrs"</span> /&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"level"</span>
value=<span class="code-quote">"INFO"</span> /&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"batchSize"</span>
value=<span class="code-quote">"10"</span> /&gt;</span>
   <span class="code-tag">&lt;/bean&gt;</span>
</pre>
</div></div>

<p>To push to client events generated by different loggers on different levels, "loggers"
property must be used instead of pair "logger" and "level":</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
   <span class="code-tag">&lt;bean class=<span class="code-quote">"org.apache.cxf.jaxrs.management.web.atom.AtomPushBean"</span>
init-method=<span class="code-quote">"init"</span>&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"url"</span>
value=<span class="code-quote">"http://somewhere.com/foo/bar"</span>/&gt;</span>
       &lt;property name=<span class="code-quote">"loggers"</span> value="
           org.apache.cxf:DEBUG,
           org.apache.cxf.jaxrs,
           org.apache.cxf.bus:ERROR,
           myNamedLogger:INFO" /&gt;
   <span class="code-tag">&lt;/bean&gt;</span>
</pre>
</div></div>
<p>In example above, second logger does not have specified level, in such case default
level of "INFO" is used.</p>

<p>In all above cases, when first delivery fails engine of ATOM push handler is shutdown
and no events will be processed and pushed until configuration reload. To avoid this frequent
case, retrial can be enabled:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
   <span class="code-tag">&lt;bean class=<span class="code-quote">"org.apache.cxf.management.web.logging.atom.AtomPushBean"</span>
init-method=<span class="code-quote">"init"</span>&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"url"</span>
value=<span class="code-quote">"http://somewhere.com/foo/bar"</span>/&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"logger"</span>
value=<span class="code-quote">"org.apache.cxf.jaxrs"</span> /&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"level"</span>
value=<span class="code-quote">"INFO"</span> /&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"retryPause"</span>
value=<span class="code-quote">"linear"</span> /&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"retryPauseTime"</span>
value=<span class="code-quote">"60"</span> /&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"retryTimeout"</span>
value=<span class="code-quote">"300"</span> /&gt;</span>
   <span class="code-tag">&lt;/bean&gt;</span>
</pre>
</div></div>
<p>In this case for 5 minutes ("retryTimeout") after delivery failure there will be
1 minute pause ("retryPauseTime") repeated every time with same value ("retryPause" as "linear").
Instead of same pause time, "exponential" value of "retryPause" can be used - each next time
pause time doubles. When timeout value is set to 0 retrying is infinite. In case of invalid
or missing values defaults are used: for pause time 30 seconds and for timeout 0 (infinite).
Instead of same pause time, "exponential" value of "retryPauseType" can be used - each next
time pause time doubles. When timeout value is set to 0 retrying is infinite. In case of invalid
or missing values defaults are used: for pause time 30 seconds and for timeout 0 (infinite).</p>

<p>Ultimate control is given by "converter" and "deliverer" properties. Either beans
of predefined or custom classes can be used (see "Programming syle" chapter for more details).
Example below shows custom class using different transport protocol than default:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
   &lt;bean id=<span class="code-quote">"soapDeliverer"</span> ...
   ...
   <span class="code-tag">&lt;bean class=<span class="code-quote">"org.apache.cxf.management.web.logging.atom.AtomPushBean"</span>
init-method=<span class="code-quote">"init"</span>&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"deliverer"</span>&gt;</span>
           <span class="code-tag">&lt;ref bean=<span class="code-quote">"soapDeliverer"</span>/&gt;</span>
       <span class="code-tag">&lt;/property&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"loggers"</span>
... /&gt;</span>
   <span class="code-tag">&lt;/bean&gt;</span>
</pre>
</div></div>
<p>Note that specifying custom deliverer cause ignoring "url" and "retryXxx" because
underneath configuration replaces employed tandem of RetryingDeliverer and WebClientDeliverer
with provided one.</p>

<p>When ATOM feeds must be delivered to more than one endpoint and additionally each
endpoint is fed by different loggers simply use multiple ATOM push beans in Spring config:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
   <span class="code-tag">&lt;bean id=<span class="code-quote">"atom1"</span>
class=<span class="code-quote">"org.apache.cxf.management.web.logging.atom.AtomPushBean"</span>
init-method=<span class="code-quote">"init"</span>&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"url"</span>
value=<span class="code-quote">"http://someplace.com/foo/bar"</span>/&gt;</span>
       ...
   <span class="code-tag">&lt;/bean&gt;</span>
   <span class="code-tag">&lt;bean id=<span class="code-quote">"atom2"</span>
class=<span class="code-quote">"org.apache.cxf.jaxrs.management.web.atom.AtomPushBean"</span>
init-method=<span class="code-quote">"init"</span>&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"url"</span>
value=<span class="code-quote">"http://otherplace.com/baz/blah"</span>/&gt;</span>
       ...
   <span class="code-tag">&lt;/bean&gt;</span>
   ....
</pre>
</div></div>

<h3><a name="DebuggingandLogging-Propertiesfile"></a>Properties file</h3>
<p>When CXF is used either without Spring or logging is configured with properties file,
support for this type of configuration becomes handy. ATOM push handler supports "simple configuration"
with properties file; simple means aligned to expressiveness of JUL configuration that is
limited to cases, where each type of handler can be used only once and registered with root
logger.</p>

<p>Set of properties is very similar to Spring configuration with following exceptions:</p>
<ul>
	<li>Properties specify classes of custom deliverers and converters, instead of instances.</li>
	<li>Custom deliverer must have public constructor with the only String parameters;
created instance will have passed URL of client.</li>
	<li>Multiple client endpoints is not supported out of the box (cannot instantiate multiple
handlers as in Spring)</li>
</ul>


<p>Example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
 handlers = org.apache.cxf.management.web.logging.atom.AtomPushHandler, java.util.logging.ConsoleHandler
 .level = INFO
 ...
 org.apache.cxf.jaxrs.ext.management.web.AtomPushHandler.url = http:<span class="code-comment">//localhost:9080
</span> org.apache.cxf.jaxrs.ext.management.web.AtomPushHandler.batchSize = 10
 org.apache.cxf.jaxrs.ext.management.web.AtomPushHandler.deliverer = WebClientDeliverer 
 org.apache.cxf.jaxrs.ext.management.web.AtomPushHandler.converter = foo.bar.MyConverter
 org.apache.cxf.jaxrs.ext.management.web.AtomPushHandler.retry.pause = linear
 org.apache.cxf.jaxrs.ext.management.web.AtomPushHandler.retry.pause.time = 10
 org.apache.cxf.jaxrs.ext.management.web.AtomPushHandler.retry.timeout = 360
 ...
</pre>
</div></div>

<h3><a name="DebuggingandLogging-Programmingstyle"></a>Programming style</h3>
<p>In most complex cases direct programming using <tt><a href="http://cxf.apache.org/javadoc/latest/org/apache/cxf/management/web/logging/atom/package-summary.html"
class="external-link" rel="nofollow">org.apache.cxf.jaxrs.ext.logging.atom</a></tt>
package may be necessary. In this case AtomPushHandler class is main artifact and Deliverer
and Converter interfaces and their implementations are necessary components.</p>

<p>Following example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    Deliverer d = <span class="code-keyword">new</span> WebClientDeliverer(<span
class="code-quote">"http:<span class="code-comment">//somewhere.com/foo/bar"</span>);
</span>    d = <span class="code-keyword">new</span> RetryingDeliverer(d,
300, 60, <span class="code-keyword">true</span>);
    Converter c = <span class="code-keyword">new</span> SingleEntryContentConverter();
    AtomPushHandler h = <span class="code-keyword">new</span> AtomPushHandler(1,
c, d);    
    Logger l = Logger.getLogger(<span class="code-quote">"org.apache.cxf.jaxrs"</span>);
    l.setLevel(Level.INFO);
    l.addHandler(h);
</pre>
</div></div>
<p>is equivalent to Spring configuration:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   &lt;bean class=<span class="code-quote">"org.apache.cxf.management.web.logging.atom.AtomPushBean"</span>
init-method=<span class="code-quote">"init"</span>&gt;
       &lt;property name=<span class="code-quote">"url"</span> value=<span
class="code-quote">"http:<span class="code-comment">//somewhere.com/foo/bar"</span>/&gt;
</span>       &lt;property name=<span class="code-quote">"logger"</span>
value=<span class="code-quote">"org.apache.cxf.jaxrs"</span> /&gt;
       &lt;property name=<span class="code-quote">"level"</span> value=<span
class="code-quote">"INFO"</span> /&gt;
       &lt;property name=<span class="code-quote">"retryPause"</span> value=<span
class="code-quote">"linear"</span> /&gt;
       &lt;property name=<span class="code-quote">"retryPauseTime"</span>
value=<span class="code-quote">"60"</span> /&gt;
       &lt;property name=<span class="code-quote">"retryTimeout"</span> value=<span
class="code-quote">"300"</span> /&gt;
   &lt;/bean&gt;
</pre>
</div></div>

<h2><a name="DebuggingandLogging-PollStyle"></a>Poll Style</h2>

<p><a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/atom/AtomPullServer.java"
class="external-link" rel="nofollow">AtomPullServer</a> acts as an Atom feed endpoint
and makes all log events it has accumulated or read from some external storage available for
polling.</p>

<p>Log events are made available in pages, that is a feed instance will list up to a
configurable maximum number of entries and will also include atom links of types 'prev', 'next',
'first' and 'last', thus making it possible to browse through all the log records.</p>

<h3><a name="DebuggingandLogging-Springconfiguration"></a>Spring configuration</h3>

<p>When configuring AtomPullServer endpoints, one can set the 'loggers' property the
same way as it is done for AtomPushBeans, for example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
   <span class="code-tag">&lt;bean class=<span class="code-quote">"org.apache.cxf.management.web.logging.atom.AtomPullServer"</span>
init-method=<span class="code-quote">"init"</span>&gt;</span>
       &lt;property name=<span class="code-quote">"loggers"</span> value="
           org.apache.cxf:DEBUG,
           org.apache.cxf.jaxrs,
           org.apache.cxf.bus:ERROR,
           myNamedLogger:INFO" /&gt;
       <span class="code-tag">&lt;property name=<span class="code-quote">"pageSize"</span>
value=<span class="code-quote">"30"</span>/&gt;</span>
   <span class="code-tag">&lt;/bean&gt;</span>
</pre>
</div></div>

<p>In addition to the 'loggers' property, a 'pageSize' property limiting a number of
entries per page to 30 is also set (default is 40).</p>

<p>One can have a <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/ReadWriteLogStorage.java"
class="external-link" rel="nofollow">ReadWriteLogStorage</a> bean injected into AtomPushBean
if the log records have to be periodically offloaded from memory and persisted across restarts
:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
   <span class="code-tag">&lt;bean id=<span class="code-quote">"storage"</span>
class=<span class="code-quote">"org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPullSpringTest$Storage"</span>/&gt;</span>

   <span class="code-tag">&lt;bean class=<span class="code-quote">"org.apache.cxf.management.web.logging.atom.AtomPullServer"</span>
init-method=<span class="code-quote">"init"</span>&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"loggers"</span>
value=<span class="code-quote">"org.apache.cxf.jaxrs"</span> /&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"maxInMemorySize"</span>
value=<span class="code-quote">"400"</span>/&gt;</span>
       <span class="code-tag">&lt;property name=<span class="code-quote">"storage"</span>&gt;</span>
           <span class="code-tag">&lt;ref bean=<span class="code-quote">"storage"</span>/&gt;</span>
       <span class="code-tag">&lt;/property&gt;</span>
   <span class="code-tag">&lt;/bean&gt;</span>
</pre>
</div></div>

<p>When a number of records in memory reaches 400 (default is 500) then the records
will be offloaded into a provided storage and will be read from it after the restart or when
a client has requested a relevant page. If no storage is available then after an in-memory
limit is reached the oldest records will be discarded, one can set a maxInMemorySize property
to a large enough value if needed.</p>

<p>Another option is to require a given AtomPullServer to read from the external read-only
storage by registering a <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/management-web/src/main/java/org/apache/cxf/management/web/logging/ReadableLogStorage.java"
class="external-link" rel="nofollow">ReadableLogStorage</a> bean. For example, very
often, the runtime is already logging to some external file, thus AtomPullServer can be asked
to read from this file only with the help of ReadableLogStorage, without AtomPullServer having
to catch log events too. </p>

<p>Once AtomPullServer has been configured, it has to be registered as a service bean
with the jaxrs endpoint so that Atom aware clients (blog readers, etc) can start polling it
:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"atomServer"</span>
address=<span class="code-quote">"/atom"</span>&gt;</span>
 <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
   <span class="code-tag">&lt;ref bean=<span class="code-quote">"atomPullServer"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>

 <span class="code-tag">&lt;jaxrs:providers&gt;</span>
  <span class="code-tag">&lt;ref bean=<span class="code-quote">"feed"</span>/&gt;</span>
  <span class="code-tag">&lt;ref bean=<span class="code-quote">"entry"</span>/&gt;</span>
 <span class="code-tag">&lt;/jaxrs:providers&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>

<span class="code-tag">&lt;bean id=<span class="code-quote">"feed"</span>
class=<span class="code-quote">"org.apache.cxf.jaxrs.provider.AtomFeedProvider"</span>/&gt;</span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"entry"</span>
class=<span class="code-quote">"org.apache.cxf.jaxrs.provider.AtomEntryProvider"</span>/&gt;</span>
</pre>
</div></div>

<h3><a name="DebuggingandLogging-LinkingtoAtomendpointsfromCXFServicespage"></a>Linking
to Atom endpoints from CXF Services page</h3>

<p>If you would like your users to find about the Atom feeds which are collecting log
events from your endpoints then AtomPullServers will need to have a CXF bus injected, as well
as be told about the address of the corresponding atom feed endpoint and of the jaxrs or jaxws
endpoint :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
&lt;bean id=<span class="code-quote">"atomPullServer"</span> class=<span
class="code-quote">"org.apache.cxf.management.web.logging.atom.AtomPullServer"</span>
init-method=<span class="code-quote">"init"</span>&gt;
&lt;property name=<span class="code-quote">"loggers"</span> value=<span
class="code-quote">"org.apache.cxf.systest.jaxrs.JAXRSLoggingAtomPullSpringTest$Resource:ALL"</span>/&gt;
&lt;property name=<span class="code-quote">"bus"</span>&gt;
&lt;ref bean=<span class="code-quote">"cxf"</span>/&gt;
&lt;/property&gt;
&lt;!-- <span class="code-keyword">this</span> is a jaxrs:server/@adrress
or jaxws:endpoint/@address of the endpoint generating the log events --&gt;
&lt;property name=<span class="code-quote">"endpointAddress"</span> value=<span
class="code-quote">"/resource"</span>/&gt;
&lt;!-- <span class="code-keyword">this</span> is a jaxrs:server/@address
of the endpoint <span class="code-keyword">for</span> which <span class="code-keyword">this</span>
atomPullServer bean is registered as a service bean --&gt;
&lt;property name=<span class="code-quote">"serverAddress"</span> value=<span
class="code-quote">"/atom"</span>/&gt;
&lt;/bean&gt;
</pre>
</div></div>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/Debugging+and+Logging">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=29161&revisedVersion=43&originalVersion=42">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/Debugging+and+Logging?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message