Use implicit logging scope for Activity (#22376)
* Revert "Hoist activity fields to the logging scope (#11211)"
This reverts commit f7a2d3c26c.
* Remove tests with Activity
* Remove ActivityId from HostingLogScope
* Enable propogation in CreateDefaultBuilder
* Clean up
* s/logging/loggingBuilder
* Enable Activity propogation for generichost
* Replace with runtime/pull/37892
This commit is contained in:
parent
36be16b640
commit
c97a0020d8
|
|
@ -189,12 +189,18 @@ namespace Microsoft.AspNetCore
|
||||||
config.AddCommandLine(args);
|
config.AddCommandLine(args);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.ConfigureLogging((hostingContext, logging) =>
|
.ConfigureLogging((hostingContext, loggingBuilder) =>
|
||||||
{
|
{
|
||||||
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
|
loggingBuilder.Configure(options =>
|
||||||
logging.AddConsole();
|
{
|
||||||
logging.AddDebug();
|
options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
|
||||||
logging.AddEventSourceLogger();
|
| ActivityTrackingOptions.TraceId
|
||||||
|
| ActivityTrackingOptions.ParentId;
|
||||||
|
});
|
||||||
|
loggingBuilder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
|
||||||
|
loggingBuilder.AddConsole();
|
||||||
|
loggingBuilder.AddDebug();
|
||||||
|
loggingBuilder.AddEventSourceLogger();
|
||||||
}).
|
}).
|
||||||
UseDefaultServiceProvider((context, options) =>
|
UseDefaultServiceProvider((context, options) =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Hosting
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Helpers for getting the right values from Activity no matter the format (w3c or hierarchical)
|
|
||||||
/// </summary>
|
|
||||||
internal static class ActivityExtensions
|
|
||||||
{
|
|
||||||
public static string GetSpanId(this Activity activity)
|
|
||||||
{
|
|
||||||
return activity.IdFormat switch
|
|
||||||
{
|
|
||||||
ActivityIdFormat.Hierarchical => activity.Id,
|
|
||||||
ActivityIdFormat.W3C => activity.SpanId.ToHexString(),
|
|
||||||
_ => null,
|
|
||||||
} ?? string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetTraceId(this Activity activity)
|
|
||||||
{
|
|
||||||
return activity.IdFormat switch
|
|
||||||
{
|
|
||||||
ActivityIdFormat.Hierarchical => activity.RootId,
|
|
||||||
ActivityIdFormat.W3C => activity.TraceId.ToHexString(),
|
|
||||||
_ => null,
|
|
||||||
} ?? string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetParentId(this Activity activity)
|
|
||||||
{
|
|
||||||
return activity.IdFormat switch
|
|
||||||
{
|
|
||||||
ActivityIdFormat.Hierarchical => activity.ParentId,
|
|
||||||
ActivityIdFormat.W3C => activity.ParentSpanId.ToHexString(),
|
|
||||||
_ => null,
|
|
||||||
} ?? string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Hosting
|
||||||
// Scope may be relevant for a different level of logging, so we always create it
|
// Scope may be relevant for a different level of logging, so we always create it
|
||||||
// see: https://github.com/aspnet/Hosting/pull/944
|
// see: https://github.com/aspnet/Hosting/pull/944
|
||||||
// Scope can be null if logging is not on.
|
// Scope can be null if logging is not on.
|
||||||
context.Scope = _logger.RequestScope(httpContext, context.Activity);
|
context.Scope = _logger.RequestScope(httpContext);
|
||||||
|
|
||||||
if (_logger.IsEnabled(LogLevel.Information))
|
if (_logger.IsEnabled(LogLevel.Information))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
@ -14,9 +13,9 @@ namespace Microsoft.AspNetCore.Hosting
|
||||||
{
|
{
|
||||||
internal static class HostingLoggerExtensions
|
internal static class HostingLoggerExtensions
|
||||||
{
|
{
|
||||||
public static IDisposable RequestScope(this ILogger logger, HttpContext httpContext, Activity activity)
|
public static IDisposable RequestScope(this ILogger logger, HttpContext httpContext)
|
||||||
{
|
{
|
||||||
return logger.BeginScope(new HostingLogScope(httpContext, activity));
|
return logger.BeginScope(new HostingLogScope(httpContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ApplicationError(this ILogger logger, Exception exception)
|
public static void ApplicationError(this ILogger logger, Exception exception)
|
||||||
|
|
@ -97,7 +96,6 @@ namespace Microsoft.AspNetCore.Hosting
|
||||||
{
|
{
|
||||||
private readonly string _path;
|
private readonly string _path;
|
||||||
private readonly string _traceIdentifier;
|
private readonly string _traceIdentifier;
|
||||||
private readonly Activity _activity;
|
|
||||||
|
|
||||||
private string _cachedToString;
|
private string _cachedToString;
|
||||||
|
|
||||||
|
|
@ -105,7 +103,7 @@ namespace Microsoft.AspNetCore.Hosting
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return 5;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,31 +119,17 @@ namespace Microsoft.AspNetCore.Hosting
|
||||||
{
|
{
|
||||||
return new KeyValuePair<string, object>("RequestPath", _path);
|
return new KeyValuePair<string, object>("RequestPath", _path);
|
||||||
}
|
}
|
||||||
else if (index == 2)
|
|
||||||
{
|
|
||||||
return new KeyValuePair<string, object>("SpanId", _activity.GetSpanId());
|
|
||||||
}
|
|
||||||
else if (index == 3)
|
|
||||||
{
|
|
||||||
return new KeyValuePair<string, object>("TraceId", _activity.GetTraceId());
|
|
||||||
}
|
|
||||||
else if (index == 4)
|
|
||||||
{
|
|
||||||
return new KeyValuePair<string, object>("ParentId", _activity.GetParentId());
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(index));
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public HostingLogScope(HttpContext httpContext, Activity activity)
|
public HostingLogScope(HttpContext httpContext)
|
||||||
{
|
{
|
||||||
_traceIdentifier = httpContext.TraceIdentifier;
|
_traceIdentifier = httpContext.TraceIdentifier;
|
||||||
_path = (httpContext.Request.PathBase.HasValue
|
_path = (httpContext.Request.PathBase.HasValue
|
||||||
? httpContext.Request.PathBase + httpContext.Request.Path
|
? httpContext.Request.PathBase + httpContext.Request.Path
|
||||||
: httpContext.Request.Path).ToString();
|
: httpContext.Request.Path).ToString();
|
||||||
|
|
||||||
_activity = activity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
@ -154,12 +138,9 @@ namespace Microsoft.AspNetCore.Hosting
|
||||||
{
|
{
|
||||||
_cachedToString = string.Format(
|
_cachedToString = string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
"RequestPath:{0} RequestId:{1}, SpanId:{2}, TraceId:{3}, ParentId:{4}",
|
"RequestPath:{0} RequestId:{1}",
|
||||||
_path,
|
_path,
|
||||||
_traceIdentifier,
|
_traceIdentifier);
|
||||||
_activity.GetSpanId(),
|
|
||||||
_activity.GetTraceId(),
|
|
||||||
_activity.GetParentId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _cachedToString;
|
return _cachedToString;
|
||||||
|
|
|
||||||
|
|
@ -40,50 +40,6 @@ namespace Microsoft.AspNetCore.Hosting.Tests
|
||||||
Assert.Null(Activity.Current);
|
Assert.Null(Activity.Current);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CreateContextWithEnabledLoggerCreatesActivityAndSetsActivityInScope()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var logger = new LoggerWithScopes(isEnabled: true);
|
|
||||||
var hostingApplication = CreateApplication(out var features, logger: logger);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var context = hostingApplication.CreateContext(features);
|
|
||||||
|
|
||||||
Assert.Single(logger.Scopes);
|
|
||||||
var pairs = ((IReadOnlyList<KeyValuePair<string, object>>)logger.Scopes[0]).ToDictionary(p => p.Key, p => p.Value);
|
|
||||||
Assert.Equal(Activity.Current.Id, pairs["SpanId"].ToString());
|
|
||||||
Assert.Equal(Activity.Current.RootId, pairs["TraceId"].ToString());
|
|
||||||
Assert.Equal(string.Empty, pairs["ParentId"]?.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CreateContextWithEnabledLoggerAndRequestIdCreatesActivityAndSetsActivityInScope()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
|
|
||||||
// Generate an id we can use for the request id header (in the correct format)
|
|
||||||
var activity = new Activity("IncomingRequest");
|
|
||||||
activity.Start();
|
|
||||||
var id = activity.Id;
|
|
||||||
activity.Stop();
|
|
||||||
|
|
||||||
var logger = new LoggerWithScopes(isEnabled: true);
|
|
||||||
var hostingApplication = CreateApplication(out var features, logger: logger, configure: context =>
|
|
||||||
{
|
|
||||||
context.Request.Headers["Request-Id"] = id;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var context = hostingApplication.CreateContext(features);
|
|
||||||
|
|
||||||
Assert.Single(logger.Scopes);
|
|
||||||
var pairs = ((IReadOnlyList<KeyValuePair<string, object>>)logger.Scopes[0]).ToDictionary(p => p.Key, p => p.Value);
|
|
||||||
Assert.Equal(Activity.Current.Id, pairs["SpanId"].ToString());
|
|
||||||
Assert.Equal(Activity.Current.RootId, pairs["TraceId"].ToString());
|
|
||||||
Assert.Equal(id, pairs["ParentId"].ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ActivityStopDoesNotFireIfNoListenerAttachedForStart()
|
public void ActivityStopDoesNotFireIfNoListenerAttachedForStart()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue