- Added Diagnostics event Source and various events
- Custom Middleware for host projects to capture API metrics and global exception handlers
This commit is contained in:
Родитель
80dafaf912
Коммит
c4cd9b8d77
|
@ -23,6 +23,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{C0537983-2503-4D70-B831-27614DB29F81}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Diagnostics.Logger", "src\Diagnostics.Logger\Diagnostics.Logger.csproj", "{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -105,6 +107,18 @@ Global
|
|||
{CFD34079-6A40-4938-8840-4325B504ACFA}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CFD34079-6A40-4938-8840-4325B504ACFA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CFD34079-6A40-4938-8840-4325B504ACFA}.Release|x86.Build.0 = Release|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Release|x64.Build.0 = Release|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -116,6 +130,7 @@ Global
|
|||
{0080F318-4A06-40E3-BCA6-5C61978CBFE6} = {0F59F43E-D06C-4A0F-8D38-9538BA58FC6A}
|
||||
{F23F3EDA-2CD2-4F7B-B605-13DF4A8A632F} = {0F59F43E-D06C-4A0F-8D38-9538BA58FC6A}
|
||||
{CFD34079-6A40-4938-8840-4325B504ACFA} = {C0537983-2503-4D70-B831-27614DB29F81}
|
||||
{9EBCA533-692C-4A6E-9831-AE84C0AFCEF2} = {0F59F43E-D06C-4A0F-8D38-9538BA58FC6A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B4A19BFB-9A33-49E2-98AD-955E9472EFAD}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Diagnostics.DataProviders\Diagnostics.DataProviders.csproj" />
|
||||
<ProjectReference Include="..\Diagnostics.Logger\Diagnostics.Logger.csproj" />
|
||||
<ProjectReference Include="..\Diagnostics.ModelsAndUtils\Diagnostics.ModelsAndUtils.csproj" />
|
||||
<ProjectReference Include="..\Diagnostics.Scripts\Diagnostics.Scripts.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Diagnostics.Logger;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Diagnostics.CompilerHost.Middleware
|
||||
{
|
||||
public class CompilerRequestMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly string _apiLoggerKey = "CompilerHost_ApiLogger";
|
||||
|
||||
public CompilerRequestMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext httpContext)
|
||||
{
|
||||
BeginRequest_Handle(httpContext);
|
||||
|
||||
try
|
||||
{
|
||||
await _next(httpContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!httpContext.Response.HasStarted)
|
||||
{
|
||||
httpContext.Response.Clear();
|
||||
httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
}
|
||||
|
||||
LogException(httpContext, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
EndRequest_Handle(httpContext);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private void BeginRequest_Handle(HttpContext httpContext)
|
||||
{
|
||||
var logger = new ApiMetricsLogger(httpContext);
|
||||
httpContext.Items.Add(_apiLoggerKey, logger);
|
||||
}
|
||||
|
||||
private void EndRequest_Handle(HttpContext httpContext)
|
||||
{
|
||||
ApiMetricsLogger logger = (ApiMetricsLogger)httpContext.Items[_apiLoggerKey];
|
||||
if (logger == null)
|
||||
{
|
||||
logger = new ApiMetricsLogger(httpContext);
|
||||
}
|
||||
|
||||
logger.LogCompilerHostAPIMetrics(httpContext);
|
||||
}
|
||||
|
||||
private void LogException(HttpContext context, Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
ApiMetricsLogger logger = (ApiMetricsLogger)context.Items[_apiLoggerKey];
|
||||
if (logger == null)
|
||||
{
|
||||
logger = new ApiMetricsLogger(context);
|
||||
}
|
||||
|
||||
logger.LogCompilerHostUnhandledException(context, ex);
|
||||
}
|
||||
catch (Exception logEx)
|
||||
{
|
||||
DiagnosticsETWProvider.Instance.LogCompilerHostUnhandledException(
|
||||
string.Empty,
|
||||
"LogException_CompilerRequestMiddleware",
|
||||
logEx.GetType().ToString(),
|
||||
logEx.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extension method used to add the middleware to the HTTP request pipeline.
|
||||
public static class CompilerRequestMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseCompilerRequestMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<CompilerRequestMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Diagnostics.CompilerHost.Middleware;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
@ -34,6 +35,7 @@ namespace Diagnostics.CompilerHost
|
|||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseCompilerRequestMiddleware();
|
||||
app.UseMvc();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Diagnostics.Logger
|
||||
{
|
||||
public class ApiMetricsLogger
|
||||
{
|
||||
private string _requestId;
|
||||
private string _address;
|
||||
private string _verb;
|
||||
private DateTime _startTime;
|
||||
private DateTime _endTime;
|
||||
private long _latencyInMs;
|
||||
private string _subscriptionId;
|
||||
private string _resourceGroupName;
|
||||
private string _resourceName;
|
||||
|
||||
public ApiMetricsLogger(HttpContext context)
|
||||
{
|
||||
StartMetricCapture(context);
|
||||
}
|
||||
|
||||
private void StartMetricCapture(HttpContext context)
|
||||
{
|
||||
if (context.Request.Headers.TryGetValue(HeaderConstants.RequestIdHeaderName, out StringValues values))
|
||||
{
|
||||
_requestId = values.ToString();
|
||||
}
|
||||
|
||||
_startTime = DateTime.UtcNow;
|
||||
_verb = context.Request.Method;
|
||||
_address = context.Request.Path.ToString();
|
||||
|
||||
ParseFromAddress(context);
|
||||
}
|
||||
|
||||
private void ParseFromAddress(HttpContext httpContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(httpContext.Request.Path.ToString()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var parts = httpContext.Request.Path.ToString().ToLowerInvariant().Split('?')[0].Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var cursor = ((IEnumerable<string>)parts).GetEnumerator();
|
||||
while (cursor.MoveNext())
|
||||
{
|
||||
if (String.Equals(cursor.Current, "subscriptions", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cursor.MoveNext())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_subscriptionId = cursor.Current;
|
||||
|
||||
if (!cursor.MoveNext())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (String.Equals(cursor.Current, "resourceGroups", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!cursor.MoveNext())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_resourceGroupName = cursor.Current;
|
||||
|
||||
if (!cursor.MoveNext() || !String.Equals(cursor.Current, "providers", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!cursor.MoveNext() || !String.Equals(cursor.Current, "Microsoft.Web", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor.MoveNext() && String.Equals(cursor.Current, "sites", StringComparison.OrdinalIgnoreCase) || String.Equals(cursor.Current, "hostingEnvironments", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!cursor.MoveNext())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_resourceName = cursor.Current;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore error
|
||||
}
|
||||
}
|
||||
|
||||
public void LogRuntimeHostAPIMetrics(HttpContext context)
|
||||
{
|
||||
if (context == null) return;
|
||||
|
||||
_endTime = DateTime.UtcNow;
|
||||
_latencyInMs = Convert.ToInt64((_endTime - _startTime).TotalMilliseconds);
|
||||
|
||||
DiagnosticsETWProvider.Instance.LogRuntimeHostAPISummary(
|
||||
_requestId ?? string.Empty,
|
||||
_subscriptionId ?? string.Empty,
|
||||
_resourceGroupName ?? string.Empty,
|
||||
_resourceName ?? string.Empty,
|
||||
_address ?? string.Empty,
|
||||
_verb ?? string.Empty,
|
||||
string.Empty,
|
||||
context.Response.StatusCode,
|
||||
_latencyInMs,
|
||||
_startTime.ToString("HH:mm:ss.fff"),
|
||||
_endTime.ToString("HH:mm:ss.fff")
|
||||
);
|
||||
}
|
||||
|
||||
public void LogCompilerHostAPIMetrics(HttpContext context)
|
||||
{
|
||||
if (context == null) return;
|
||||
|
||||
_endTime = DateTime.UtcNow;
|
||||
_latencyInMs = Convert.ToInt64((_endTime - _startTime).TotalMilliseconds);
|
||||
|
||||
DiagnosticsETWProvider.Instance.LogCompilerHostAPISummary(
|
||||
_requestId ?? string.Empty,
|
||||
_address ?? string.Empty,
|
||||
_verb ?? string.Empty,
|
||||
context.Response.StatusCode,
|
||||
_latencyInMs,
|
||||
_startTime.ToString("HH:mm:ss.fff"),
|
||||
_endTime.ToString("HH:mm:ss.fff")
|
||||
);
|
||||
}
|
||||
|
||||
public void LogRuntimeHostUnhandledException(HttpContext context, Exception ex)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DiagnosticsETWProvider.Instance.LogRuntimeHostUnhandledException(
|
||||
_requestId ?? string.Empty,
|
||||
_address ?? string.Empty,
|
||||
_subscriptionId ?? string.Empty,
|
||||
_resourceGroupName ?? string.Empty,
|
||||
_resourceName ?? string.Empty,
|
||||
ex != null ? ex.GetType().ToString() : string.Empty,
|
||||
ex != null ? ex.ToString() : string.Empty
|
||||
);
|
||||
}
|
||||
|
||||
public void LogCompilerHostUnhandledException(HttpContext context, Exception ex)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DiagnosticsETWProvider.Instance.LogCompilerHostUnhandledException(
|
||||
_requestId ?? string.Empty,
|
||||
_address ?? string.Empty,
|
||||
ex != null ? ex.GetType().ToString() : string.Empty,
|
||||
ex != null ? ex.ToString() : string.Empty
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Diagnostics.Logger
|
||||
{
|
||||
public class HeaderConstants
|
||||
{
|
||||
public const string RequestIdHeaderName = "x-ms-request-id";
|
||||
public const string EtagHeaderName = "ETag";
|
||||
public const string IfMatchHeaderName = "If-Match";
|
||||
public const string IfNoneMatchHeaderName = "If-None-Match";
|
||||
public const string UserAgentHeaderName = "User-Agent";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Class1.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="2.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.AspNetCore.Http.Abstractions">
|
||||
<HintPath>C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnetcore.http.abstractions\2.0.1\lib\netstandard2.0\Microsoft.AspNetCore.Http.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,89 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Text;
|
||||
|
||||
namespace Diagnostics.Logger
|
||||
{
|
||||
[EventSource(Name = "Microsoft-Azure-AppService-Diagnostics")]
|
||||
public sealed class DiagnosticsETWProvider : DiagnosticsEventSourceBase
|
||||
{
|
||||
public static DiagnosticsETWProvider Instance = new DiagnosticsETWProvider();
|
||||
|
||||
#region Compile Host Events (ID Range : 1000 - 1999)
|
||||
|
||||
[Event(1000, Level = EventLevel.Informational, Channel = EventChannel.Admin)]
|
||||
public void LogCompilerHostStartup(string Message)
|
||||
{
|
||||
WriteDiagnosticsEvent(1000, Message);
|
||||
}
|
||||
|
||||
[Event(1001, Level = EventLevel.Error, Channel = EventChannel.Admin)]
|
||||
public void LogCompilerHostUnhandledException(string RequestId, string Source, string ExceptionType, string ExceptionDetails)
|
||||
{
|
||||
WriteDiagnosticsEvent(1001,
|
||||
RequestId,
|
||||
Source,
|
||||
ExceptionType,
|
||||
ExceptionDetails);
|
||||
}
|
||||
|
||||
[Event(1002, Level = EventLevel.Informational, Channel = EventChannel.Admin)]
|
||||
public void LogCompilerHostAPISummary(string RequestId, string Address, string Verb, int StatusCode, long LatencyInMilliseconds, string StartTime, string EndTime)
|
||||
{
|
||||
WriteDiagnosticsEvent(1002,
|
||||
RequestId,
|
||||
Address,
|
||||
Verb,
|
||||
StatusCode,
|
||||
LatencyInMilliseconds,
|
||||
StartTime,
|
||||
EndTime);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Runtime Host Events (ID Range : 2000 - 2999)
|
||||
|
||||
[Event(2000, Level = EventLevel.Informational, Channel = EventChannel.Admin)]
|
||||
public void LogRuntimeHostStartup(string Message)
|
||||
{
|
||||
WriteDiagnosticsEvent(2000, Message);
|
||||
}
|
||||
|
||||
[Event(2001, Level = EventLevel.Error, Channel = EventChannel.Admin)]
|
||||
public void LogRuntimeHostUnhandledException(string RequestId, string Source, string SubscriptionId, string ResourceGroup, string Resource, string ExceptionType, string ExceptionDetails)
|
||||
{
|
||||
WriteDiagnosticsEvent(2001,
|
||||
RequestId,
|
||||
Source,
|
||||
SubscriptionId,
|
||||
ResourceGroup,
|
||||
Resource,
|
||||
ExceptionType,
|
||||
ExceptionDetails);
|
||||
}
|
||||
|
||||
[Event(2002, Level = EventLevel.Informational, Channel = EventChannel.Admin)]
|
||||
public void LogRuntimeHostAPISummary(string RequestId, string SubscriptionId, string ResourceGroup, string Resource, string Address, string Verb, string OperationName, int StatusCode, long LatencyInMilliseconds, string StartTime, string EndTime)
|
||||
{
|
||||
WriteDiagnosticsEvent(2002,
|
||||
RequestId,
|
||||
SubscriptionId,
|
||||
ResourceGroup,
|
||||
Resource,
|
||||
Address,
|
||||
Verb,
|
||||
OperationName,
|
||||
StatusCode,
|
||||
LatencyInMilliseconds,
|
||||
StartTime,
|
||||
EndTime);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Data Provider Events (ID Range : 3000 - 3999)
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Text;
|
||||
|
||||
namespace Diagnostics.Logger
|
||||
{
|
||||
public abstract class DiagnosticsEventSourceBase : EventSource
|
||||
{
|
||||
[NonEvent]
|
||||
protected void WriteDiagnosticsEvent(int eventId, params object[] args)
|
||||
{
|
||||
WriteEvent(eventId, args);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Diagnostics.DataProviders\Diagnostics.DataProviders.csproj" />
|
||||
<ProjectReference Include="..\Diagnostics.Logger\Diagnostics.Logger.csproj" />
|
||||
<ProjectReference Include="..\Diagnostics.ModelsAndUtils\Diagnostics.ModelsAndUtils.csproj" />
|
||||
<ProjectReference Include="..\Diagnostics.Scripts\Diagnostics.Scripts.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Diagnostics.Logger;
|
||||
using Diagnostics.RuntimeHost.Utilities;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Diagnostics.RuntimeHost.Middleware
|
||||
{
|
||||
public class DiagnosticsRequestMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public DiagnosticsRequestMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext httpContext)
|
||||
{
|
||||
GenerateMissingRequestHeaders(ref httpContext);
|
||||
BeginRequest_Handle(httpContext);
|
||||
|
||||
try
|
||||
{
|
||||
await _next(httpContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!httpContext.Response.HasStarted)
|
||||
{
|
||||
httpContext.Response.Clear();
|
||||
httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
}
|
||||
|
||||
LogException(httpContext, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
EndRequest_Handle(httpContext);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private void BeginRequest_Handle(HttpContext httpContext)
|
||||
{
|
||||
var logger = new ApiMetricsLogger(httpContext);
|
||||
httpContext.Items.Add(HostConstants.ApiLoggerKey, logger);
|
||||
}
|
||||
|
||||
private void EndRequest_Handle(HttpContext httpContext)
|
||||
{
|
||||
ApiMetricsLogger logger = (ApiMetricsLogger)httpContext.Items[HostConstants.ApiLoggerKey];
|
||||
if (logger == null)
|
||||
{
|
||||
logger = new ApiMetricsLogger(httpContext);
|
||||
}
|
||||
|
||||
logger.LogRuntimeHostAPIMetrics(httpContext);
|
||||
}
|
||||
|
||||
private void LogException(HttpContext context, Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
ApiMetricsLogger logger = (ApiMetricsLogger)context.Items[HostConstants.ApiLoggerKey];
|
||||
if (logger == null)
|
||||
{
|
||||
logger = new ApiMetricsLogger(context);
|
||||
}
|
||||
|
||||
logger.LogRuntimeHostUnhandledException(context, ex);
|
||||
}
|
||||
catch (Exception logEx)
|
||||
{
|
||||
DiagnosticsETWProvider.Instance.LogRuntimeHostUnhandledException(
|
||||
string.Empty,
|
||||
"LogException_DiagnosticsRequestMiddleware",
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
logEx.GetType().ToString(),
|
||||
logEx.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateMissingRequestHeaders(ref HttpContext httpContext)
|
||||
{
|
||||
if (!httpContext.Request.Headers.TryGetValue(HeaderConstants.RequestIdHeaderName, out StringValues values)
|
||||
|| values == default(StringValues) || !values.Any() || string.IsNullOrWhiteSpace(values.First()))
|
||||
{
|
||||
httpContext.Request.Headers[HeaderConstants.RequestIdHeaderName] = Guid.NewGuid().ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extension method used to add the middleware to the HTTP request pipeline.
|
||||
public static class DiagnosticsRequestMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseDiagnosticsRequestMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<DiagnosticsRequestMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using Diagnostics.RuntimeHost.Utilities;
|
||||
using Diagnostics.Logger;
|
||||
using Diagnostics.RuntimeHost.Utilities;
|
||||
using Diagnostics.Scripts;
|
||||
using Diagnostics.Scripts.Models;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
@ -26,7 +27,6 @@ namespace Diagnostics.RuntimeHost.Services.SourceWatcher
|
|||
private string _lastModifiedMarkerName;
|
||||
private string _deleteMarkerName;
|
||||
private string _cacheIdFileName;
|
||||
private string _etagHeaderName;
|
||||
|
||||
private string _destinationCsxPath;
|
||||
private int _pollingIntervalInSeconds;
|
||||
|
@ -41,7 +41,6 @@ namespace Diagnostics.RuntimeHost.Services.SourceWatcher
|
|||
_lastModifiedMarkerName = "_lastModified.marker";
|
||||
_deleteMarkerName = "_delete.marker";
|
||||
_cacheIdFileName = "cacheId.txt";
|
||||
_etagHeaderName = "ETag";
|
||||
LoadConfigurations();
|
||||
Start();
|
||||
}
|
||||
|
@ -84,7 +83,7 @@ namespace Diagnostics.RuntimeHost.Services.SourceWatcher
|
|||
return;
|
||||
}
|
||||
|
||||
string githubRootContentETag = GetHeaderValue(response, _etagHeaderName).Replace("W/", string.Empty);
|
||||
string githubRootContentETag = GetHeaderValue(response, HeaderConstants.EtagHeaderName).Replace("W/", string.Empty);
|
||||
GithubEntry[] githubDirectories = await response.Content.ReadAsAsyncCustom<GithubEntry[]>();
|
||||
|
||||
foreach (GithubEntry gitHubDir in githubDirectories)
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Diagnostics.DataProviders;
|
||||
using Diagnostics.RuntimeHost.Middleware;
|
||||
using Diagnostics.RuntimeHost.Services;
|
||||
using Diagnostics.RuntimeHost.Services.SourceWatcher;
|
||||
using Diagnostics.Scripts;
|
||||
|
@ -54,6 +55,7 @@ namespace Diagnostics.RuntimeHost
|
|||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseDiagnosticsRequestMiddleware();
|
||||
app.UseMvc();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace Diagnostics.RuntimeHost.Utilities
|
|||
internal class HostConstants
|
||||
{
|
||||
internal const int WatcherDefaultPollingIntervalInSeconds = 5 * 60;
|
||||
internal const string ApiLoggerKey = "API_LOGGER";
|
||||
|
||||
// These Configurations probably should be in Data Providers
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче