/// <summary> /// Renders all alements found in <paramref name="sortedList"/>. /// Elements are sorted by weight (in descending order). /// Each element is rendered on a separate line using the following format string: $"[{weight}] {path}. /// The 'weigth' fragment is padded so that all 'path's are aligned on the left. /// </summary> protected static string CollapseDictionaryTimeLogs(ConcurrentBoundedSortedCollection <long, string> sortedList, Func <long, string> weightRenderer) { var maxRenderedWeightLength = sortedList.Any() ? sortedList.Max(kvp => weightRenderer(kvp.Key).Length) : 0; StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair <long, string> pair in sortedList.Reverse()) { var renderedWeight = weightRenderer(pair.Key); var paddedDurationStr = renderedWeight.PadLeft(maxRenderedWeightLength); stringBuilder.Append(I($"{Environment.NewLine} [{paddedDurationStr}] {pair.Value}")); } return(stringBuilder.ToString()); }
/// <summary> /// Returns an array of json strings containing performance information about top N Pips /// </summary> public string[] GenerateTopPipPerformanceInfoJsonArray() { var sortedTopPipPerformanceInfo = m_sortedTopPipPerformanceInfo .Reverse() // Log highest execution time pips first .Select(a => a.Value) .ToArray(); if (sortedTopPipPerformanceInfo.Length == 0) { return(CollectionUtilities.EmptyArray <string>()); } // final array of JSON strings to be returned at the end var jsonResp = new List <string>(); var messageJsonPrefix = "{\"" + JsonPerfArrayPropertyName + "\":["; var messageJsonSuffix = "]}"; int firstValidElementIndex = 0; string firstValidElement; do { firstValidElement = SerializePipPerfInfo(sortedTopPipPerformanceInfo[firstValidElementIndex]); firstValidElementIndex++; }while (firstValidElement.Length >= m_ariaCharLimit && firstValidElementIndex < sortedTopPipPerformanceInfo.Length); if (firstValidElementIndex == sortedTopPipPerformanceInfo.Length && firstValidElement.Length >= m_ariaCharLimit) { // All values are larger than the telemetry message size limit return(CollectionUtilities.EmptyArray <string>()); } using var sbPool = Pools.GetStringBuilder(); var currentMessage = sbPool.Instance; currentMessage.Append(messageJsonPrefix) .Append(firstValidElement); for (var i = firstValidElementIndex; i < sortedTopPipPerformanceInfo.Length && jsonResp.Count < m_maxNumberOfBatches; i++) { var pipPerfJson = SerializePipPerfInfo(sortedTopPipPerformanceInfo[i]); if (pipPerfJson.Length >= m_ariaCharLimit) { // Skip pips with large description continue; } var newMessageLength = currentMessage.Length + 1 + pipPerfJson.Length + messageJsonSuffix.Length; if (newMessageLength <= m_ariaCharLimit) { // continue current batch currentMessage.Append(",").Append(pipPerfJson); } else { // finish the current batch and start a new one currentMessage.Append(messageJsonSuffix); jsonResp.Add(currentMessage.ToString()); currentMessage.Clear(); currentMessage.Append(messageJsonPrefix).Append(pipPerfJson); } } if (jsonResp.Count < m_maxNumberOfBatches) { currentMessage.Append(messageJsonSuffix); jsonResp.Add(currentMessage.ToString()); } return(jsonResp.ToArray()); }