/// <summary> /// Finalize latency analysis for the supplied type of message /// </summary> /// <param name="theMessageId">The identifier for the type of message for which latency analysis is to be finalized</param> /// <param name="theRows">The data table rows on which latency analysis is to be finalized</param> private void FinaliseForMessageId(ulong theMessageId, DictionaryEnumerableType theRows) { CommonHistogram theHistogram = new CommonHistogram( this.theDebugInformation, Constants.NumberOfBins, Constants.BestCaseLatency, Constants.WorstCaseLatency); ulong theNumberOfMessagePairs = 0; double theMinTimestampDifference = double.MaxValue; double theMaxTimestampDifference = double.MinValue; ulong theMinTimestampPacketNumber = 0; ulong theMaxTimestampPacketNumber = 0; ulong theMinTimestampSequenceNumber = 0; ulong theMaxTimestampSequenceNumber = 0; ulong theNumberOfTimestampDifferenceInstances = 0; double theTotalOfTimestampDifferences = 0; double theAverageTimestampDifference = 0; System.Collections.Generic.List <string> theOutOfRangeLatencies = new System.Collections.Generic.List <string>(); foreach (DictionaryKeyValuePairType theRow in theRows) { // Keep a running total of the number of message pairs ++theNumberOfMessagePairs; double theTimestampDifference = theRow.Value.TimestampDifference; if (!theHistogram.AddValue(theTimestampDifference)) { theOutOfRangeLatencies.Add( "The message pair for packet number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theRow.Value.FirstInstancePacketNumber.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " and sequence number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theRow.Key.SequenceNumber.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " has an out of range latency of " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,19}", theRow.Value.TimestampDifference.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " ms"); } //// Keep a running total of the timestamp differences to allow for averaging ++theNumberOfTimestampDifferenceInstances; theTotalOfTimestampDifferences += theTimestampDifference; if (theMinTimestampDifference > theTimestampDifference) { theMinTimestampDifference = theTimestampDifference; theMinTimestampPacketNumber = theRow.Value.FirstInstancePacketNumber; theMinTimestampSequenceNumber = theRow.Key.SequenceNumber; } if (theMaxTimestampDifference < theTimestampDifference) { theMaxTimestampDifference = theTimestampDifference; theMaxTimestampPacketNumber = theRow.Value.FirstInstancePacketNumber; theMaxTimestampSequenceNumber = theRow.Key.SequenceNumber; } } this.theDebugInformation.WriteTextLine( "The number of message pairs with a Message Id of " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,5}", theMessageId.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " was " + theNumberOfMessagePairs.ToString(System.Globalization.CultureInfo.CurrentCulture)); if (theNumberOfTimestampDifferenceInstances > 0) { theAverageTimestampDifference = theTotalOfTimestampDifferences / theNumberOfTimestampDifferenceInstances; this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( "The minimum latency was " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,19}", theMinTimestampDifference.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " ms for packet number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theMinTimestampPacketNumber.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " and sequence number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theMinTimestampSequenceNumber.ToString(System.Globalization.CultureInfo.CurrentCulture))); this.theDebugInformation.WriteTextLine( "The maximum latency was " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,19}", theMaxTimestampDifference.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " ms for packet number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theMaxTimestampPacketNumber.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " and sequence number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theMaxTimestampSequenceNumber.ToString(System.Globalization.CultureInfo.CurrentCulture))); this.theDebugInformation.WriteTextLine( "The average latency was " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,19}", theAverageTimestampDifference.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " ms"); if (this.outputHistogram) { //// Output the histogram this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( new string('-', 144)); this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( "The histogram (" + Constants.BinsPerMillisecond.ToString(System.Globalization.CultureInfo.CurrentCulture) + " bins per millisecond) for the latencies is:"); this.theDebugInformation.WriteBlankLine(); theHistogram.OutputValues(); } if (theOutOfRangeLatencies.Any()) { this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( new string('-', 144)); this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( "The number of those message pairs that had an out of range latency was " + theOutOfRangeLatencies.Count().ToString(System.Globalization.CultureInfo.CurrentCulture)); if (this.outputAdditionalInformation) { this.theDebugInformation.WriteBlankLine(); // Output the data for any message pair with an out of range latency foreach (string theString in theOutOfRangeLatencies) { this.theDebugInformation.WriteTextLine(theString); } } } } this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( new string('-', 144)); this.theDebugInformation.WriteBlankLine(); // Output additional information for the supplied type of message this.OutputAdditionalInformation( theMessageId, theRows, theNumberOfTimestampDifferenceInstances); }
/// <summary> /// Finalize burst analysis for the supplied type of message /// </summary> /// <param name="theHostId">The host Id for which burst analysis is to be finalized</param> /// <param name="isOutgoing">Boolean flag that indicates whether the messages to be finalized were received on its outgoing journey or its incoming journey (true indicates outgoing, false indicates incoming)</param> /// <param name="theMessageId">The identifier for the type of message for which burst analysis is to be finalized</param> /// <param name="theRows">The data table rows on which burst analysis is to be finalized</param> private void FinaliseForMessageId(byte theHostId, bool isOutgoing, ulong theMessageId, EnumerableRowCollection <System.Data.DataRow> theRows) { CommonHistogram theTimestampHistogram = new CommonHistogram( this.theDebugInformation, Constants.NumberOfBins, Constants.MinTimestampDifference, Constants.MaxTimestampDifference); ulong theNumberOfMessages = 0; double theMinTimestampDifference = double.MaxValue; double theMaxTimestampDifference = double.MinValue; ulong theMinTimestampPacketNumber = 0; ulong theMaxTimestampPacketNumber = 0; ulong theMinTimestampSequenceNumber = 0; ulong theMaxTimestampSequenceNumber = 0; double theLastTimestamp = 0.0; ulong theNumberOfTimestampDifferenceInstances = 0; double theTotalOfTimestampDifferences = 0; double theAverageTimestampDifference = 0; bool theFirstRowProcessed = false; System.Collections.Generic.List <string> theIgnoredTimestamps = new System.Collections.Generic.List <string>(); System.Collections.Generic.List <string> theOutOfRangeTimestamps = new System.Collections.Generic.List <string>(); foreach (System.Data.DataRow theTimestampValuesRow in theRows) { // Keep a running total of the number of messages ++theNumberOfMessages; ulong theSequenceNumber = theTimestampValuesRow.Field <ulong>("SequenceNumber"); ulong thePacketNumber = theTimestampValuesRow.Field <ulong>("PacketNumber"); double thePacketTimestamp = theTimestampValuesRow.Field <double>("PacketTimestamp"); // Do not calculate the difference in timestamp for first row - just record value and move on to second row if (!theFirstRowProcessed) { theLastTimestamp = thePacketTimestamp; theFirstRowProcessed = true; continue; } //// The timestamp double theAbsoluteTimestampDifference = System.Math.Abs((thePacketTimestamp - theLastTimestamp) * 1000.0); // Milliseconds // Only those messages with a timestamp difference in the chosen range will be marked as processed // This should prevent the processing of duplicates of a message (e.g. if port mirroring results in two copies of the time-supplying message) if (theAbsoluteTimestampDifference < Constants.MinAbsoluteTimestampDifference) { theIgnoredTimestamps.Add( "The message for packet number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", thePacketNumber.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " and sequence number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theSequenceNumber.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " has an absolute timestamp difference of " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,19}", theAbsoluteTimestampDifference.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " ms which is below the minimum value of " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,5}", Constants.MinAbsoluteTimestampDifference.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " ms so it has been ignored and discarded"); } else { double theTimestampDifference = (thePacketTimestamp - theLastTimestamp) * 1000.0; // Milliseconds //// Keep a running total of the timestamp differences to allow for averaging ++theNumberOfTimestampDifferenceInstances; theTotalOfTimestampDifferences += theTimestampDifference; if (!theTimestampHistogram.AddValue(theTimestampDifference)) { theOutOfRangeTimestamps.Add( "The message for packet number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", thePacketNumber.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " and sequence number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theSequenceNumber.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " has an out of range timestamp difference of " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,19}", theTimestampDifference.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " ms"); } if (theMinTimestampDifference > theTimestampDifference) { theMinTimestampDifference = theTimestampDifference; theMinTimestampPacketNumber = thePacketNumber; theMinTimestampSequenceNumber = theSequenceNumber; } if (theMaxTimestampDifference < theTimestampDifference) { theMaxTimestampDifference = theTimestampDifference; theMaxTimestampPacketNumber = thePacketNumber; theMaxTimestampSequenceNumber = theSequenceNumber; } // Keep a record of the last timestamp received (from this time-supplying // message) to allow comparison with the next timestamp received theLastTimestamp = thePacketTimestamp; } } if (isOutgoing) { this.theDebugInformation.WriteTextLine( "The number of outgoing messages with a Message Id of " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,5}", theMessageId) + " was " + theNumberOfMessages.ToString(System.Globalization.CultureInfo.CurrentCulture)); } else { this.theDebugInformation.WriteTextLine( "The number of incoming messages with a Message Id of " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,5}", theMessageId) + " was " + theNumberOfMessages.ToString(System.Globalization.CultureInfo.CurrentCulture)); } if (theNumberOfTimestampDifferenceInstances > 0) { this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( new string('-', 144)); this.theDebugInformation.WriteBlankLine(); theAverageTimestampDifference = theTotalOfTimestampDifferences / theNumberOfTimestampDifferenceInstances; this.theDebugInformation.WriteTextLine( "The minimum timestamp difference was " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,19}", theMinTimestampDifference.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " ms for packet number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theMinTimestampPacketNumber.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " and sequence number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theMinTimestampSequenceNumber.ToString(System.Globalization.CultureInfo.CurrentCulture))); this.theDebugInformation.WriteTextLine( "The maximum timestamp difference was " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,19}", theMaxTimestampDifference.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " ms for packet number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theMaxTimestampPacketNumber.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " and sequence number " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,7}", theMaxTimestampSequenceNumber.ToString(System.Globalization.CultureInfo.CurrentCulture))); this.theDebugInformation.WriteTextLine( "The average timestamp difference was " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,19}", theAverageTimestampDifference.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " ms"); if (theAverageTimestampDifference > 0) { this.theDebugInformation.WriteBlankLine(); double theMessageRate = 1.0 / (theAverageTimestampDifference / 1000.0); // Hertz this.theDebugInformation.WriteTextLine( "The average message rate was " + string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0,19}", theMessageRate.ToString(System.Globalization.CultureInfo.CurrentCulture)) + " Hz"); } if (this.outputHistogram) { //// Output the histogram this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( new string('-', 144)); this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( "The histogram (" + Constants.BinsPerMillisecond.ToString(System.Globalization.CultureInfo.CurrentCulture) + " bins per millisecond) for the timestamp differences is:"); this.theDebugInformation.WriteBlankLine(); theTimestampHistogram.OutputValues(); } if (theOutOfRangeTimestamps.Any()) { this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( new string('-', 144)); this.theDebugInformation.WriteBlankLine(); if (isOutgoing) { this.theDebugInformation.WriteTextLine( "The number of those outgoing messages that had an out of range timestamp difference was " + theOutOfRangeTimestamps.Count().ToString(System.Globalization.CultureInfo.CurrentCulture)); } else { this.theDebugInformation.WriteTextLine( "The number of those incoming messages that had an out of range timestamp difference was " + theOutOfRangeTimestamps.Count().ToString(System.Globalization.CultureInfo.CurrentCulture)); } if (this.outputAdditionalInformation) { this.theDebugInformation.WriteBlankLine(); // Output the data for any message with an out of range timestamp difference foreach (string theString in theOutOfRangeTimestamps) { this.theDebugInformation.WriteTextLine(theString); } } } if (theIgnoredTimestamps.Any()) { this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( new string('-', 144)); this.theDebugInformation.WriteBlankLine(); if (isOutgoing) { this.theDebugInformation.WriteTextLine( "The number of those outgoing messages that were ignored and discarded was " + theIgnoredTimestamps.Count().ToString(System.Globalization.CultureInfo.CurrentCulture)); } else { this.theDebugInformation.WriteTextLine( "The number of those incoming messages that were ignored and discarded was " + theIgnoredTimestamps.Count().ToString(System.Globalization.CultureInfo.CurrentCulture)); } if (this.outputAdditionalInformation) { this.theDebugInformation.WriteBlankLine(); // Output the data for any time-supplying messages that were ignored and discarded foreach (string theString in theIgnoredTimestamps) { this.theDebugInformation.WriteTextLine(theString); } } } } this.theDebugInformation.WriteBlankLine(); this.theDebugInformation.WriteTextLine( new string('-', 144)); this.theDebugInformation.WriteBlankLine(); // Output additional information for the supplied type of message this.OutputAdditionalInformation( theHostId, isOutgoing, theMessageId, theRows, theNumberOfTimestampDifferenceInstances); }