Interface MatsTrace<Z>
-
- Type Parameters:
Z- The type which STOs and DTOs are serialized into. When employing JSON for the "outer" serialization of MatsTrace, it does not make that much sense to use a binary (Z=byte[]) "inner" representation of the DTOs and STOs, because JSON is terrible at serializing byte arrays.
- All Known Implementing Classes:
MatsTraceFieldImpl
public interface MatsTrace<Z>Together with theMatsSerializer, this interface describes one way to implement a wire-protocol for how Mats communicates. It is up to the implementation of theMatsFactoryto implement a protocol of how the Mats API is transferred over the wire. This is one such implementation that can be used, which is employed by the default JMS implementation of Mats.The MatsTrace is designed to contain all previous
MatsTrace.Calls in a processing, thus helping the debugging for any particular stage immensely: All earlier calls with data and stack frames for this processing is kept in the trace, thus enabling immediate understanding of what lead up to the particular situation.However, for any particular invocation (invoke, request or reply), only the current (last)
MatsTrace.Call- along with the stack frames for the same and lower stack depths than the current call - is needed to execute the stage. This makes it possible to use a condensed variant of MatsTrace that only includes the single currentMatsTrace.Call, along with the relevant stack frames. This is defined by theMatsTrace.KeepMatsTraceenum.One envisions that for development and the production stabilization phase of the system, the long form is used, while when the system have performed flawless for a while, one can change it to use the condensed form, thereby shaving some cycles for the serialization and deserialization, but more importantly potentially quite a bit of bandwidth and message processing compared to transfer of the full trace.
-
-
Nested Class Summary
Nested Classes Modifier and Type Interface Description static interfaceMatsTrace.Call<Z>Represents an entry in theMatsTrace.static classMatsTrace.KeepMatsTraceSpecifies how the MatsTrace will handle historic values that are present just for debugging.static interfaceMatsTrace.StackState<Z>The State instances (of type Z), along with the height of the stack the state relates to.
-
Field Summary
Fields Modifier and Type Field Description static java.lang.StringNULLEDString employed as return value for "debug only" fields which may as well be null - by setting them to null, we conserve time and space in the serialization (For JSON, even the field itself is not serialized if the value is null).
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description MatsTrace<Z>addGotoCall(java.lang.String from, java.lang.String to, Z data, Z initialState)MatsTrace<Z>addNextCall(java.lang.String from, java.lang.String to, Z data, Z state)Adds aNEXTCall, which is a "skip call" to the next stage in a multistage service, as opposed to the normal request out to a service expecting a reply.MatsTrace<Z>addReplyCall(java.lang.String from, Z data)Adds aREPLYCall, which happens when a requested service is finished with its processing and have some Reply to return.MatsTrace<Z>addRequestCall(java.lang.String from, java.lang.String to, MatsTrace.Call.MessagingModel toMessagingModel, java.lang.String replyTo, MatsTrace.Call.MessagingModel replyToMessagingModel, Z data, Z replyState, Z initialState)Adds aREQUESTCall, which is an invocation of a service where one expects a Reply from this service to go to a specified endpoint, typically the next stage in a multi-stage endpoint: Envision a normal invocation of some method that returns a value.MatsTrace<Z>addSendCall(java.lang.String from, java.lang.String to, MatsTrace.Call.MessagingModel toMessagingModel, Z data, Z initialState)Adds aSENDCall, meaning a "request" which do not expect a Reply: Envision an invocation of a void-method.java.util.List<MatsTrace.Call<Z>>getCallFlow()intgetCallNumber()MatsTrace.Call<Z>getCurrentCall()longgetCurrentSpanId()java.util.Optional<MatsTrace.StackState<Z>>getCurrentState()Returns theMatsTrace.StackStatefor thegetCurrentCall(), if present.java.lang.StringgetDebugInfo()java.lang.StringgetFlowId()longgetInitializedTimestamp()java.lang.StringgetInitializingAppName()java.lang.StringgetInitializingAppVersion()java.lang.StringgetInitializingHost()java.lang.StringgetInitiatorId()MatsTrace.KeepMatsTracegetKeepTrace()java.lang.StringgetParentMatsMessageId()If this is achild flowof an existing flow, this should return the MatsMessageId of the message whose processing spawned this new flow.longgetSameHeightEndpointEnteredTimestamp()longgetSameHeightOutgoingTimestamp()java.util.List<MatsTrace.StackState<Z>>getStateFlow()java.util.List<MatsTrace.StackState<Z>>getStateStack()longgetTimeToLive()intgetTotalCallNumber()"Stack overflow protection" mechanism.java.lang.StringgetTraceId()ZgetTraceProperty(java.lang.String propertyName)Retrieves a property value set bysetTraceProperty(String, Object), refer toProcessContext.getTraceProperty(String, Class).java.util.Set<java.lang.String>getTracePropertyKeys()booleanisInteractive()booleanisNoAudit()booleanisNonPersistent()voidsetOutgoingTimestamp(long timestamp)Shall be invoked after adding the outgoing call, immediately before serializing the outgoing MatsTrace.voidsetStageEnteredTimestamp(long timestamp)Invoke this as early as possible on the reception of a message.voidsetTraceProperty(java.lang.String propertyName, Z propertyValue)Sets a trace property, refer toProcessContext.setTraceProperty(String, Object).MatsTrace<Z>withChildFlow(java.lang.String parentMatsMessageId, int totalCallNumber)If this newly created MatsTrace is a child-flow (initiated within a Stage) of an existing flow, then this method should be invoked to set the parent MatsMessageId, and the "total call number" which is a "Call Overflow protection" mechanism.MatsTrace<Z>withDebugInfo(java.lang.String initializingAppName, java.lang.String initializingAppVersion, java.lang.String initializingHost, java.lang.String initiatorId, java.lang.String debugInfo)Can only be set once..
-
-
-
Field Detail
-
NULLED
static final java.lang.String NULLED
String employed as return value for "debug only" fields which may as well be null - by setting them to null, we conserve time and space in the serialization (For JSON, even the field itself is not serialized if the value is null). If they are null, the corresponding getter returns this value.- See Also:
- Constant Field Values
-
-
Method Detail
-
withDebugInfo
MatsTrace<Z> withDebugInfo(java.lang.String initializingAppName, java.lang.String initializingAppVersion, java.lang.String initializingHost, java.lang.String initiatorId, java.lang.String debugInfo)
Can only be set once..- Parameters:
initiatorId- the id set usingmatsInitiate.from(initiatorId)- it is not the name of the initiator.- Returns:
this, for chaining. Note that this is opposed to the add[Request|Send|Next|Reply]Call(..) methods, which return a new, independent instance.
-
withChildFlow
MatsTrace<Z> withChildFlow(java.lang.String parentMatsMessageId, int totalCallNumber)
If this newly created MatsTrace is a child-flow (initiated within a Stage) of an existing flow, then this method should be invoked to set the parent MatsMessageId, and the "total call number" which is a "Call Overflow protection" mechanism. Parent Mats Message Id: The MatsMessageId of the message whose processing spawned this new flow. Total Call Number: Initializes thegetTotalCallNumber(). If this message is initiated within an existing call flow, set to the current call'sgetTotalCallNumber()+ 1. This number will increase for every subsequent call this flow is going through, just as withgetCallNumber()- the difference being that it should continue increasing if a new message is initiated within a flow. Thereby it is possible to stop an out-of-control initiate-send/request recursion, by checking that thegetTotalCallNumber()doesn't ever go above a fixed number, e.g. 100.- Parameters:
parentMatsMessageId- the MatsMessageId of the message whose processing spawned this new flow.totalCallNumber- thegetTotalCallNumber()to initialize this MatsTrace with.- Returns:
this, for chaining. Note that this is opposed to the add[Request|Send|Next|Reply]Call(..) methods, which return a new, independent instance.
-
getTraceId
java.lang.String getTraceId()
- Returns:
- the TraceId that this
MatsTracewas initiated with - this is set once, at initiation time, and follows the processing till it terminates. (All log lines will have the traceId set on the MDC.)
-
getFlowId
java.lang.String getFlowId()
- Returns:
- the "FlowId", which is a system-specified, guaranteed-globally-unique TraceId - and shall be the prefix
of each
MatsTrace.Call.getMatsMessageId(), separated by a "_".
-
getInitializedTimestamp
long getInitializedTimestamp()
-
getKeepTrace
MatsTrace.KeepMatsTrace getKeepTrace()
- Returns:
- to which extent the Call history (with State) should be kept. The default is
MatsTrace.KeepMatsTrace.COMPACT.
-
isNonPersistent
boolean isNonPersistent()
- Returns:
- whether the message should be JMS-style "non-persistent", default is
false(i.e. persistent, reliable).
-
isInteractive
boolean isInteractive()
- Returns:
- whether the message should be prioritized in that a human is actively waiting for the reply, default is
false.
-
getTimeToLive
long getTimeToLive()
- Returns:
- the number of milliseconds the message should live before being time out. 0 means "forever", and is the default.
-
isNoAudit
boolean isNoAudit()
- Returns:
- a hint to the underlying implementation, or to any monitoring/auditing tooling on the Message Broker, that it does not make much value in auditing this message flow, typically because it is just a "getter" of information to show to some user, or a health-check validating that some service is up and answers in a timely fashion.
-
getInitializingAppName
java.lang.String getInitializingAppName()
-
getInitializingAppVersion
java.lang.String getInitializingAppVersion()
-
getInitializingHost
java.lang.String getInitializingHost()
-
getInitiatorId
java.lang.String getInitiatorId()
- Returns:
- a fictive "endpointId" of the initiator, see
MatsInitiator.MatsInitiate.from(String).
-
getDebugInfo
java.lang.String getDebugInfo()
-
getCallNumber
int getCallNumber()
- Returns:
- the number of calls that this MatsTrace have been through, i.e. how many times
MatsTrace.add[Request|Next|Reply..](..)has been invoked on this MatsTrace. This means that right after a new MatsTrace has been created, before a call has been added, 0 is returned. With KeepMatsTrace atFULLorCOMPACT, the returned number will be the same asgetCallFlow().size(), but withMINIMAL, that number of always 1, but this number will still return the number of calls that has been added through the flow. - See Also:
getTotalCallNumber()
-
getTotalCallNumber
int getTotalCallNumber()
"Stack overflow protection" mechanism.- Returns:
- the total call number, which is the same as
getCallNumber()unless this flow was initiated within a stage, in which case the totalCallNumber starts at the current call number at that stage (as set withwithChildFlow(String, int)). This ensures that if we end up with e.g. a mats flow initiating a new mats flow to itself, thus creating a loop, this number will continuously increase, and we can thus break out at some obviously-too-large value.
-
getParentMatsMessageId
java.lang.String getParentMatsMessageId()
If this is achild flowof an existing flow, this should return the MatsMessageId of the message whose processing spawned this new flow.- Returns:
- the MatsMessageId of the message whose processing spawned this new flow.
-
setTraceProperty
void setTraceProperty(java.lang.String propertyName, Z propertyValue)Sets a trace property, refer toProcessContext.setTraceProperty(String, Object). Notice that on the MatsTrace-side, the value must be of typeZ.- Parameters:
propertyName- the name of the property.propertyValue- the value of the property.- See Also:
getTracePropertyKeys(),getTraceProperty(String)
-
getTraceProperty
Z getTraceProperty(java.lang.String propertyName)
Retrieves a property value set bysetTraceProperty(String, Object), refer toProcessContext.getTraceProperty(String, Class). Notice that on the MatsTrace-side, the value is of typeZ.- Parameters:
propertyName- the name of the property to retrieve.- Returns:
- the value of the property.
- See Also:
setTraceProperty(String, Object),getTracePropertyKeys()
-
getTracePropertyKeys
java.util.Set<java.lang.String> getTracePropertyKeys()
- Returns:
- the set of keys containing
trace properties. - See Also:
getTraceProperty(String),setTraceProperty(String, Object)
-
addRequestCall
MatsTrace<Z> addRequestCall(java.lang.String from, java.lang.String to, MatsTrace.Call.MessagingModel toMessagingModel, java.lang.String replyTo, MatsTrace.Call.MessagingModel replyToMessagingModel, Z data, Z replyState, Z initialState)
Adds aREQUESTCall, which is an invocation of a service where one expects a Reply from this service to go to a specified endpoint, typically the next stage in a multi-stage endpoint: Envision a normal invocation of some method that returns a value.- Parameters:
from- which stageId this request is for. This is solely meant for monitoring and debugging - the protocol does not need the from specifier, as this is not where any replies go to.to- which endpoint that should get the request.toMessagingModel- theMatsTrace.Call.MessagingModelof 'to'.replyTo- which endpoint that should get the reply from the requested endpoint.replyToMessagingModel- theMatsTrace.Call.MessagingModelof 'replyTo'.data- the request data, most often a JSON representing the Request Data Transfer Object that the requested service expects to get.replyState- the state data for the stageId that gets the reply to this request, that is, the state for the stageId that is at the first element of the replyStack. Most often a JSON representing the State Transfer Object for the multi-stage endpoint.initialState- an optional feature, whereby the state can be set for the initial stage of the requested endpoint. Same stuff as replyState.
-
addSendCall
MatsTrace<Z> addSendCall(java.lang.String from, java.lang.String to, MatsTrace.Call.MessagingModel toMessagingModel, Z data, Z initialState)
Adds aSENDCall, meaning a "request" which do not expect a Reply: Envision an invocation of a void-method. Or an invocation of some method that returns the value, but where you invoke it as a void-method (i.e. not storing the result, e.g. the methodmap.remove("test")returns the removed value, but is often invoked without storing this.).- Parameters:
from- which stageId this request is for. This is solely meant for monitoring and debugging - the protocol does not need the from specifier, as this is not where any replies go to.to- which endpoint that should get the message.toMessagingModel- theMatsTrace.Call.MessagingModelof 'to'.data- the request data, most often a JSON representing the Request Data Transfer Object that the receiving service expects to get.initialState- an optional feature, whereby the state can be set for the initial stage of the requested endpoint.
-
addNextCall
MatsTrace<Z> addNextCall(java.lang.String from, java.lang.String to, Z data, Z state)
Adds aNEXTCall, which is a "skip call" to the next stage in a multistage service, as opposed to the normal request out to a service expecting a reply. The functionality is functionally identical toaddSendCall(String, String, MessagingModel, Object, Object)addSendCall(...)}, but has its ownCallTypeenum valueNEXT. Note: Cannot specifyMatsTrace.Call.MessagingModelhere, as one cannot fathom where that would make sense: It must beQUEUE.- Parameters:
from- which stageId this request is for. This is solely meant for monitoring and debugging - the protocol does not need the from specifier, as this is not where any replies go to.to- which endpoint that should get the message - the next stage in a multi-stage service.data- the request data, most often a JSON representing the Request Data Transfer Object that the next stage expects to get.state- the state data for the next stage.
-
addReplyCall
MatsTrace<Z> addReplyCall(java.lang.String from, Z data)
Adds aREPLYCall, which happens when a requested service is finished with its processing and have some Reply to return. This method pops the stack (takes the last element) from the (previous) current call, sets this as the "to" parameter, and uses the rest of the list as the stack for the next Call.- Parameters:
from- which stageId this request is for. This is solely meant for monitoring and debugging - the protocol does not need the from specifier, as this is not where any replies go to.data- the request data, most often a JSON representing the Request Data Transfer Object that the requesting service expects to get.
-
addGotoCall
MatsTrace<Z> addGotoCall(java.lang.String from, java.lang.String to, Z data, Z initialState)
- Parameters:
data- the request data, most often a JSON representing the Request Data Transfer Object that the passed-to endpoint expects to get.initialState- an optional feature, whereby the state can be set for the initial stage of the requested endpoint.
-
setOutgoingTimestamp
void setOutgoingTimestamp(long timestamp)
Shall be invoked after adding the outgoing call, immediately before serializing the outgoing MatsTrace.- Sets the outgoing Call's
MatsTrace.Call.getCalledTimestamp()to be more closely aligned to the exact sending time. (For example, the message may have been constructed, then a massive SQL query was performed, and then a new message is constructed, and then the messages are actually turned into JMS messages and committed on the wire. This means that the first message will have a much earlier timestamp than the second.) Using this method, all outgoing messages can have the Called Timestamp set right before it is serialized and JMS-constructed and committed. - If the
getCurrentCall()is a REQUEST, SEND, GOTO or PUBLISH (anything else than REPLY), it also sets the same-height-called-timestamp, recorded on the stackframe below it, or on the MatsTrace itself if there is no stackframe below (initial SEND). This is to be able to calculate the "time between stages" for the e.g. time between stage1 and stage2 of a multi-stage endpoint, noting that this might entail multiple levels of Request and Replies (thus it must reside on the stack).
- Sets the outgoing Call's
-
getSameHeightOutgoingTimestamp
long getSameHeightOutgoingTimestamp()
- Returns:
- the timestamp set by
setOutgoingTimestamp(long)for the preceding call on the same stack height. Used to calculate the "time between stages" for the different stages on an endpoint. It does not make sense to get this for the initial stage of an Endpoint if the incoming is a REQUEST, and the return value will then be-1.
-
setStageEnteredTimestamp
void setStageEnteredTimestamp(long timestamp)
Invoke this as early as possible on the reception of a message. Used to calculate the "total endpoint time", through all stages (including intermediate request/replies): Time from entry on the Initial Stage, to when the endpoint Replies, or stops (no outgoing message).
-
getSameHeightEndpointEnteredTimestamp
long getSameHeightEndpointEnteredTimestamp()
- Returns:
- the value of
setStageEnteredTimestamp(long)for the stages of the same endpoint. Used to calculate the "total endpoint time", through all stages, when the endpoint Replies, or stops (no outgoing message).
-
getCurrentSpanId
long getCurrentSpanId()
- Returns:
- this MatsTrace's SpanId. If it is still on the initiator side, before having had a call added to it, or
on the terminator side, when the stack again is empty, the SpanId is derived from the
FlowId. Otherwise, it is the topmost element of an internal stack, in the same way asgetCurrentCall().MatsTrace.Call.getReplyStack().
-
getCurrentCall
MatsTrace.Call<Z> getCurrentCall()
-
getCurrentState
java.util.Optional<MatsTrace.StackState<Z>> getCurrentState()
Returns theMatsTrace.StackStatefor thegetCurrentCall(), if present. Searches in the'State Flow'from the back (most recent) for the first element that is at the current stack height, as defined bygetCurrentCall().MatsTrace.Call.getReplyStackHeight(). If a more shallow stackDepth than the specified is encountered, or the list is exhausted without the Stack Height being found, the search is terminated with null. This happens for the initial stage for an endpoint, unless the 'initialState' was set on the SEND or REQUEST. The point of the 'State Flow' is the same as for the Call list: Monitoring and debugging, by keeping a history of all calls in the processing, along with the states that was present at each call point. If "condensing" is on (COMPACTorMINIMAL), the stack-state-list is - by the condensing algorithm - turned in to a pure stack (as available viagetStateStack()), with the StackState for the earliest stack element at position 0, while the latest (current) at end of list. The above-specified search algorithm still works, as it now will either find the element with the correct stack depth at the end of the list, or it is not there. NOTE: The StateStack (mostly) includes a frame for the current call, as opposed to theMatsTrace.Call.getReplyStack()(reply stack), which only includes frames below us. Note that as a matter of avoiding space use, on a REQUEST call, the StackState is not added for the actual REQUEST message's state stack, unless the "initial incoming state" is supplied (which is uncommon - a service invocation typically starts with an empty state). However, on REPLY messages, it will always be present, and hence the state stack is typically one level higher (includes current frame) than the reply stack (only includes frames below). NOTE: As further info on how the state stack relates to the reply stack height: When a REPLY comes to a terminator, there are 0 more frames below. However, the terminator needs its state, which is at state stack height 0.- Returns:
- the
MatsTrace.StackStatefor thegetCurrentCall()if it exists,nullotherwise, as is typical when entering initial stage of an endpoint.
-
getStateStack
java.util.List<MatsTrace.StackState<Z>> getStateStack()
- Returns:
- the stack of the states for the current stack: getCurrentCall().getStack().
- See Also:
for more information on how the "State Flow" works.
-
getCallFlow
java.util.List<MatsTrace.Call<Z>> getCallFlow()
- Returns:
- the flow of calls, from the first REQUEST (or SEND), to the
current call- unlessKeepTraceis MINIMAL, in which case only the current call is present in the list.
-
getStateFlow
java.util.List<MatsTrace.StackState<Z>> getStateFlow()
- Returns:
- the entire list of states as they have changed throughout the call flow. If
MatsTrace.KeepMatsTraceis COMPACT or MINIMAL, then it will be a pure stack (as returned withgetStateStack(), with the last element being the most recent stack frame. NOTICE: The index position in this list has little to do with which stack level the state refers to. This must be gotten fromMatsTrace.StackState.getHeight(). - See Also:
for more information on how the "State Flow" works.
-
-