JBossWS records' collection and management system gives administrators a means of performing custom analysis of their webservice traffic as well as exporting communication logs.
What is recorded
Each record is basically composed of a message plus additional information; here are the current record attributes:
- Creation date
- Source host
- Destination host
- Message type (in/out)
- Invoked endpoint operation
- Message envelope (including both soap:header and soap:body for SOAP messages)
- Http headers
- Record group ID (allowing records belonging to the same message flow to be linked together)
Of course records may also have meaningful values for a subset of the afore mentioned record attributes.
What are records useful for? In spite of endpoint metrics that provide response time information and counts of invocations, records provide users with rich data about the content of the exchanged messages and their sender/receiver. The record system allows fine grained management and is customizable according to the users need; some of the use cases supported by the default configuration are:
- Logging request and response messages: being able to record messages received from and sent to a given service consumer without stopping the provider may be really useful. You just need to set the recording attribute of their endpoint's LogRecorder to true. The added value of this logging solution comes from the use of filters through which messages coming from a given address and related to a given wsdl operation only can be logged.
- Accountability: service providers may want to know which consumers are actually hitting a given service. This can be done for example using the getClientHosts functionality of the MemoryBufferRecorder once it has been switched to recording state.
- Getting statistics, filtering records: service administrators might want to see the last records related to a given endpoint or operation, the last records related to messages coming from a given customer and the response the system gave them, etc. These information can be obtained using the getRecordsByOperation, getRecordsByClientHost or the more general getMatchingRecords functionality of the MemoryBufferRecorder.
How it works and how to use it
The recording system is composed of
- JAX-WS handlers intercepting inbound and outbound communication
- Record processors plugged into deployed endpoints; handlers collect records and send them to every processors through the current endpoint. Processors may store records, convert them, log them, ...
- MBean views of processors that can be used to configure and fine tune recording at runtime
- Record filters allowing selection of information to be recorded as well as providing means of performing custom queries on the saved records.
On server side records are collected by JAX-WS handlers and passed to the configured processors. JBossWS comes with two default record processors that are plugged into every endpoint during the deployment:
- LogRecorder: a simple record processor that writes records to the configured log.
- MemoryBufferRecorder: a record processor that keeps the last received records in memory and allows user to search / get statistics on them.
Every processors can be fine tuned to process some record attributes only according to the user and/or performance requirements. Default processors are not in recording mode upon creation, thus you need to switch them to recording mode through their MBean interfaces (see the Recording flag in the jmx-console).
Common processor properties and their respective defaults values are:
- processDestinationHost (true)
- processSourceHost (true)
- processHeaders (true)
- processEnvelope (true)
- processMessageType (true)
- processOperation (true)
- processDate (true)
- recording (false)
The recorders can be configured in the stacks bean configuration
<!-- Installed Record Processors--> <bean name="WSMemoryBufferRecorder" class="org.jboss.wsf.framework.management.recording.MemoryBufferRecorder"> <property name="recording">false</property> </bean> <bean name="WSLogRecorder" class="org.jboss.wsf.framework.management.recording.LogRecorder"> <property name="recording">false</property> </bean>
The recording system is available for all the JBossWS supported stacks. However slightly different procedure is required to enable it depending on the used stack.
- Native stack
Native stack comes with JBossWS - JAX-WS Endpoint Configuration. The default standard endpoint already has the server side recording handler:
<endpoint-config> <config-name>Standard Endpoint</config-name> <pre-handler-chains> <javaee:handler-chain> <javaee:protocol-bindings>##SOAP11_HTTP</javaee:protocol-bindings> <javaee:handler> <javaee:handler-name>Recording Handler</javaee:handler-name> <javaee:handler-class>org.jboss.wsf.framework.invocation.RecordingServerHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </pre-handler-chains> </endpoint-config>
thus nothing is required to use it since it is automatically installed in the pre-handler-chain. Of course you might want to add it to other endpoint configurations you're using.
- Metro and CXF stacks
Other stacks require users to manually add the org.jboss.wsf.framework.invocation.RecordingServerHandler to their endpoint handler chain. This can be done the same way common user handlers are added.
Once the handler is properly added to the chain, log recording configuration is agnostic to the used stack. Users just need to tune the processors parameters though their MBean interfaces.
JMX management of processors is of course available on server side only. However users might also be interested in collecting and processing records on client side. Since handlers can be set on client side too, customer handlers could be configured to capture messages almost like the RecordingServerHandler does. This is left to the users since it is directly linked to their custom needs. For instance a common use could be to pass client side collected records to the LogRecorder.
Adding custom recorders
As previously said, the recording system is extensible: JBossWS users can write their own processors and plug them at runtime into their deployed endpoints through the addRecordProcessor functionality of the ManagedEndpoint MBean. Every processor needs to implement the org.jboss.wsf.spi.management.recording.RecordProcessor interface. Then you can choose one of the two following options:
- Give you record processor an MBean interface declaring the manageable attributes: the recording system will plug your processor to the endpoint and register a management MBean for it using your interface. This allows you to create highly configurable custom processors. For an example of this development option, take a look at the org.jboss.wsf.framework.management.recording.MemoryBufferRecorder.
- Add your record processor to the managed endpoint as is: the recording system will plug it to the endpoint and register a standard management MBean for its basic processing configuration. The org.jboss.wsf.framework.management.recording.LogRecorder is an example of this development option.
A code snippet showing how to get the MBeanProxy instance which you can invoke MBean with can be found here.
Of course the recording handler's position in the handler chain influences the collected records. As a matter of fact some information may or may not be available at a given point of the handler chain execution. The standard endpoint configuration declares the RecordingServerHandler into the pre-handler-chain. Speaking of the native stack, this means for example that you'll get the invoked operation data and that decrypted messages will be recorded if using WS-Security, since the WS-Security handler runs in the post-handler-chain. Users might want to change the recording handler's position in the chain according to their requirements.
Records attributes include a record group ID that is meant to link records whose messages belong to the same message flow (a request-response for example). In order to set the right group ID to the records, the current ID is associated to the thread that is processing the endpoint invocation. This means that multiple related records can be linked together and extracted together from a processor.
For this reason, you might want to install multiple recording handlers into different points of the handler chain. For instance, it could make sense to record messages both before and after encryption/decryption when using WS-Security.
This paragraph covers eventual future extensions and/or idea JBossWS users may want to leverage for their own business.
The MemoryBufferRecorder provides interesting functionalities to query the collected records set. For obvious reasons, records are discarded once a given size of the buffer is reached.
A DB based recorder could be developed; it should work the same way the MemoryBufferRecorder does, except for records that should be saved through a given datasource. This will provide persistence of data even in case of application server reboot and webservice application redeploy. It will also allow records coming from different node of a cluster to be stored together. Finally this would allow administrators to directly query the database, which might be far more efficient.
Custom log writer
The idea of getting statistics from collected records could be further exploited getting custom logs from the records. These logs could be outputted by a custom processor in standard or proprietary formats allowing them to be imported into eventual third-party log processing tools which might offer complex/funky graphic or statistic functionalities and so on.
You might want to take a look at the org.jboss.wsf.framework.management.recording and org.jboss.wsf.spi.management.recording packages in the source code to better understand how all this works and can be used.