Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

React to Logging API changes #584

Merged
merged 1 commit into from
Jan 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 119 additions & 44 deletions src/Microsoft.AspNetCore.Hosting/Internal/HostingLoggerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

Expand Down Expand Up @@ -52,7 +53,7 @@ public static void ApplicationError(this ILogger logger, Exception exception)
logger.LogError(
eventId: LoggerEventIds.ApplicationStartupException,
message: "Application startup exception",
error: exception);
exception: exception);
}

public static void Starting(this ILogger logger)
Expand All @@ -61,7 +62,7 @@ public static void Starting(this ILogger logger)
{
logger.LogDebug(
eventId: LoggerEventIds.Starting,
data: "Hosting starting");
message: "Hosting starting");
}
}

Expand All @@ -71,7 +72,7 @@ public static void Started(this ILogger logger)
{
logger.LogDebug(
eventId: LoggerEventIds.Started,
data: "Hosting started");
message: "Hosting started");
}
}

Expand All @@ -81,17 +82,40 @@ public static void Shutdown(this ILogger logger)
{
logger.LogDebug(
eventId: LoggerEventIds.Shutdown,
data: "Hosting shutdown");
message: "Hosting shutdown");
}
}


private class HostingLogScope : ILogValues
private class HostingLogScope : IReadOnlyList<KeyValuePair<string, object>>
{
private readonly HttpContext _httpContext;

private string _cachedToString;
private IEnumerable<KeyValuePair<string, object>> _cachedGetValues;

public int Count
{
get
{
return 2;
}
}

public KeyValuePair<string, object> this[int index]
{
get
{
if (index == 0)
{
return new KeyValuePair<string, object>("RequestId", _httpContext.TraceIdentifier);
}
else if (index == 1)
{
return new KeyValuePair<string, object>("RequestPath", _httpContext.Request.Path.ToString());
}
throw new IndexOutOfRangeException(nameof(index));
}
}

public HostingLogScope(HttpContext httpContext)
{
Expand All @@ -108,29 +132,65 @@ public override string ToString()
return _cachedToString;
}

public IEnumerable<KeyValuePair<string, object>> GetValues()
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
if (_cachedGetValues == null)
for (int i = 0; i < Count; ++i)
{
_cachedGetValues = new[]
{
new KeyValuePair<string, object>("RequestId", _httpContext.TraceIdentifier),
new KeyValuePair<string, object>("RequestPath", _httpContext.Request.Path.ToString()),
};
yield return this[i];
}
}

return _cachedGetValues;
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

private class HostingRequestStarting : ILogValues
private class HostingRequestStarting : IReadOnlyList<KeyValuePair<string, object>>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per #592 - HostingRequestFinished below requires updating as well.

{
internal static readonly Func<object, Exception, string> Callback = (state, exception) => ((HostingRequestStarting)state).ToString();

private readonly HttpRequest _request;

private string _cachedToString;
private IEnumerable<KeyValuePair<string, object>> _cachedGetValues;

public int Count
{
get
{
return 9;
}
}

public KeyValuePair<string, object> this[int index]
{
get
{
switch (index)
{
case 0:
return new KeyValuePair<string, object>("Protocol", _request.Protocol);
case 1:
return new KeyValuePair<string, object>("Method", _request.Method);
case 2:
return new KeyValuePair<string, object>("ContentType", _request.ContentType);
case 3:
return new KeyValuePair<string, object>("ContentLength", _request.ContentLength);
case 4:
return new KeyValuePair<string, object>("Scheme", _request.Scheme.ToString());
case 5:
return new KeyValuePair<string, object>("Host", _request.Host.ToString());
case 6:
return new KeyValuePair<string, object>("PathBase", _request.PathBase.ToString());
case 7:
return new KeyValuePair<string, object>("Path", _request.Path.ToString());
case 8:
return new KeyValuePair<string, object>("QueryString", _request.QueryString.ToString());
default:
throw new IndexOutOfRangeException(nameof(index));
}
}
}

public HostingRequestStarting(HttpContext httpContext)
{
Expand All @@ -147,38 +207,55 @@ public override string ToString()
return _cachedToString;
}

public IEnumerable<KeyValuePair<string, object>> GetValues()
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
if (_cachedGetValues == null)
for (int i = 0; i < Count; ++i)
{
_cachedGetValues = new[]
{
new KeyValuePair<string, object>("Protocol", _request.Protocol),
new KeyValuePair<string, object>("Method", _request.Method),
new KeyValuePair<string, object>("ContentType", _request.ContentType),
new KeyValuePair<string, object>("ContentLength", _request.ContentLength),
new KeyValuePair<string, object>("Scheme", _request.Scheme.ToString()),
new KeyValuePair<string, object>("Host", _request.Host.ToString()),
new KeyValuePair<string, object>("PathBase", _request.PathBase.ToString()),
new KeyValuePair<string, object>("Path", _request.Path.ToString()),
new KeyValuePair<string, object>("QueryString", _request.QueryString.ToString()),
};
yield return this[i];
}
}

return _cachedGetValues;
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

private class HostingRequestFinished
private class HostingRequestFinished : IReadOnlyList<KeyValuePair<string, object>>
{
internal static readonly Func<object, Exception, string> Callback = (state, exception) => ((HostingRequestFinished)state).ToString();

private readonly HttpContext _httpContext;
private readonly TimeSpan _elapsed;

private IEnumerable<KeyValuePair<string, object>> _cachedGetValues;

private string _cachedToString;

public int Count
{
get
{
return 3;
}
}

public KeyValuePair<string, object> this[int index]
{
get
{
switch (index)
{
case 0:
return new KeyValuePair<string, object>("ElapsedMilliseconds", _elapsed.TotalMilliseconds);
case 1:
return new KeyValuePair<string, object>("StatusCode", _httpContext.Response.StatusCode);
case 2:
return new KeyValuePair<string, object>("ContentType", _httpContext.Response.ContentType);
default:
throw new IndexOutOfRangeException(nameof(index));
}
}
}

public HostingRequestFinished(HttpContext httpContext, TimeSpan elapsed)
{
_httpContext = httpContext;
Expand All @@ -195,19 +272,17 @@ public override string ToString()
return _cachedToString;
}

public IEnumerable<KeyValuePair<string, object>> GetValues()
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
if (_cachedGetValues == null)
for (int i = 0; i < Count; ++i)
{
_cachedGetValues = new[]
{
new KeyValuePair<string, object>("ElapsedMilliseconds", _elapsed.TotalMilliseconds),
new KeyValuePair<string, object>("StatusCode", _httpContext.Response.StatusCode),
new KeyValuePair<string, object>("ContentType", _httpContext.Response.ContentType),
};
yield return this[i];
}
}

return _cachedGetValues;
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public static async Task<HttpResponseMessage> RetryRequest(
{
if (retry == retryCount - 1)
{
logger.LogError("Failed to connect, retry limit exceeded.", exception);
logger.LogError(0, exception, "Failed to connect, retry limit exceeded.");
throw;
}
else
Expand Down
2 changes: 1 addition & 1 deletion test/Microsoft.AspNetCore.Hosting.Tests/WebHostTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ public IDisposable BeginScopeImpl(object state)
var stringified = state.ToString();
return this;
}
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
var stringified = formatter(state, exception);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ private class VerifierLogger : ILogger<WebHost>
public bool IsEnabled(LogLevel logLevel) => true;

// This call verifies that fields of HttpRequest are accessed and valid
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter) => formatter(state, exception);
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) => formatter(state, exception);

class NoopDispoasble : IDisposable
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ private class VerifierLogger : ILogger<WebHost>
public bool IsEnabled(LogLevel logLevel) => true;

// This call verifies that fields of HttpRequest are accessed and valid
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter) => formatter(state, exception);
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) => formatter(state, exception);

class NoopDispoasble : IDisposable
{
Expand Down