Transaction tracking user exit sample
The AceSpanTraceExample user exit sample demonstrates how you can use a user exit to capture flow context information, which could then be used to implement a simple span trace for message flows that contain HTTP, Kafka, or MQ transport nodes.
A span trace can be used to track transactions across multiple components, so that you can see how the transactions have been routed through the components. This approach typically passes a span identifier from one component to another, through transport headers, to allow the transaction to be correlated; this enables you to see a broader view of the transactions than you could see if you used a separate trace for each individual component.
If you run an integration server with this sample user exit enabled, an MQ queue on
the integration server's default queue manager (AceSpanTraceExample
) is used to
write a span summary message each time a flow with an MQ, Kafka, or HTTP
transport input node processes a message. The user exit reads or writes a span identifier when the
flow inputs or outputs an MQ, Kafka, or HTTP message.
The AceSpanTraceExample sample is in the install_dir\sample\extensions\userexits\transports directory, and the loadable exit library is called AceSpanTraceExample.lel.
The AceSpanTraceExample is a C++ implementation that uses the App Connect Enterprise interface defined through the MqsiTransportUserExitBase class, which uses C user exit callbacks to show how a message flow span trace might be implemented. The logic of the exit is implemented in the AceSpanTraceExample.hpp/cpp.
onTransportInputMessage
This callback informs the user exit that an MQInput, HTTPInput, SOAPInput, HTTPAsyncResponse, SOAPAsyncResponse, or KafkaConsumer node has received a message, and signals the start of a message flow processing span. The callback provides the message flow and node context and any requested headers, such as MQ MQRFH2 header fields, HTTP headers, or Kafka properties.
beforeTransportOutputMessage
This callback informs the user exit that an MQOutput, HTTPRequest, HTTPAsyncRequest, SOAPRequest, SOAPAsyncRequest, RESTRequest, RESTAsyncRequest, or KafkaProducer node is about to emit a message. This callback allows the user exit to set any required headers in the output message, such as MQ MQRFH2 header fields, HTTP headers, or Kafka properties.
afterTransportOutputMessage
This callback informs the user exit that an MQOutput, HTTPRequest, HTTPAsyncRequest, SOAPRequest, SOAPAsyncRequest, RESTRequest, RESTAsyncRequest, or KafkaProducer node has emitted a message. This callback allows the user exit to receive details of the message emitted and its destination, such as MQ
MQMD.msgid
.onTransportResponseMessage
This callback informs the user exit that an HTTPRequest, SOAPRequest, or RESTRequest node has received a response message. The callback provides the message flow and node context and any requested headers.
beforeTransportGetMessage
This callback informs the user exit that an MQGet or KafkaRead node is about to start a read operation to attempt to get a message.
onTransportGetMessage
This callback informs the user exit that an MQGet or KafkaRead node has received a message. The callback allows the user exit to obtain required headers from the received message, such as MQ MQRFH2 header fields or Kafka properties.
onTransportTransactionComplete
This callback informs the user exit that a message flow processing span, which started at an
onTransportInputMessage
, is complete. The callback allows the user exit to access the completion status and any last exception code.
- MqsiTransportUserExitBase
- MqsiUserExitWrapper
onTransportResponseMessage
or onTransportGetMessage
callback is invoked each time a message is propagated to
the directly connected output connections:- HTTPRequest
- RESTRequest
- SOAPRequest
- MQGet
- KafkaRead
UserExits:
activeUserExitList: 'AceSpanTraceExample'
userExitPath: '<path>'
The user exit path defines
the directory or set of directories that the integration server's
exit manager inspects to see whether there are any loadable exit library
files. When an integration server starts and finds the sample loadable
exit library, it calls its onStartServer
function
and passes context information including the name of the integration
server and the version at which the integration server is running,
and also allows the sample to register the name of a span trace example.
If that name matches an entry in the activeUserExitList
,
the transport-specific callback functions in this library are invoked
by the integration server when messages are processed by the message
flows.
The onStartServer
callback in this example also provides a data structure of
transports for which it should be called (either HTTP, Kafka, or MQ) and
field names and locations that the functions in the user exit library will be passed (on an input
message) or set (on an output message).
The exit callbacks in the sample are called from message flow nodes that interact with the MQ, Kafka, or HTTP transport. All these transports receive message flow context information including server name, application name, library name, message flow name, and message flow node name and type. Additionally, they are passed data from fields as defined in the example data structure table. For example, the following table defines the data structure for HTTP:
Transport | Location | Field name |
---|---|---|
HTTP | HTTPHeader | traceparent |
HTTP | HTTPHeader | tracestate |
HTTP | HTTPHeader | x-remote-addr |
- The
onTransportInputMessage
receives any headers that are found in the input, such astraceparent
,tracestate
, andx-remote-addr
. It sets a new value fortraceparent
and then saves the values in the environment, which can then be accessed from other message flow nodes that are involved in the trace.For example, you could have a message flow containing an HTTPInput node, and the
onStartServer
function has registered the data structure and specified that it should be called for HTTP transport messages. When the HTTPInput node receives a message, it checks to see whether it needs to invoke the user exit, based on the information in the transport section. If it does need to invoke the user exit, it performs a lookup in the message assembly to extract the values that are available, then calls theonTransportInputMessage
function that is implemented in the user exit library. In addition to the data structure, it also passes some flow context information, such as the name of the integration server, the application, the message flow name, the message flow node name and type, and the transport type of the message flow node that has called this user exit.The sample implements this user exit interface. The sample receives the headers and sets a new value for
traceparent
(traceParent = TraceStartedinACE
), which appears in the span context. The sample also sets a value for theAceTrace
environment variable by usingsetEnvironmentValue(name)
, which provides an audit trail of the nodes that have called the user exit. - The
beforeTransportOutputMessage
function retrieves the value oftraceparent
from the environment by usinggetEnvironmentValue(name)
, and appends the name of the current message flow node to theAceTrace
environment variable. The outbound HTTPOutputHeader is then set (traceparent=traceparent+"flow-context"
) and the returned values are updated into the output message header.For example, you could have an HTTPRequest node that is about to send an output message. The transport type has been checked, and it has been determined that the callback function in the user exit library needs to be invoked. The data that is relevant to the HTTP transport is passed over, and the message flow exit is invoked with the flow context information. The sample then appends the information about the current message flow (such as the message flow name, application name, and message flow node name) into the
AceTrace
environment variable, which is recording the audit trail of nodes that have caused the user exit to be invoked. The sample also retrieves thetraceparent
that was set by the HTTPInput node, and concatenates that with the flow context information. The HTTPRequest node has now been added onto the end of thetraceparent
in the environment, which was previously set by the HTTPInput node. The information in the data structure is updated into the message assembly and set into the outbound HTTP header. - The
onTransportResponseMessage
allows the user exit to record the arrival of a response message from an HTTP request. - The
beforeTransportGetMessage
signals that a mid-flow Get or Read message flow node is about to start a get or read operation on the transport. - The
onTransportGetMessage
signals that a mid-flow Get or Read message flow node has received a message from a transport and provides trace data from it. - The
onTransportTransactionComplete
message is used by the user exit to complete the span trace and issue a summary message to an MQ queue on the integration server's default queue manager (AceSpanTraceExample
). - The
afterTransportOutputMessage
retrieves information from the transport relating to the message that has been transmitted. For HTTP, this would include the HTTPRequestURL
.