Skip to content

Commit 8f0e779

Browse files
Closes #43: Merge branch '#43-structured-logging' into main
2 parents b226422 + 8b802df commit 8f0e779

12 files changed

+318
-44
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
##
44
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
55

6+
docs/build/
7+
docs/source/_build
8+
69
# User-specific files
710
*.rsuser
811
*.suo

release-notes/wip-release-notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Date: ???
1111
* #34: Create Func obfuscator Can now obfuscate based on a user defined function.
1212
* #35: Create Func matcher. Can now specify a predicate function that matches the key of secrets.
1313
* #42: Logging all connection strings now does so in a single log message.
14+
* #43: All logging is now using structured renderers.
1415

1516
### Miscellaneous
1617

src/Stravaig.Extensions.Configuration.Diagnostics/ConfigurationDiagnosticsOptions.cs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ public class ConfigurationDiagnosticsOptions
1414
private ISecretObfuscator _obfuscator = PlainTextObfuscator.Instance;
1515
private IMatcher _configurationKeyMatcher = NullMatcher.Instance;
1616
private IMatcher _connectionStringElementMatcher = NullMatcher.Instance;
17+
private IConfigurationKeyRenderer _configurationKeyRenderer = StructuredConfigurationKeyRenderer.Instance;
18+
private IConfigurationProviderRenderer _configurationProviderRenderer = StructuredConfigurationProviderRenderer.Instance;
19+
private IConfigurationProviderNameRenderer _configurationProviderNameRenderer = StructuredConfigurationProviderNameRenderer.Instance;
1720
private IConnectionStringRenderer _connectionStringRenderer = StructuredConnectionStringRenderer.Instance;
1821
private IAllConnectionStringsRenderer _allConnectionStringRenderer = StructuredAllConnectionStringsRenderer.Instance;
19-
22+
2023
/// <summary>
2124
/// Global options used if no specific options are set.
2225
/// </summary>
@@ -53,9 +56,36 @@ public IMatcher ConnectionStringElementMatcher
5356
get => _connectionStringElementMatcher;
5457
set => _connectionStringElementMatcher = value ?? NullMatcher.Instance;
5558
}
59+
60+
/// <summary>
61+
/// The renderer that creates the log message for all configuration values in a configuration.
62+
/// </summary>
63+
public IConfigurationKeyRenderer ConfigurationKeyRenderer
64+
{
65+
get => _configurationKeyRenderer;
66+
set => _configurationKeyRenderer = value ?? StructuredConfigurationKeyRenderer.Instance;
67+
}
68+
69+
/// <summary>
70+
/// The renderer that creates the log message for the providers of a configuration.
71+
/// </summary>
72+
public IConfigurationProviderRenderer ConfigurationProviderRenderer
73+
{
74+
get => _configurationProviderRenderer;
75+
set => _configurationProviderRenderer = value ?? StructuredConfigurationProviderRenderer.Instance;
76+
}
77+
78+
/// <summary>
79+
/// The renderer that creates the log message for the names of the providers of a configuration.
80+
/// </summary>
81+
public IConfigurationProviderNameRenderer ConfigurationProviderNameRenderer
82+
{
83+
get => _configurationProviderNameRenderer;
84+
set => _configurationProviderNameRenderer = value ?? StructuredConfigurationProviderNameRenderer.Instance;
85+
}
5686

5787
/// <summary>
58-
/// The renderer that creates the log message for a deconstructed connection string
88+
/// The renderer that creates the log message for a deconstructed connection string.
5989
/// </summary>
6090
public IConnectionStringRenderer ConnectionStringRenderer
6191
{
@@ -64,7 +94,7 @@ public IConnectionStringRenderer ConnectionStringRenderer
6494
}
6595

6696
/// <summary>
67-
/// The renderer that creates the log message for all deconstructed connection strings in a configuration
97+
/// The renderer that creates the log message for all deconstructed connection strings in a configuration.
6898
/// </summary>
6999
public IAllConnectionStringsRenderer AllConnectionStringsRenderer
70100
{
@@ -101,4 +131,4 @@ public ConfigurationDiagnosticsOptions BuildConnectionStringElementMatcher(Actio
101131
return this;
102132
}
103133
}
104-
}
134+
}

src/Stravaig.Extensions.Configuration.Diagnostics/ConfigurationRootProviderNameExtensions.cs

Lines changed: 105 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using System;
2-
using System.Linq;
31
using Microsoft.Extensions.Configuration;
42
using Microsoft.Extensions.Logging;
53

@@ -21,6 +19,18 @@ public static void LogProviderNamesAsInformation(this ILogger logger, IConfigura
2119
logger.LogProviderNames(config, LogLevel.Information);
2220
}
2321

22+
/// <summary>
23+
/// Logs the provider names in the given <see cref="T:Microsoft.Extensions.Configuration.IConfigurationRoot"/>
24+
/// at the Information log level.
25+
/// </summary>
26+
/// <param name="config">The configuration root to examine.</param>
27+
/// <param name="logger">The logger to write the results to.</param>
28+
/// <param name="options">The options to use for rendering the provider names.</param>
29+
public static void LogProviderNamesAsInformation(this ILogger logger, IConfigurationRoot config, ConfigurationDiagnosticsOptions options)
30+
{
31+
logger.LogProviderNames(config, LogLevel.Information, options);
32+
}
33+
2434
/// <summary>
2535
/// Logs the provider names in the given <see cref="T:Microsoft.Extensions.Configuration.IConfigurationRoot"/>
2636
/// at the Debug log level.
@@ -32,6 +42,18 @@ public static void LogProviderNamesAsDebug(this ILogger logger, IConfigurationRo
3242
logger.LogProviderNames(config, LogLevel.Debug);
3343
}
3444

45+
/// <summary>
46+
/// Logs the provider names in the given <see cref="T:Microsoft.Extensions.Configuration.IConfigurationRoot"/>
47+
/// at the Debug log level.
48+
/// </summary>
49+
/// <param name="config">The configuration root to examine.</param>
50+
/// <param name="logger">The logger to write the results to.</param>
51+
/// <param name="options">The options to use for rendering the provider names.</param>
52+
public static void LogProviderNamesAsDebug(this ILogger logger, IConfigurationRoot config, ConfigurationDiagnosticsOptions options)
53+
{
54+
logger.LogProviderNames(config, LogLevel.Debug, options);
55+
}
56+
3557
/// <summary>
3658
/// Logs the provider names in the given <see cref="T:Microsoft.Extensions.Configuration.IConfigurationRoot"/>
3759
/// at the Trace log level.
@@ -43,6 +65,18 @@ public static void LogProviderNamesAsTrace(this ILogger logger, IConfigurationRo
4365
logger.LogProviderNames(config, LogLevel.Trace);
4466
}
4567

68+
/// <summary>
69+
/// Logs the provider names in the given <see cref="T:Microsoft.Extensions.Configuration.IConfigurationRoot"/>
70+
/// at the Trace log level.
71+
/// </summary>
72+
/// <param name="config">The configuration root to examine.</param>
73+
/// <param name="logger">The logger to write the results to.</param>
74+
/// <param name="options">The options to use for rendering the provider names.</param>
75+
public static void LogProviderNamesAsTrace(this ILogger logger, IConfigurationRoot config, ConfigurationDiagnosticsOptions options)
76+
{
77+
logger.LogProviderNames(config, LogLevel.Trace, options);
78+
}
79+
4680
/// <summary>
4781
/// Logs the provider names in the given <see cref="T:Microsoft.Extensions.Configuration.IConfigurationRoot"/>
4882
/// </summary>
@@ -51,12 +85,24 @@ public static void LogProviderNamesAsTrace(this ILogger logger, IConfigurationRo
5185
/// <param name="level">The log level to use.</param>
5286
public static void LogProviderNames(this ILogger logger, IConfigurationRoot config, LogLevel level)
5387
{
54-
var providerNames = config.Providers
55-
.Select(p => p.GetType().FullName);
56-
string message = "The following configuration providers were registered:" +
57-
Environment.NewLine +
58-
string.Join(Environment.NewLine, providerNames);
59-
logger.Log(level, message);
88+
logger.LogProviderNames(config, level, ConfigurationDiagnosticsOptions.GlobalOptions);
89+
}
90+
91+
/// <summary>
92+
/// Logs the provider names in the given <see cref="T:Microsoft.Extensions.Configuration.IConfigurationRoot"/>
93+
/// </summary>
94+
/// <param name="config">The configuration root to examine.</param>
95+
/// <param name="logger">The logger to write the results to.</param>
96+
/// <param name="level">The log level to use.</param>
97+
/// <param name="options">The options to use for rendering the provider names.</param>
98+
public static void LogProviderNames(
99+
this ILogger logger,
100+
IConfigurationRoot config,
101+
LogLevel level,
102+
ConfigurationDiagnosticsOptions options)
103+
{
104+
var message = options.ConfigurationProviderNameRenderer.Render(config);
105+
logger.Log(message.GetLogLevel(level), message.Exception, message.MessageTemplate, message.Properties);
60106
}
61107

62108
/// <summary>
@@ -68,6 +114,17 @@ public static void LogProvidersAsInformation(this ILogger logger, IConfiguration
68114
{
69115
logger.LogProviders(config, LogLevel.Information);
70116
}
117+
118+
/// <summary>
119+
/// Logs a list of the providers the configuration is using at the Information level.
120+
/// </summary>
121+
/// <param name="logger">The logger to write the details to.</param>
122+
/// <param name="config">The configuration root.</param>
123+
/// <param name="options">The options to use for rendering the providers.</param>
124+
public static void LogProvidersAsInformation(this ILogger logger, IConfigurationRoot config, ConfigurationDiagnosticsOptions options)
125+
{
126+
logger.LogProviders(config, LogLevel.Information, options);
127+
}
71128

72129
/// <summary>
73130
/// Logs a list of the providers the configuration is using at the Debug level.
@@ -79,6 +136,17 @@ public static void LogProvidersAsDebug(this ILogger logger, IConfigurationRoot c
79136
logger.LogProviders(config, LogLevel.Debug);
80137
}
81138

139+
/// <summary>
140+
/// Logs a list of the providers the configuration is using at the Debug level.
141+
/// </summary>
142+
/// <param name="logger">The logger to write the details to.</param>
143+
/// <param name="config">The configuration root.</param>
144+
/// <param name="options">The options to use for rendering the providers.</param>
145+
public static void LogProvidersAsDebug(this ILogger logger, IConfigurationRoot config, ConfigurationDiagnosticsOptions options)
146+
{
147+
logger.LogProviders(config, LogLevel.Debug, options);
148+
}
149+
82150
/// <summary>
83151
/// Logs a list of the providers the configuration is using at the Trace level.
84152
/// </summary>
@@ -89,6 +157,17 @@ public static void LogProvidersAsTrace(this ILogger logger, IConfigurationRoot c
89157
logger.LogProviders(config, LogLevel.Trace);
90158
}
91159

160+
/// <summary>
161+
/// Logs a list of the providers the configuration is using at the Trace level.
162+
/// </summary>
163+
/// <param name="logger">The logger to write the details to.</param>
164+
/// <param name="config">The configuration root.</param>
165+
/// <param name="options">The options to use for rendering the providers.</param>
166+
public static void LogProvidersAsTrace(this ILogger logger, IConfigurationRoot config, ConfigurationDiagnosticsOptions options)
167+
{
168+
logger.LogProviders(config, LogLevel.Trace, options);
169+
}
170+
92171
/// <summary>
93172
/// Logs a list of the providers the configuration is using.
94173
/// </summary>
@@ -97,12 +176,24 @@ public static void LogProvidersAsTrace(this ILogger logger, IConfigurationRoot c
97176
/// <param name="level">The level to log at.</param>
98177
public static void LogProviders(this ILogger logger, IConfigurationRoot config, LogLevel level)
99178
{
100-
var providers = config.Providers
101-
.Select(p => p.ToString());
102-
string message = "The following configuration providers were registered:" +
103-
Environment.NewLine +
104-
string.Join(Environment.NewLine, providers);
105-
logger.Log(level, message);
179+
logger.LogProviders(config, level, ConfigurationDiagnosticsOptions.GlobalOptions);
180+
}
181+
182+
/// <summary>
183+
/// Logs a list of the providers the configuration is using.
184+
/// </summary>
185+
/// <param name="logger">The logger to write the details to.</param>
186+
/// <param name="config">The configuration root.</param>
187+
/// <param name="level">The level to log at.</param>
188+
/// <param name="options">The options to use for rendering the providers.</param>
189+
public static void LogProviders(
190+
this ILogger logger,
191+
IConfigurationRoot config,
192+
LogLevel level,
193+
ConfigurationDiagnosticsOptions options)
194+
{
195+
var message = options.ConfigurationProviderRenderer.Render(config);
196+
logger.Log(message.GetLogLevel(level), message.Exception, message.MessageTemplate, message.Properties);
106197
}
107198
}
108199
}

src/Stravaig.Extensions.Configuration.Diagnostics/ILoggerIConfigurationExtensions.cs

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
41
using Microsoft.Extensions.Configuration;
52
using Microsoft.Extensions.Logging;
63

@@ -95,28 +92,8 @@ public static void LogConfigurationValues(this ILogger logger, IConfiguration co
9592
/// <param name="options">The options to use to obfuscate secrets.</param>
9693
public static void LogConfigurationValues(this ILogger logger, IConfiguration config, LogLevel level, ConfigurationDiagnosticsOptions options)
9794
{
98-
99-
var valueMap = config.AsEnumerable()
100-
.OrderBy(kvp => kvp.Key)
101-
.Select(kvp => Obfuscate(kvp, options))
102-
.Select(Render);
103-
string message = "The following values are available:" +
104-
Environment.NewLine +
105-
string.Join(Environment.NewLine, valueMap);
106-
107-
logger.Log(level, message);
108-
}
109-
110-
private static string Render(KeyValuePair<string, string> kvp)
111-
{
112-
return $"{kvp.Key} : {kvp.Value}";
113-
}
114-
115-
private static KeyValuePair<string, string> Obfuscate(KeyValuePair<string, string> kvp, ConfigurationDiagnosticsOptions options)
116-
{
117-
return options.ConfigurationKeyMatcher.IsMatch(kvp.Key)
118-
? new KeyValuePair<string, string>(kvp.Key, options.Obfuscator.Obfuscate(kvp.Value))
119-
: kvp;
95+
var message = options.ConfigurationKeyRenderer.Render(config, options);
96+
logger.Log(message.GetLogLevel(level), message.Exception, message.MessageTemplate, message.Properties);
12097
}
12198
}
12299
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Microsoft.Extensions.Configuration;
2+
3+
namespace Stravaig.Extensions.Configuration.Diagnostics.Renderers
4+
{
5+
/// <summary>
6+
/// A renderer that renders the log message for all configuration values in a configuration.
7+
/// </summary>
8+
public interface IConfigurationKeyRenderer
9+
{
10+
/// <summary>
11+
/// Renders the configuration values in the provided configuration.
12+
/// </summary>
13+
/// <param name="configuration">The application configuration.</param>
14+
/// <param name="options">The options to use to determine how secrets are rendered.</param>
15+
/// <returns>A message entry.</returns>
16+
MessageEntry Render(IConfiguration configuration, ConfigurationDiagnosticsOptions options);
17+
}
18+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Microsoft.Extensions.Configuration;
2+
3+
namespace Stravaig.Extensions.Configuration.Diagnostics.Renderers
4+
{
5+
/// <summary>
6+
/// The renderer that renders the log messages for the names of the providers of a configuration.
7+
/// </summary>
8+
public interface IConfigurationProviderNameRenderer
9+
{
10+
/// <summary>
11+
/// Renders the names of the configuration providers of the provided configuration.
12+
/// </summary>
13+
/// <param name="configuration">The application configuration.</param>
14+
/// <returns>A message entry.</returns>
15+
MessageEntry Render(IConfigurationRoot configuration);
16+
}
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Microsoft.Extensions.Configuration;
2+
3+
namespace Stravaig.Extensions.Configuration.Diagnostics.Renderers
4+
{
5+
/// <summary>
6+
/// The renderer that renders the log messages for the providers of a configuration.
7+
/// </summary>
8+
public interface IConfigurationProviderRenderer
9+
{
10+
/// <summary>
11+
/// Renders the configuration providers of the provided configuration.
12+
/// </summary>
13+
/// <param name="configuration">The application configuration.</param>
14+
/// <returns>A message entry.</returns>
15+
MessageEntry Render(IConfigurationRoot configuration);
16+
}
17+
}

0 commit comments

Comments
 (0)