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.
00017 LBMReceiverCallback myReceiverCallback = new LBMReceiverCallback(onReceive); 00018 00019 /*** Initialization: create necessary UM objects. ***/ 00020 ctx = new LBMContext(); 00021 00022 rtopic = new LBMTopic(ctx, "test.topic"); 00023 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.
00036 case LBM.MSG_DATA: 00037 System.Console.Out.Write("[" + msg.topicName() + "][" + msg.source() + "][" + msg.sequenceNumber() + "]"); 00038 if ((msg.flags() & LBM.MSG_FLAG_UME_RETRANSMIT) != 0) { 00039 System.Console.Out.Write("-RX-"); 00040 } 00041 if ((msg.flags() & LBM.MSG_FLAG_OTR) != 0) { 00042 System.Console.Out.Write("-OTR-"); 00043 } 00044 System.Console.Out.Write(", "); 00045 System.Console.Out.WriteLine(msg.data().Length + " bytes"); 00046 break;
Similar to data messages above, the only real difference being that these messages can be responded to via the API.
00047 case LBM.MSG_REQUEST: 00048 if ((msg.flags() & LBM.MSG_FLAG_UME_RETRANSMIT) != 0) { 00049 System.Console.Out.Write("-RX-"); 00050 } 00051 if ((msg.flags() & LBM.MSG_FLAG_OTR) != 0) { 00052 System.Console.Out.Write("-OTR-"); 00053 } 00054 System.Console.Out.Write(", "); 00055 System.Console.Out.WriteLine(msg.data().Length + " bytes"); 00056 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.
00063 case LBM.MSG_UNRECOVERABLE_LOSS: 00064 System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "][" + msg.sequenceNumber().ToString("x") + "], LOST"); 00065 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
00066 case LBM.MSG_UNRECOVERABLE_LOSS_BURST: 00067 System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "][" + msg.sequenceNumber().ToString("x") + "], LOST BURST"); 00068 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.
00057 case LBM.MSG_BOS: 00058 System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "], Beginning of Transport Session"); 00059 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.
00060 case LBM.MSG_EOS: 00061 System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "], End of Transport Session"); 00062 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.
00069
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.
00070 case LBM.MSG_UME_REGISTRATION_ERROR: 00071 System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "] UME registration error: " + msg.dataString()); 00072 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.
00073 case LBM.MSG_UME_REGISTRATION_SUCCESS_EX: 00074 UMERegistrationSuccessInfo reg = msg.registrationSuccessInfo(); 00075 System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "] store " + reg.storeIndex() + ": " 00076 + reg.store() + " UME registration successful. Sequence number is " + reg.sequenceNumber()); 00077 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.
00078 case LBM.MSG_UME_REGISTRATION_COMPLETE_EX: 00079 UMERegistrationCompleteInfo regcomplete = msg.registrationCompleteInfo(); 00080 System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "] UME registration complete. SQN " 00081 + regcomplete.sequenceNumber() + ". Flags " + regcomplete.flags()); 00082 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.
00083 case LBM.MSG_UME_DEREGISTRATION_SUCCESS_EX: 00084 System.Console.Out.Write("DEREGISTRATION SUCCESSFUL "); 00085 UMEDeregistrationSuccessInfo dereg = msg.deregistrationSuccessInfo(); 00086 System.Console.Out.Write("[" + msg.topicName() + "][" + msg.source() + "] store " + dereg.storeIndex() + ": " 00087 + dereg.store() + " UME deregistration successful. SrcRegID " + dereg.sourceRegistrationId() + " RcvRegID " + dereg.receiverRegistrationId() 00088 + ". Flags " + dereg.flags() + " "); 00089 System.Console.Out.WriteLine(); 00090 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.
00091 case LBM.MSG_UME_DEREGISTRATION_COMPLETE_EX: 00092 System.Console.Out.WriteLine("DEREGISTRATION COMPLETE"); 00093 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.
00094 case LBM.MSG_UME_REGISTRATION_CHANGE: 00095 System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "] UME registration change: " + msg.dataString()); 00096 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.
00097 default: 00098 System.Console.Out.WriteLine("Other event, type=" + msg.type()); 00099 break;