Most applications that use Ultra Messaging (UM) are already logging a lot of application specific data. Sometimes, these logs can be as large as multiple gigabytes, per day! So it is understandable that users will want to keep their UM specific items to a minimum and focus on the application logging. That being said, there is some crucial data that should be logged pertaining to the Ultra Messaging Persistence (UMP) framework as, without this data, debugging problems related to messaging can be near impossible. This sample offers you the data that is most important to log, and the reason why this data is so important to track.
There is one program source file:
Standard context and receiver creation. Note the message handler function passed into the receiver create function, this is the callback function that will handle all the receiver callback events.
00014 ReceiverCallback myReceiverCallback = new ReceiverCallback(); 00015 00016 /*** Initialization: create necessary UM objects. ***/ 00017 ctx = new LBMContext(); 00018 00019 rtopic = new LBMTopic(ctx, "test.topic"); 00020 rcv = new LBMReceiver(ctx, rtopic, myReceiverCallback, null);
Here is the message callback. The message callback function is a single function that can be coded to deal with many different callback events. Only a single event is processed at a time, therefore a switch statement works best for handling the different types of events that are possible. Below is a description of each event, as well as which data is useful to log, as well as how important it is to log such data in the applications log file.
This is the message type used for handling received messages. If your application is already printing the data from every message, then it would be worth logging the Ultra Messaging sequence number, topic string, and the flags in the message data structure. The sequence number can help us keep track of what messages this particular receiver consumed, the topic will help identify the receiver, and the flags can identify whether the messages are coming directly from a source or being recovered from a store.
If your application is not regularly logging data messages because it would grow the application logs too large, then this data can be skipped. However, it would be useful to have the ability to enable logging as part of some kind of application debug mode.
00034 case LBM.MSG_DATA: 00035 System.out.print("[" + msg.topicName() + "][" + msg.source() + "][" + msg.sequenceNumber() + "]"); 00036 if ((msg.flags() & LBM.MSG_FLAG_UME_RETRANSMIT) != 0) { 00037 System.out.print("-RX-"); 00038 } 00039 if ((msg.flags() & LBM.MSG_FLAG_OTR) != 0) { 00040 System.out.print("-OTR-"); 00041 } 00042 System.out.print(", "); 00043 System.out.println(msg.data().length + " bytes"); 00044 break;
Similar to data messages above, the only real difference being that these messages can be responded to via the API.
00045 case LBM.MSG_REQUEST: 00046 if ((msg.flags() & LBM.MSG_FLAG_UME_RETRANSMIT) != 0) { 00047 System.out.print("-RX-"); 00048 } 00049 if ((msg.flags() & LBM.MSG_FLAG_OTR) != 0) { 00050 System.out.print("-OTR-"); 00051 } 00052 System.out.print(", "); 00053 System.out.println(msg.data().length + " bytes"); 00054 break;
This event indicates that a single message has been declared unrecoverable, and will not be received by the application. This should always be logged. Unrecoverable Loss in a UMP environment is typically not expected and indicates a failure of the transport level recovery, so this event should be logged every time, with the topic name, the sequence number provided, and the source information. The source information will identify the source publishing the messages that have been lost.
00061 case LBM.MSG_UNRECOVERABLE_LOSS: 00062 System.err.println("[" + msg.topicName() + "][" + msg.source() + "][" + Long.toHexString(msg.sequenceNumber()) + "], LOST"); 00063 break;
Similar to regular loss, but indicates a larger gap of messages have been decalred unrecoverable. Same as above, this should always be logged. Since this indicates a large number of messages that are unrecoverable, it is even more important to log all the data provided in the message data structure (topic name, sequence number, and source information). See sample handle_burst for more information on handling burst loss
00064 case LBM.MSG_UNRECOVERABLE_LOSS_BURST: 00065 System.err.println("[" + msg.topicName() + "][" + msg.source() + "][" + Long.toHexString(msg.sequenceNumber()) + "], LOST BURST"); 00066 break;
BOS indicates that a new transport session has been detected in which messages will be received on for a specific source transport. This callback should be logged, as it is useful when trying to debug connectivity issues. This should always be logged with the topic name and source information.
00055 case LBM.MSG_BOS: 00056 System.out.println("[" + msg.topicName() + "][" + msg.source() + "], Beginning of Transport Session"); 00057 break;
Similar as BOS, this indicates that there has been no activity on a transport and that the transport has timed out. This should always be logged with the same information as BOS.
00058 case LBM.MSG_EOS: 00059 System.out.println("[" + msg.topicName() + "][" + msg.source() + "], End of Transport Session"); 00060 break;
The no source notifcation callback is not enabled by default, and must be configured with resolution_no_source_notification_threshold . For more information on setting this callback, please see sample: no_source_notify. Logging this callback is entirely up to the developer, however it could also be useful when trying to debug connectivity issues.
00067
This callback event indicates an error while trying to register with a UMP store. This should be logged every time along with the topic name and error string provided in the callback.
00068 case LBM.MSG_UME_REGISTRATION_ERROR: 00069 System.out.println("[" + msg.topicName() + "][" + msg.source() + "] UME registration error: " + msg.dataString()); 00070 break;
This callback is executed every time the receiver registers to a particular store, and very much is worth logging. In particular, the topic name, store information, receiver and source RegID.s, flags, and registered sequence number. The sequence number here indicates where the store thinks this receiver is at, and is one of the deciding factors when determining the starting sequence number for the receiver. The source and receiver RegID are useful for tracking those components in the store log and store web-monitor.
00071 case LBM.MSG_UME_REGISTRATION_SUCCESS_EX: 00072 UMERegistrationSuccessInfo reg = msg.registrationSuccessInfo(); 00073 System.out.println("[" + msg.topicName() + "][" + msg.source() + "] store " + reg.storeIndex() + ": " 00074 + reg.store() + " UME registration successful. Sequence number is " + reg.sequenceNumber()); 00075 break;
This callback is only executed once per registration, regardless of the number of stores. Complete indicates that a quorum of stores has been registered, and the receiver is ready to start receiving messages. It is important to log the topic name, the source and receiver RegID.s, flags, and the consensus sequence number . as this is the first sequence number the receiver should consume going forward.
00076 case LBM.MSG_UME_REGISTRATION_COMPLETE_EX: 00077 UMERegistrationCompleteInfo regcomplete = msg.registrationCompleteInfo(); 00078 System.out.println("[" + msg.topicName() + "][" + msg.source() + "] UME registration complete. SQN " 00079 + regcomplete.sequenceNumber() + ". Flags " + regcomplete.flags()); 00080 break;
This callback should be logged when using the Receiver Paced Persistence mode of operation or when using the deregistration AP. It indicates that the receiver deregistered from a particular store. The source and receiver RegID, sequence number, store information, and flags should be logged here.
00081 case LBM.MSG_UME_DEREGISTRATION_SUCCESS_EX: 00082 System.out.print("DEREGISTRATION SUCCESSFUL "); 00083 UMEDeregistrationSuccessInfo dereg = msg.deregistrationSuccessInfo(); 00084 System.out.print("[" + msg.topicName() + "][" + msg.source() + "] store " + dereg.storeIndex() + ": " 00085 + dereg.store() + " UME deregistration successful. SrcRegID " + dereg.sourceRegistrationId() + " RcvRegID " + dereg.receiverRegistrationId() 00086 + ". Flags " + dereg.flags() + " "); 00087 System.out.println(); 00088 break;
.Similar to the deregistration success callback; this callback indicates that the receiver has successfully deregistered from all stores, and should be logged. Topic name and source information are sufficient for this callback.
00089 case LBM.MSG_UME_DEREGISTRATION_COMPLETE_EX: 00090 System.out.println("DEREGISTRATION COMPLETE"); 00091 break;
This callback should be logged as it indicates a change in the registration status for a particular topic. Topic name, source information, and the message data should be printed here. The message data will have the change that has been made to registration.
00092 case LBM.MSG_UME_REGISTRATION_CHANGE: 00093 System.out.println("[" + msg.topicName() + "][" + msg.source() + "] UME registration change: " + msg.dataString()); 00094 break;
Lastly, it is a good idea to have a default case to log anything that the application is not expecting. As of writing this sample, there are no other callbacks that could be handled for UMP. However, new callbacks are added, so it's good in the event of a library upgrade.
00095 default: 00096 System.out.println("Other event, type=" + msg.type()); 00097 break;