2.6. Logging

2.6.1. Dynamic tube-based message logging

As you may know, Metro creates a tubeline for each WS endpoint and endoint client to process SOAP messages flowing from and to the endpoint and or its client. Each tubeline consist of a set of tube instances chained together. A tube is a basic SOAP message processing unit. Standard Metro tubes are used to implement processing logic for different SOAP processing aspects (validation, Java-XML mapping etc.) and higher-level QoS domains (security, reliable messaging etc.) As an experimental feature, custom tubes are supported as well.

When developing an advanced web service that requires Quality of Service features or adding a custom tube into the default Metro tubeline, the ability to see the SOAP message content at different processing stages as the message flows through the tubeline may be very useful. As Metro tubeline get's dynamically created for each endpoint or client, Metro (since version 2.0) provides a new message logging facility that copes with the dynamics of a tubeline creation by defining a set of templating rules that provide a generic way for constructing system-level properties able to control message content logging before and/or after each tube's processing.

To turn on the logging for any particular tube (or a set of tubes) created by a specific tube factory, the developer needs to set one or more of the following system properties, depending on the target scope:

  • <tube_factory_class_name>.dump - expects boolean string, if set to true turns on the logging before and after tube's processing
  • <tube_factory_class_name>.dump.before - expects boolean string, if set to true turns on the logging before tube's processing
    • overrides anything set by <tube_factory_class_name>.dump
  • <tube_factory_class_name>.dump.after - expects boolean string, if set to true turns on the logging after tube's processing
    • overrides anything set by <tube_factory_class_name>.dump
  • <tube_factory_class_name>.dump.level - expects string representing java.util.logging.Level, if set, overrides the default message dumping level for the class, which is java.util.logging.Level.INFO

There is a set of common system properties that control logging for all tubes and take the lowest precedence so that they can be overriden by a tube-specific properties:

  • com.sun.metro.soap.dump - expects a boolean string, if set to true turns on the message dumping before and after each tube's processing on both sides client and endpoint
  • com.sun.metro.soap.dump.before/after - expects a boolean string, if set to true turns on the message dumping before/after each tube's processing on both sides client and endpoint.
  • com.sun.metro.soap.dump.client/endpoint - expects a boolean string, if set to true turns on the message dumping before and after each tube's processing on the respective side (client or endpoint).
  • com.sun.metro.soap.dump.client/endpoint.before/after - expects a boolean string, if set to true turns on the message dumping before/after each tube's processing on the respective side (client or endpoint).
  • com.sun.metro.soap.dump.level and com.sun.metro.soap.dump.client/endpoint.level - controls the logging level for the whole tubeline
The logger root used for message dumping is <tube_factory_class_name>.

Most of the factories create tubes on both client and endpoint side. To narrow down the message dumping scope, following system properties can be used:

  • <tube_factory_class_name>.dump.client/endpoint - expects boolean string, if set to true turns on the logging before and after tube's processing
    • overrides anything set by <tube_factory_class_name>.dump
  • <tube_factory_class_name>.dump.client/endpoint.before - expects boolean string, if set to true turns on the logging before tube's processing
    • overrides anything set by <tube_factory_class_name>.dump and/or <tube_factory_class_name>.dump.client/endpoint
  • <tube_factory_class_name>.dump.client/endpoint.after - expects boolean string, if set to true turns on the logging after tube's processing
    • overrides anything set by <tube_factory_class_name>.dump and/or <tube_factory_class_name>.dump.client/endpoint
  • <tube_factory_class_name>.dump.client/endpoint.level - expects string representing java.util.logging.Level, if set, overrides anything set by <tube_factory_class_name>.level and or the default message dumping level for the class, which is java.util.logging.Level.INFO

2.6.1.1. Examples

In the following examples we will be working with the metro-default.xml file that defines the default Metro tubeline and looks like this:


<metro xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/metro/config" version="1.0">
    <tubelines default="#default-metro-tubeline">
        <tubeline name="default-metro-tubeline">
            <client-side>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.TerminalTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.HandlerTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.ValidationTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.MustUnderstandTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.MonitoringTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.AddressingTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.tx.runtime.TxTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.rx.rm.runtime.RmTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.rx.mc.runtime.McTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.wss.provider.wsit.SecurityTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.dump.ActionDumpTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.rx.testing.PacketFilteringTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.dump.MessageDumpingTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.TransportTubeFactory"></tube-factory>
            </client-side>
            <endpoint-side>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.TransportTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.dump.MessageDumpingTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.rx.testing.PacketFilteringTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.dump.ActionDumpTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.wss.provider.wsit.SecurityTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.rx.mc.runtime.McTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.AddressingTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.rx.rm.runtime.RmTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.tx.runtime.TxTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.MonitoringTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.MustUnderstandTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.HandlerTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.ValidationTubeFactory"></tube-factory>
                <tube-factory className="com.sun.xml.ws.assembler.jaxws.TerminalTubeFactory"></tube-factory>
            </endpoint-side>
        </tubeline>
    </tubelines>
</metro>
                

Example 1

To turn on the the message dumping before and after security tube's processing on both, client and endpoint side, following system property needs to be set to true:

com.sun.xml.wss.provider.wsit.SecurityTubeFactory.dump=true
com.sun.xml.wss.provider.wsit.SecurityTubeFactory.dump=true
                    

Example 2

To turn on the the message dumping only after security tube's processing on both, client and server side, following system property needs to be set to true:

com.sun.xml.wss.provider.wsit.SecurityTubeFactory.dump.after=true
com.sun.xml.wss.provider.wsit.SecurityTubeFactory.dump.after=true
                    

Example 3

To turn on the the message dumping only after security tube's processing only on the client side, following system property needs to be set to true:

com.sun.xml.wss.provider.wsit.SecurityTubeFactory.dump.client.after=true
com.sun.xml.wss.provider.wsit.SecurityTubeFactory.dump.client.after=true
                    

Example 4

This example sets message dumping before and after security processing, except for before security processing on the endpoint side. The logging level for message dumps is set to FINE on both sides:

com.sun.xml.wss.provider.wsit.SecurityTubeFactory.dump=true
com.sun.xml.wss.provider.wsit.SecurityTubeFactory.dump.endpoint.before=false
com.sun.xml.wss.provider.wsit.SecurityTubeFactory.dump.level=FINE
                    

2.6.2. Dumping SOAP messages on client

2.6.2.1. Transport level dump

One of the things people want to do while developing Web Services is to look at what the client is sending and receiving. To monitor soap traffic, there are some GUI tools like TCP Monitor and WSMonitor. These monitors are implemented with a 'man in the middle' approach where-in, the monitor listens to a port (Client send requests to this port) and forwards it to another port (Server listens to this port). Since these tools use port forwarding, you need to change your Web Service client to send request to the port where the monitor listens (Especially, if you are using static clients generated by wsimport, the default endpoint address taken from the wsdl needs to be overidden by setting ENDPOINT_ADDRESS_PROPERTY on the proxy).

In JAX-WS, you can monitor the request and response messages without changing the client. When you invoke the Web Service, just pass the system property com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true, it prints out the request and response message.

If you are using an Apache Ant script to run your client, this system property can be set as a <jvmarg/> element:

Setting system properties via Ant

<project name="metro client" basedir=".">   
   <property environment="env"/>
   <property name="build.dir" location ="/files/hudson/workspace/jaxws-user-guide/build"/>
   <property name="build.classes.dir" location ="/classes"/>

   <target name="run">
      <java classname="client.MyClient" fork="yes">         
         <arg value="xxx"/>  <!-- optional args[0] sent to MyClient.main() -->
         <arg value="xxx"/>  <!-- optional args[1], etc. -->
         <classpath>
            <pathelement location=""/>
            <pathelement location="/lib/javaee.jar"/>
            <pathelement location="/lib/webservices-rt.jar"/>
            <pathelement location="/lib/activation.jar"/>
     </classpath>
         <jvmarg value="-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true"/>
      </java>
    </target>
</project>
                

Alternatively you can execute com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true; from your Java program to programatically enable/disable logging. Since you often run JAX-WS in a container where setting system properties can be tedious, you might find this easier.

With this switch enabled, you'll see message dumps like the following in System.out.

Sample dump

---[HTTP request]---
SOAPAction: 
Content-Type: text/xml
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><addNumbers xmlns="http://duke.example.org"><arg0>10</arg0><arg1>20</arg1></addNumbers></S:Body></S:Envelope>--------------------

---[HTTP response 200]---
Date: Thu, 17 Aug 2006 00:35:42 GMT
Content-type: text/xml
Transfer-encoding: chunked
Server: Apache-Coyote/1.1
null: HTTP/1.1 200 OK

<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><addNumbersResponse xmlns="http://duke.example.org"><return>30</return></addNumbersResponse></S:Body></S:Envelope>--------------------
                

A similar property com.sun.xml.ws.transport.local.LocalTransportPipe.dump=true is available for the local transport.

2.6.2.2. Transport-agnostic dump

The dump mechanism explained above allows you to get the actual bytes that are sent over the wire, as well as any transport specific information (such as HTTP headers), but the mechanism is different from transports to transports. JAX-WS also defines a transport-agnostic dump, which works regardless of what transport you use.

This dump happens after JAX-WS parses the incoming message into XML infoset. So you will not be able to investigate a well-formedness error with this dump.

To enable such dump, set the system property com.sun.xml.ws.util.pipe.StandaloneTubeAssembler.dump=true or execute that as a Java program.

2.6.3. Dumping SOAP messages on server

You can dump incoming HTTP requests and responses to System.out on the server side by using the system property com.sun.xml.ws.transport.http.HttpAdapter.dump=true. This works exactly like above (except that this works on server, not client.) You can also set this property programatically by executing com.sun.xml.ws.transport.http.HttpAdapter.dump=true; as Java progrma.

The transport agnostic dump as explained above also works on the server for incoming messages and responses.


Terms of Use; Privacy Policy; Copyright ©2013-2014 (revision 20140418.2d69abc)
 
 
Close
loading
Please Confirm
Close