Reorganize source code in preparation to move into aspnet/Extensions
Prior to reorganization, this source code was found in f7d8e4e053
This commit is contained in:
parent
08375cd15c
commit
fc4e64de38
|
|
@ -7,6 +7,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Microsoft.Extensions.Logging.AzureAppServices;
|
using Microsoft.Extensions.Logging.AzureAppServices;
|
||||||
using Microsoft.Extensions.Logging.AzureAppServices.Internal;
|
using Microsoft.Extensions.Logging.AzureAppServices.Internal;
|
||||||
|
using Microsoft.Extensions.Logging.Configuration;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using static Microsoft.Extensions.DependencyInjection.ServiceDescriptor;
|
using static Microsoft.Extensions.DependencyInjection.ServiceDescriptor;
|
||||||
|
|
||||||
|
|
@ -55,6 +56,7 @@ namespace Microsoft.Extensions.Logging
|
||||||
services.AddSingleton<IConfigureOptions<AzureFileLoggerOptions>>(new FileLoggerConfigureOptions(config, context));
|
services.AddSingleton<IConfigureOptions<AzureFileLoggerOptions>>(new FileLoggerConfigureOptions(config, context));
|
||||||
services.AddSingleton<IOptionsChangeTokenSource<AzureFileLoggerOptions>>(
|
services.AddSingleton<IOptionsChangeTokenSource<AzureFileLoggerOptions>>(
|
||||||
new ConfigurationChangeTokenSource<AzureFileLoggerOptions>(config));
|
new ConfigurationChangeTokenSource<AzureFileLoggerOptions>(config));
|
||||||
|
LoggerProviderOptions.RegisterProviderOptions<AzureFileLoggerOptions, FileLoggerProvider>(builder.Services);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addedBlobLogger)
|
if (addedBlobLogger)
|
||||||
|
|
@ -63,6 +65,7 @@ namespace Microsoft.Extensions.Logging
|
||||||
services.AddSingleton<IConfigureOptions<AzureBlobLoggerOptions>>(new BlobLoggerConfigureOptions(config, context));
|
services.AddSingleton<IConfigureOptions<AzureBlobLoggerOptions>>(new BlobLoggerConfigureOptions(config, context));
|
||||||
services.AddSingleton<IOptionsChangeTokenSource<AzureBlobLoggerOptions>>(
|
services.AddSingleton<IOptionsChangeTokenSource<AzureBlobLoggerOptions>>(
|
||||||
new ConfigurationChangeTokenSource<AzureBlobLoggerOptions>(config));
|
new ConfigurationChangeTokenSource<AzureBlobLoggerOptions>(config));
|
||||||
|
LoggerProviderOptions.RegisterProviderOptions<AzureBlobLoggerOptions, BlobLoggerProvider>(builder.Services);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,9 @@ namespace Microsoft.Extensions.Logging.AzureAppServices
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a strictly positive value representing the maximum retained file count or null for no limit.
|
/// Gets or sets a string representing the prefix of the file name used to store the logging information.
|
||||||
/// Defaults to <c>2</c>.
|
/// The current date, in the format YYYYMMDD will be added after the given value.
|
||||||
|
/// Defaults to <c>diagnostics-</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string FileName
|
public string FileName
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,22 @@ namespace Microsoft.Extensions.Logging.AzureAppServices.Internal
|
||||||
builder.Append(logLevel.ToString());
|
builder.Append(logLevel.ToString());
|
||||||
builder.Append("] ");
|
builder.Append("] ");
|
||||||
builder.Append(_category);
|
builder.Append(_category);
|
||||||
builder.Append(": ");
|
|
||||||
|
var scopeProvider = _provider.ScopeProvider;
|
||||||
|
if (scopeProvider != null)
|
||||||
|
{
|
||||||
|
scopeProvider.ForEachScope((scope, stringBuilder) =>
|
||||||
|
{
|
||||||
|
stringBuilder.Append(" => ").Append(scope);
|
||||||
|
}, builder);
|
||||||
|
|
||||||
|
builder.AppendLine(":");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.Append(": ");
|
||||||
|
}
|
||||||
|
|
||||||
builder.AppendLine(formatter(state, exception));
|
builder.AppendLine(formatter(state, exception));
|
||||||
|
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
|
|
|
||||||
|
|
@ -66,5 +66,11 @@ namespace Microsoft.Extensions.Logging.AzureAppServices.Internal
|
||||||
/// Gets or sets value indicating if logger accepts and queues writes.
|
/// Gets or sets value indicating if logger accepts and queues writes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether scopes should be included in the message.
|
||||||
|
/// Defaults to <c>false</c>.
|
||||||
|
/// </summary>
|
||||||
|
public bool IncludeScopes { get; set; } = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.Logging.AzureAppServices.Internal
|
namespace Microsoft.Extensions.Logging.AzureAppServices.Internal
|
||||||
{
|
{
|
||||||
public abstract class BatchingLoggerProvider: ILoggerProvider
|
public abstract class BatchingLoggerProvider: ILoggerProvider, ISupportExternalScope
|
||||||
{
|
{
|
||||||
private readonly List<LogMessage> _currentBatch = new List<LogMessage>();
|
private readonly List<LogMessage> _currentBatch = new List<LogMessage>();
|
||||||
private readonly TimeSpan _interval;
|
private readonly TimeSpan _interval;
|
||||||
|
|
@ -22,6 +22,11 @@ namespace Microsoft.Extensions.Logging.AzureAppServices.Internal
|
||||||
private Task _outputTask;
|
private Task _outputTask;
|
||||||
private CancellationTokenSource _cancellationTokenSource;
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
|
|
||||||
|
private bool _includeScopes;
|
||||||
|
private IExternalScopeProvider _scopeProvider;
|
||||||
|
|
||||||
|
internal IExternalScopeProvider ScopeProvider => _includeScopes ? _scopeProvider : null;
|
||||||
|
|
||||||
protected BatchingLoggerProvider(IOptionsMonitor<BatchingLoggerOptions> options)
|
protected BatchingLoggerProvider(IOptionsMonitor<BatchingLoggerOptions> options)
|
||||||
{
|
{
|
||||||
// NOTE: Only IsEnabled is monitored
|
// NOTE: Only IsEnabled is monitored
|
||||||
|
|
@ -50,6 +55,8 @@ namespace Microsoft.Extensions.Logging.AzureAppServices.Internal
|
||||||
{
|
{
|
||||||
var oldIsEnabled = IsEnabled;
|
var oldIsEnabled = IsEnabled;
|
||||||
IsEnabled = options.IsEnabled;
|
IsEnabled = options.IsEnabled;
|
||||||
|
_includeScopes = options.IncludeScopes;
|
||||||
|
|
||||||
if (oldIsEnabled != IsEnabled)
|
if (oldIsEnabled != IsEnabled)
|
||||||
{
|
{
|
||||||
if (IsEnabled)
|
if (IsEnabled)
|
||||||
|
|
@ -159,5 +166,10 @@ namespace Microsoft.Extensions.Logging.AzureAppServices.Internal
|
||||||
{
|
{
|
||||||
return new BatchingLogger(this, categoryName);
|
return new BatchingLogger(this, categoryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ISupportExternalScope.SetScopeProvider(IExternalScopeProvider scopeProvider)
|
||||||
|
{
|
||||||
|
_scopeProvider = scopeProvider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.Logging.AzureAppServices.Internal;
|
using Microsoft.Extensions.Logging.AzureAppServices.Internal;
|
||||||
|
|
@ -13,8 +14,9 @@ namespace Microsoft.Extensions.Logging.AzureAppServices.Test
|
||||||
{
|
{
|
||||||
public class BatchingLoggerProviderTests
|
public class BatchingLoggerProviderTests
|
||||||
{
|
{
|
||||||
DateTimeOffset _timestampOne = new DateTimeOffset(2016, 05, 04, 03, 02, 01, TimeSpan.Zero);
|
private DateTimeOffset _timestampOne = new DateTimeOffset(2016, 05, 04, 03, 02, 01, TimeSpan.Zero);
|
||||||
string _nl = Environment.NewLine;
|
private string _nl = Environment.NewLine;
|
||||||
|
private Regex _timeStampRegex = new Regex(@"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3} .\d{2}:\d{2} ");
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task LogsInIntervals()
|
public async Task LogsInIntervals()
|
||||||
|
|
@ -34,6 +36,33 @@ namespace Microsoft.Extensions.Logging.AzureAppServices.Test
|
||||||
Assert.Equal("2016-05-04 04:02:01.000 +00:00 [Error] Cat: Error message" + _nl, provider.Batches[0][1].Message);
|
Assert.Equal("2016-05-04 04:02:01.000 +00:00 [Error] Cat: Error message" + _nl, provider.Batches[0][1].Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task IncludesScopes()
|
||||||
|
{
|
||||||
|
var provider = new TestBatchingLoggingProvider(includeScopes: true);
|
||||||
|
var factory = new LoggerFactory(new [] { provider });
|
||||||
|
var logger = factory.CreateLogger("Cat");
|
||||||
|
|
||||||
|
await provider.IntervalControl.Pause;
|
||||||
|
|
||||||
|
using (logger.BeginScope("Scope"))
|
||||||
|
{
|
||||||
|
using (logger.BeginScope("Scope2"))
|
||||||
|
{
|
||||||
|
logger.Log(LogLevel.Information, 0, "Info message", null, (state, ex) => state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider.IntervalControl.Resume();
|
||||||
|
await provider.IntervalControl.Pause;
|
||||||
|
|
||||||
|
Assert.Matches(_timeStampRegex, provider.Batches[0][0].Message);
|
||||||
|
Assert.EndsWith(
|
||||||
|
" [Information] Cat => Scope => Scope2:" + _nl +
|
||||||
|
"Info message" + _nl,
|
||||||
|
provider.Batches[0][0].Message);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task RespectsBatchSize()
|
public async Task RespectsBatchSize()
|
||||||
{
|
{
|
||||||
|
|
@ -85,13 +114,14 @@ namespace Microsoft.Extensions.Logging.AzureAppServices.Test
|
||||||
public List<LogMessage[]> Batches { get; } = new List<LogMessage[]>();
|
public List<LogMessage[]> Batches { get; } = new List<LogMessage[]>();
|
||||||
public ManualIntervalControl IntervalControl { get; } = new ManualIntervalControl();
|
public ManualIntervalControl IntervalControl { get; } = new ManualIntervalControl();
|
||||||
|
|
||||||
public TestBatchingLoggingProvider(TimeSpan? interval = null, int? maxBatchSize = null, int? maxQueueSize = null)
|
public TestBatchingLoggingProvider(TimeSpan? interval = null, int? maxBatchSize = null, int? maxQueueSize = null, bool includeScopes = false)
|
||||||
: base(new OptionsWrapperMonitor<BatchingLoggerOptions>(new BatchingLoggerOptions
|
: base(new OptionsWrapperMonitor<BatchingLoggerOptions>(new BatchingLoggerOptions
|
||||||
{
|
{
|
||||||
FlushPeriod = interval ?? TimeSpan.FromSeconds(1),
|
FlushPeriod = interval ?? TimeSpan.FromSeconds(1),
|
||||||
BatchSize = maxBatchSize,
|
BatchSize = maxBatchSize,
|
||||||
BackgroundQueueSize = maxQueueSize,
|
BackgroundQueueSize = maxQueueSize,
|
||||||
IsEnabled = true
|
IsEnabled = true,
|
||||||
|
IncludeScopes = includeScopes
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ namespace Microsoft.Extensions.Logging.Testing
|
||||||
{
|
{
|
||||||
public interface ITestSink
|
public interface ITestSink
|
||||||
{
|
{
|
||||||
|
event Action<WriteContext> MessageLogged;
|
||||||
|
|
||||||
|
event Action<BeginScopeContext> ScopeStarted;
|
||||||
|
|
||||||
Func<WriteContext, bool> WriteEnabled { get; set; }
|
Func<WriteContext, bool> WriteEnabled { get; set; }
|
||||||
|
|
||||||
Func<BeginScopeContext, bool> BeginEnabled { get; set; }
|
Func<BeginScopeContext, bool> BeginEnabled { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,9 @@ namespace Microsoft.Extensions.Logging.Testing
|
||||||
TestOutputHelper = testOutputHelper;
|
TestOutputHelper = testOutputHelper;
|
||||||
|
|
||||||
var classType = GetType();
|
var classType = GetType();
|
||||||
var logLevelAttribute = methodInfo.GetCustomAttribute<LogLevelAttribute>();
|
var logLevelAttribute = methodInfo.GetCustomAttribute<LogLevelAttribute>()
|
||||||
|
?? methodInfo.DeclaringType.GetCustomAttribute<LogLevelAttribute>()
|
||||||
|
?? methodInfo.DeclaringType.Assembly.GetCustomAttribute<LogLevelAttribute>();
|
||||||
var testName = testMethodArguments.Aggregate(methodInfo.Name, (a, b) => $"{a}-{(b ?? "null")}");
|
var testName = testMethodArguments.Aggregate(methodInfo.Name, (a, b) => $"{a}-{(b ?? "null")}");
|
||||||
|
|
||||||
var useShortClassName = methodInfo.DeclaringType.GetCustomAttribute<ShortClassNameAttribute>()
|
var useShortClassName = methodInfo.DeclaringType.GetCustomAttribute<ShortClassNameAttribute>()
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,17 @@ namespace Microsoft.Extensions.Logging.Testing
|
||||||
|
|
||||||
public IProducerConsumerCollection<WriteContext> Writes { get => _writes; set => _writes = new ConcurrentQueue<WriteContext>(value); }
|
public IProducerConsumerCollection<WriteContext> Writes { get => _writes; set => _writes = new ConcurrentQueue<WriteContext>(value); }
|
||||||
|
|
||||||
|
public event Action<WriteContext> MessageLogged;
|
||||||
|
|
||||||
|
public event Action<BeginScopeContext> ScopeStarted;
|
||||||
|
|
||||||
public void Write(WriteContext context)
|
public void Write(WriteContext context)
|
||||||
{
|
{
|
||||||
if (WriteEnabled == null || WriteEnabled(context))
|
if (WriteEnabled == null || WriteEnabled(context))
|
||||||
{
|
{
|
||||||
_writes.Enqueue(context);
|
_writes.Enqueue(context);
|
||||||
}
|
}
|
||||||
|
MessageLogged?.Invoke(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Begin(BeginScopeContext context)
|
public void Begin(BeginScopeContext context)
|
||||||
|
|
@ -44,6 +49,7 @@ namespace Microsoft.Extensions.Logging.Testing
|
||||||
{
|
{
|
||||||
_scopes.Enqueue(context);
|
_scopes.Enqueue(context);
|
||||||
}
|
}
|
||||||
|
ScopeStarted?.Invoke(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool EnableWithTypeName<T>(WriteContext context)
|
public static bool EnableWithTypeName<T>(WriteContext context)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ using System;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.Logging.Testing
|
namespace Microsoft.Extensions.Logging.Testing
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false)]
|
||||||
public class LogLevelAttribute : Attribute
|
public class LogLevelAttribute : Attribute
|
||||||
{
|
{
|
||||||
public LogLevelAttribute(LogLevel logLevel)
|
public LogLevelAttribute(LogLevel logLevel)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Testing.xunit;
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
@ -9,6 +10,7 @@ using Xunit.Abstractions;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.Logging.Testing.Tests
|
namespace Microsoft.Extensions.Logging.Testing.Tests
|
||||||
{
|
{
|
||||||
|
[LogLevel(LogLevel.Debug)]
|
||||||
[ShortClassName]
|
[ShortClassName]
|
||||||
public class LoggedTestXunitTests : TestLoggedTest
|
public class LoggedTestXunitTests : TestLoggedTest
|
||||||
{
|
{
|
||||||
|
|
@ -75,7 +77,7 @@ namespace Microsoft.Extensions.Logging.Testing.Tests
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[LogLevel(LogLevel.Information)]
|
[LogLevel(LogLevel.Information)]
|
||||||
public void LoggedFactFilteredByLogLevel()
|
public void LoggedFactFilteredByMethodLogLevel()
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Information");
|
Logger.LogInformation("Information");
|
||||||
Logger.LogDebug("Debug");
|
Logger.LogDebug("Debug");
|
||||||
|
|
@ -85,6 +87,17 @@ namespace Microsoft.Extensions.Logging.Testing.Tests
|
||||||
Assert.Equal("Information", message.Formatter(message.State, null));
|
Assert.Equal("Information", message.Formatter(message.State, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LoggedFactFilteredByClassLogLevel()
|
||||||
|
{
|
||||||
|
Logger.LogDebug("Debug");
|
||||||
|
Logger.LogTrace("Trace");
|
||||||
|
|
||||||
|
var message = Assert.Single(TestSink.Writes);
|
||||||
|
Assert.Equal(LogLevel.Debug, message.LogLevel);
|
||||||
|
Assert.Equal("Debug", message.Formatter(message.State, null));
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("Hello world")]
|
[InlineData("Hello world")]
|
||||||
[LogLevel(LogLevel.Information)]
|
[LogLevel(LogLevel.Information)]
|
||||||
|
|
@ -129,6 +142,37 @@ namespace Microsoft.Extensions.Logging.Testing.Tests
|
||||||
{
|
{
|
||||||
Assert.True(SetupInvoked);
|
Assert.True(SetupInvoked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void MessageWrittenEventInvoked()
|
||||||
|
{
|
||||||
|
WriteContext context = null;
|
||||||
|
TestSink.MessageLogged += ctx => context = ctx;
|
||||||
|
Logger.LogInformation("Information");
|
||||||
|
Assert.Equal(TestSink.Writes.Single(), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ScopeStartedEventInvoked()
|
||||||
|
{
|
||||||
|
BeginScopeContext context = null;
|
||||||
|
TestSink.ScopeStarted += ctx => context = ctx;
|
||||||
|
using (Logger.BeginScope("Scope")) {}
|
||||||
|
Assert.Equal(TestSink.Scopes.Single(), context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LoggedTestXunitLogLevelTests : LoggedTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void LoggedFactFilteredByAssemblyLogLevel()
|
||||||
|
{
|
||||||
|
Logger.LogTrace("Trace");
|
||||||
|
|
||||||
|
var message = Assert.Single(TestSink.Writes);
|
||||||
|
Assert.Equal(LogLevel.Trace, message.LogLevel);
|
||||||
|
Assert.Equal("Trace", message.Formatter(message.State, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LoggedTestXunitInitializationTests : TestLoggedTest
|
public class LoggedTestXunitInitializationTests : TestLoggedTest
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
|
|
||||||
|
[assembly: LogLevel(LogLevel.Trace)]
|
||||||
Loading…
Reference in New Issue