// 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();
}
}
}