public virtual void ExtractContextAndRedisCommand(ClrThread thread, ThreadStackEnumerator threadStackObjectEnumerator, IModelMapperFactory factory, IDictionary <string, List <HttpContextMappingModel> > contextsByRedisCommands) { string command = null; HttpContextMappingModel httpContext = null; foreach (var clrObj in threadStackObjectEnumerator.Enumerate(thread)) { ExtractCommandOrContext(clrObj, factory, ref command, ref httpContext); // already extracted both from the thread stack. if (!string.IsNullOrEmpty(command) && (httpContext != null)) { break; } } List <HttpContextMappingModel> httpContextsForGivenRedisCommand = null; if (!string.IsNullOrEmpty(command)) { if (!contextsByRedisCommands.ContainsKey(command)) { httpContextsForGivenRedisCommand = new List <HttpContextMappingModel>(); contextsByRedisCommands.Add(command, httpContextsForGivenRedisCommand); } else { httpContextsForGivenRedisCommand = contextsByRedisCommands[command]; } } if (httpContext?.HasURL == true && httpContext?.Request != null) { if (httpContextsForGivenRedisCommand != null) { httpContextsForGivenRedisCommand.Add(httpContext); } else { if (!contextsByRedisCommands.ContainsKey("NoCommand")) { contextsByRedisCommands.Add("NoCommand", new List <HttpContextMappingModel>()); } var noCommand = contextsByRedisCommands["NoCommand"]; noCommand.Add(httpContext); } } }
public virtual StringBuilder ExtractRedisPendingCommandsForRequests(ClrRuntime runtime, IModelMapperFactory clrObjectToModelFactory) { var knownObjects = new HashSet <ulong>(); var threadStackObjectEnumerator = new ThreadStackEnumerator( includePossiblyDead: true, filter: ThreadStackObjectFilter); List <string> commands = new List <string>(); int totalContexts = 0; IDictionary <string, List <HttpContextMappingModel> > httpContextsMappedByRedisCommand = new Dictionary <string, List <HttpContextMappingModel> >(); foreach (var contextThread in ThreadFilter.ExtactAliveUserThreads(runtime)) { ExtractContextAndRedisCommand(contextThread, threadStackObjectEnumerator, clrObjectToModelFactory, httpContextsMappedByRedisCommand); } var differentRedisCommands = httpContextsMappedByRedisCommand.OrderByDescending(grouping => grouping.Value.Count); var aspNetIDs = (from requestGroup in httpContextsMappedByRedisCommand let httpContexts = requestGroup.Value from httpContext in httpContexts let requestInfo = new { httpContext, httpContext?.Request?.AspNetSessionId } group requestInfo by requestInfo.AspNetSessionId into sameSessions select sameSessions).OrderByDescending(t => t.Count()).ToArray(); var sb = new StringBuilder(); sb.AppendLine($"Different Commands found: {differentRedisCommands.Count()}"); totalContexts = httpContextsMappedByRedisCommand.Sum(elem => elem.Value.Count); sb.AppendLine($"Total requests {totalContexts} VS unique asp.net sessions {aspNetIDs.Length}"); foreach (var cmd in differentRedisCommands) { sb.AppendLine($"Hits: {cmd.Value.Count}"); sb.AppendLine(); sb.AppendLine(cmd.Key); foreach (var context in cmd.Value.OrderByDescending(request => request.ExecutionDuration)) { sb.AppendLine(FormatLine(context)); } sb.AppendLine("**************"); } foreach (var session in aspNetIDs) { sb.AppendLine($"Session: {session.Key}:"); foreach (var request in session) { sb.AppendLine($"{request.httpContext.URL} executed for {request.httpContext.ExecutionDuration.TotalSeconds:F2} sec."); } sb.AppendLine("**************"); sb.AppendLine(); } return(sb); }