Skip to content

Commit

Permalink
Load JSON based NLog config (e.g. declared in appsettings.json) + Beg…
Browse files Browse the repository at this point in the history
…inScopeParser performance improvements (#263)

* Load NLog config from appsettings.json using NLogLoggingConfiguration

* Update NLog.Extensions.Logging.csproj

* refactor
  • Loading branch information
snakefoot authored and 304NotModified committed Apr 1, 2019
1 parent 2460b35 commit d7717f4
Show file tree
Hide file tree
Showing 15 changed files with 365 additions and 107 deletions.
1 change: 1 addition & 0 deletions NLog.Extensions.Logging.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
appveyor.yml = appveyor.yml
build.ps1 = build.ps1
CHANGELOG.MD = CHANGELOG.MD
README.md = README.md
EndProjectSection
EndProject
Expand Down
4 changes: 2 additions & 2 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# creates NuGet package at \artifacts
dotnet --version

$versionPrefix = "1.4.0"
$versionSuffix = ""
$versionPrefix = "1.5.0"
$versionSuffix = "rc1"
$versionFile = $versionPrefix + "." + ${env:APPVEYOR_BUILD_NUMBER}
$versionProduct = $versionPrefix;
if (-Not $versionSuffix.Equals(""))
Expand Down
1 change: 0 additions & 1 deletion examples/NetCore2/ConsoleExample/ConsoleExample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.0" />
<PackageReference Include="NLog.Schema" Version="4.5.11" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions examples/NetCore2/ConsoleExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ internal class Program
private static void Main()
{
var logger = LogManager.GetCurrentClassLogger();

try
{
var config = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();

LogManager.Configuration = new NLogLoggingConfiguration(config.GetSection("NLog"));

var servicesProvider = BuildDi(config);
using (servicesProvider as IDisposable)
{
Expand Down
38 changes: 38 additions & 0 deletions examples/NetCore2/ConsoleExample/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,43 @@
"ParseMessageTemplates": true,
"CaptureMessageProperties": true
}
},
"NLog": {
"autoreload": true,
"internalLogLevel": "Info",
"internalLogFile": "c:/temp/console-example-internal.log",
"throwConfigExceptions": true,
"targets": {
"console": {
"type": "Console",
"layout": "${date}|${level:uppercase=true}|${message} ${exception:format=tostring}|${logger}|${all-event-properties}"
},
"file": {
"type": "AsyncWrapper",
"target": {
"wrappedFile": {
"type": "File",
"fileName": "c:/temp/console-example.log",
"layout": {
"type": "JsonLayout",
"Attributes": [
{ "name": "timestamp", "layout": "${date:format=o}" },
{ "name": "level", "layout": "${level}" },
{ "name": "logger", "layout": "${logger}" },
{ "name": "message", "layout": "${message:raw=true}" },
{ "name": "properties", "encode": false, "layout": { "type": "JsonLayout", "includeallproperties": "true" } }
]
}
}
}
}
},
"rules": [
{
"logger": "*",
"minLevel": "Trace",
"writeTo": "File,Console"
}
]
}
}
112 changes: 112 additions & 0 deletions src/NLog.Extensions.Logging/Config/NLogLoggingConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Configuration;
using NLog.Config;

namespace NLog.Extensions.Logging
{
/// <summary>
/// Configures NLog through Microsoft Extension Configuration section (Ex from appsettings.json)
/// </summary>
public class NLogLoggingConfiguration : LoggingConfigurationParser
{
private readonly Action<object> _reloadConfiguration;

/// <summary>
/// Initializes a new instance of the <see cref="NLogLoggingConfiguration"/> class.
/// </summary>
/// <param name="nlogConfig">Configuration section to be read</param>
public NLogLoggingConfiguration(IConfigurationSection nlogConfig)
: this(nlogConfig, LogManager.LogFactory)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="NLogLoggingConfiguration"/> class.
/// </summary>
/// <param name="nlogConfig">Configuration section to be read</param>
/// <param name="logFactory">The <see cref="LogFactory"/> to which to apply any applicable configuration values.</param>
public NLogLoggingConfiguration(IConfigurationSection nlogConfig, LogFactory logFactory)
: base(logFactory)
{
_reloadConfiguration = (state) => LoadConfigurationSection((IConfigurationSection)state, true);
LoadConfigurationSection(nlogConfig, null);
}

private void LoadConfigurationSection(IConfigurationSection nlogConfig, bool? autoReload)
{
var configElement = new LoggingConfigurationElement(nlogConfig, true);
LoadConfig(configElement, null);
if (autoReload ?? configElement.AutoReload)
{
nlogConfig.GetReloadToken().RegisterChangeCallback(_reloadConfiguration, nlogConfig);
}
}

private class LoggingConfigurationElement : ILoggingConfigurationElement
{
readonly IConfigurationSection _configurationSection;
readonly string _nameOverride;

public bool AutoReload { get; }

public LoggingConfigurationElement(IConfigurationSection configurationSection, bool topElement, string nameOverride = null)
{
_configurationSection = configurationSection;
_nameOverride = nameOverride;
if (topElement && bool.TryParse(configurationSection["autoreload"], out var autoreload))
{
AutoReload = autoreload;
}
}

public string Name => _nameOverride ?? _configurationSection.Key;

public IEnumerable<KeyValuePair<string, string>> Values
{
get
{
var children = _configurationSection.GetChildren();
foreach (var child in children)
{
if (!child.GetChildren().Any())
yield return new KeyValuePair<string, string>(child.Key, child.Value);
}
if (_nameOverride != null)
yield return new KeyValuePair<string, string>("name", _configurationSection.Key);
}
}

public IEnumerable<ILoggingConfigurationElement> Children
{
get
{
var children = _configurationSection.GetChildren();
foreach (var child in children)
{
var firstChildValue = child?.GetChildren()?.FirstOrDefault();
if (firstChildValue == null)
{
continue;
}

if (_nameOverride == "target" && child.Key.EqualsOrdinalIgnoreCase("target") && child.GetChildren().Count() == 1)
{
yield return new LoggingConfigurationElement(firstChildValue, false, "target");
}
else
{
string nameOverride = null;
if (_configurationSection.Key.EqualsOrdinalIgnoreCase("targets"))
{
nameOverride = "target";
}
yield return new LoggingConfigurationElement(child, false, nameOverride);
}
}
}
}
}
}
}
13 changes: 13 additions & 0 deletions src/NLog.Extensions.Logging/Internal/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Linq;

namespace NLog.Extensions.Logging
{
internal static class StringExtensions
{
internal static bool EqualsOrdinalIgnoreCase(this string text, string text2)
{
return string.Equals(text, text2, StringComparison.OrdinalIgnoreCase);
}
}
}
Loading

0 comments on commit d7717f4

Please sign in to comment.