public static async Task <IAnalyzerResult> Analyze(Guid appid, string apikey, StructuredQuery query, string[] queryParts) { query = QueryBuilder.RemoveProject(query); query = QueryBuilder.RemoveSummarize(query); var isExceptionsQuery = query.FirstOrDefault()?.Trim().StartsWith("exceptions", StringComparison.OrdinalIgnoreCase) == true; QueryGroup queryGroup; var whereQuery = @" | where details[0].parsedStack[0].fileName != '' | project itemCount, filename = extract('([^\\\\/]+)$', 1, tostring(details[0].parsedStack[0].fileName)), type, line = tostring(details[0].parsedStack[0].line) | summarize sum(itemCount) by filename, type, line | order by sum_itemCount"; if (isExceptionsQuery) { queryGroup = new QueryGroup(query); queryGroup.AddParts(queryParts); queryGroup.Append(QueryBuilder.Parse(whereQuery)); } else { var exceptionsQuery = QueryBuilder.Parse( $@" exceptions | {query.First(q => q.Contains("timestamp >"))} {whereQuery}"); queryGroup = new QueryGroup(exceptionsQuery); queryGroup.Replace(query.First().Trim(), query); queryGroup.AddParts(queryParts); } var queryString = queryGroup.ToString(); var result = await AppInsightsClient.GetTableQuery(appid, apikey, queryString); result.Columns[0].Name = "File"; result.Columns[1].Name = "Exception"; result.Columns[3].Name = "Count"; result.Columns.RemoveAt(2); foreach (var row in result.Rows) { row.Add($"where details[0].parsedStack[0].fileName endswith '{row[0]}' and details[0].parsedStack[0].line == {row[2]}"); row.Add($"where details[0].parsedStack[0].fileName !endswith '{row[0]}' or details[0].parsedStack[0].line != {row[2]}"); row[0] = $"{row[0]} ({row[2]})"; var exception = (string)row[1]; row[1] = exception.Substring(exception.LastIndexOf('.') + 1); row.RemoveAt(2); } return(new TableAnalyzerResult("Stacktraces", true, result)); }
public static async Task <IAnalyzerResult> Analyze(ApiToken apiToken, StructuredQuery query, string[] queryParts) { query = QueryBuilder.RemoveProject(query); query = QueryBuilder.RemoveSummarize(query); var isRequestsQuery = query.FirstOrDefault()?.Trim().StartsWith("requests", StringComparison.OrdinalIgnoreCase) == true; QueryGroup queryGroup; var whereQuery = @" | project domain = extract('^(https|http)://(.*?)/', 2, url), duration, itemCount, success | summarize duration = avg(duration), failedCount=sumif(itemCount, success == false), totalCount=sum(itemCount) by domain | order by totalCount desc | take 20 | project domain, totalCount, duration, failedCount, failedPercentage = 100.0 / totalCount * failedCount"; if (isRequestsQuery) { queryGroup = new QueryGroup(query); queryGroup.AddParts(queryParts); queryGroup.Append(QueryBuilder.Parse(whereQuery)); } else { var requestsQuery = QueryBuilder.Parse( $@" requests | {query.First(q => q.Contains("timestamp >"))} {whereQuery}"); queryGroup = new QueryGroup(requestsQuery); queryGroup.Replace(query.First().Trim(), query); queryGroup.AddParts(queryParts); } var queryString = queryGroup.ToString(); var result = await AppInsightsClient.GetTableQuery(apiToken, queryString); result.Columns[0].Name = "Domain"; result.Columns[1].Name = "Count"; result.Columns[2].Name = "Duration"; result.Columns[3].Name = "Failures"; result.Columns[4].Name = "Percentage"; foreach (var row in result.Rows) { row[2] = $"{row[2]:0} ms"; row[4] = $"{row[4]:0} %"; row.Add($"where url contains '{row[0]}'"); row.Add($"where url !contains '{row[0]}'"); } return(new TableAnalyzerResult("Domains", true, result)); }
public static async Task <IAnalyzerResult> Analyze(ApiToken apiToken, StructuredQuery query, string[] queryParts) { query = QueryBuilder.RemoveProject(query); query = QueryBuilder.RemoveSummarize(query); var isRequestsQuery = query.FirstOrDefault()?.Trim().StartsWith("requests", StringComparison.OrdinalIgnoreCase) == true; QueryGroup queryGroup; var whereQuery = @" | summarize _count=sum(itemCount) by resultCode | project resultCode, _count | sort by _count desc"; if (isRequestsQuery) { queryGroup = new QueryGroup(query); queryGroup.AddParts(queryParts); queryGroup.Append(QueryBuilder.Parse(whereQuery)); } else { var requestsQuery = QueryBuilder.Parse( $@" requests | {query.First(q => q.Contains("timestamp >"))} {whereQuery}"); queryGroup = new QueryGroup(requestsQuery); queryGroup.Replace(query.First().Trim(), query); queryGroup.AddParts(queryParts); } var queryString = queryGroup.ToString(); var result = await AppInsightsClient.GetTableQuery(apiToken, queryString); result.Columns[0].Name = "Status code"; result.Columns[1].Name = "Count"; foreach (var row in result.Rows) { row.Add($"where resultCode == {row[0]}"); row.Add($"where resultCode != {row[0]}"); } return(new TableAnalyzerResult("Status codes", true, result)); }
public static async Task <IAnalyzerResult> Analyze(Guid appid, string apikey, StructuredQuery query, string[] queryParts) { query = QueryBuilder.RemoveProject(query); query = QueryBuilder.RemoveSummarize(query); var isExceptionsQuery = query.FirstOrDefault()?.Trim().StartsWith("exceptions", StringComparison.OrdinalIgnoreCase) == true; QueryGroup queryGroup; var whereQuery = @" | summarize _count = sum(itemCount) by type | sort by _count desc | take 20"; if (isExceptionsQuery) { queryGroup = new QueryGroup(query); queryGroup.AddParts(queryParts); queryGroup.Append(QueryBuilder.Parse(whereQuery)); } else { var exceptionsQuery = QueryBuilder.Parse( $@" exceptions | {query.First(q => q.Contains("timestamp >"))} {whereQuery}"); queryGroup = new QueryGroup(exceptionsQuery); queryGroup.Replace(query.First().Trim(), query); queryGroup.AddParts(queryParts); } var queryString = queryGroup.ToString(); var result = await AppInsightsClient.GetTableQuery(appid, apikey, queryString); result.Columns[0].Name = "Exception type"; result.Columns[1].Name = "Count"; foreach (var row in result.Rows) { row.Add($"where type == '{row[0]}'"); row.Add($"where type != '{row[0]}'"); } return(new TableAnalyzerResult("Exceptions", true, result)); }
public static async Task <IAnalyzerResult> Analyze(Guid appid, string apikey, StructuredQuery query, string[] queryParts) { query = QueryBuilder.RemoveProject(query); query = QueryBuilder.RemoveSummarize(query); var isExceptionsQuery = query.FirstOrDefault()?.Trim().StartsWith("exceptions", StringComparison.OrdinalIgnoreCase) == true; QueryGroup queryGroup; var whereQuery = @" | project itemCount, message = strcat(outerMessage, ' \n\n ', customDimensions['AdditionalErrorDetails'], ' \n\n ', customDimensions['additionalDetails']) | project itemCount, message = replace(@'[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}', '[GUID]', message) | project itemCount, message = replace(@'(^|[ ''])(http:|https:)*[/]{1,2}(.*?)([ ]|$|\n)', ' [URL] ', message) | project itemCount, message = replace(@'[0-9]', '[X]', message) | where message !contains 'username' or message !contains 'password' | summarize sum(itemCount) by message | order by sum_itemCount desc | take 20"; if (isExceptionsQuery) { queryGroup = new QueryGroup(query); queryGroup.AddParts(queryParts); queryGroup.Append(QueryBuilder.Parse(whereQuery)); } else { var exceptionsQuery = QueryBuilder.Parse( $@" exceptions | {query.First(q => q.Contains("timestamp >"))} {whereQuery}"); queryGroup = new QueryGroup(exceptionsQuery); queryGroup.Replace(query.First().Trim(), query); queryGroup.AddParts(queryParts); } var queryString = queryGroup.ToString(); var result = await AppInsightsClient.GetTableQuery(appid, apikey, queryString); result.Columns[0].Name = "Exception message"; result.Columns[1].Name = "Count"; foreach (var row in result.Rows) { var rowText = (string)row[0]; var commandText = ((string)row[0]).Trim(); rowText = rowText.Replace("[X]", "X"); rowText = Regex.Replace(rowText, "[X]+", "X"); var lines = new List <string>(); foreach (var line in Regex.Split(rowText, @"\n").SelectMany(line => Regex.Split(Regex.Replace(line, @"\. ", ".. "), @"\. "))) { var trimmedLine = Regex.Replace(line, @"^[ ]*\[[A-Z]+\][ ]*", "").Trim(); if (!string.IsNullOrWhiteSpace(trimmedLine) && lines.All(l => l != trimmedLine)) { lines.Add(trimmedLine); } } rowText = string.Join("\n", lines); row[0] = rowText.Trim(); var matches = Regex.Matches(commandText, @"(^|\])(.*?)($|\[)"); if (matches.Any(match => match.Groups[2].Length > 10)) { commandText = matches .First(match => match.Groups[2].Length > 10) .Groups[2].Value.Trim(); } commandText = commandText.Replace("'", @"\'"); row.Add($"where outerMessage contains '{commandText}' or customDimensions['AdditionalErrorDetails'] contains '{commandText}' or customDimensions['additionalDetails'] contains '{commandText}'"); row.Add($"where outerMessage !contains '{commandText}' and customDimensions['AdditionalErrorDetails'] !contains '{commandText}' and customDimensions['additionalDetails'] !contains '{commandText}'"); } return(new TableAnalyzerResult("Exception messages", true, result)); }