// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Linq; using LoggingWebSite; using Microsoft.AspNet.WebUtilities; namespace Microsoft.AspNet.Mvc.FunctionalTests { public static class LoggingExtensions { public const string RequestTraceIdQueryKey = "RequestTraceId"; /// /// Gets a scope node with the given name /// /// /// /// A scope node if found, else null public static ScopeNodeDto FindScope(this IEnumerable activities, string scopeName) { ScopeNodeDto node = null; foreach (var activity in activities) { if (activity.RepresentsScope) { node = GetScope(activity.Root, scopeName); // Ideally we do not expect multiple scopes with the same name // to exist in the logs, so we break on the first found scope node. // Note: The logs can contain multiple scopes with the same name across // different requests, but the tests are expected to filter the logs by request // (ex: using request trace id) and then find the scope by name. if (node != null) { return node; } } } return node; } /// /// Gets all the logs messages matching the given data type /// /// /// public static IEnumerable GetLogsByDataType(this IEnumerable activities) { var logInfos = new List(); foreach (var activity in activities) { if (!activity.RepresentsScope) { var logInfo = activity.Root.Messages.OfDataType() .FirstOrDefault(); if (logInfo != null) { logInfos.Add(logInfo); } } else { GetLogsByDataType(activity.Root, logInfos); } } return logInfos; } /// /// Filters for logs activties created during application startup /// /// /// public static IEnumerable FilterByStartup(this IEnumerable activities) { return activities.Where(activity => activity.RequestInfo == null); } /// /// Filters log activities based on the given request. /// /// /// The "RequestTraceId" query parameter value /// public static IEnumerable FilterByRequestTraceId(this IEnumerable activities, string requestTraceId) { return activities.Where(activity => activity.RequestInfo != null && string.Equals(GetQueryValue(activity.RequestInfo.Query, RequestTraceIdQueryKey), requestTraceId, StringComparison.OrdinalIgnoreCase)); } /// /// Filters the log messages based on the given data type /// /// /// public static IEnumerable OfDataType(this IEnumerable logInfos) { return logInfos.Where(logInfo => logInfo.StateType != null && logInfo.StateType.Equals(typeof(T))); } /// /// Traverses through the log node tree and gets the log messages whose StateType /// matches the supplied data type. /// /// /// private static void GetLogsByDataType(ScopeNodeDto node, IList logInfoDtos) { foreach (var logInfo in node.Messages.OfDataType()) { logInfoDtos.Add(logInfo); } foreach (var scopeNode in node.Children) { GetLogsByDataType(scopeNode, logInfoDtos); } } private static ScopeNodeDto GetScope(ScopeNodeDto root, string scopeName) { if (string.Equals(root.State?.ToString(), scopeName, StringComparison.OrdinalIgnoreCase)) { return root; } foreach (var childNode in root.Children) { var foundNode = GetScope(childNode, scopeName); if (foundNode != null) { return foundNode; } } return null; } private static string GetQueryValue(string query, string key) { var queryString = QueryHelpers.ParseQuery(query); return queryString[key].FirstOrDefault(); } } }