Skip to content

Commit 9c20851

Browse files
Merge pull request #17 from Stravaig-Projects/#11/logging
#11: Add logging
2 parents 3f721fd + ff220fe commit 9c20851

19 files changed

+275
-35
lines changed

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,40 @@ builder.AddSqlServer(opts =>
5454
});
5555
```
5656

57+
### Adding logging
5758

59+
The configuration provider is set up too early in the pipeline to be able to accept logging from the start. However you can attach a logger after it has been set up. The configuration provider will also hold on to any log messages and replay them once a logger it attached. It works like this:
60+
61+
* When calling `AddSqlServer` on the configuration builder. Make sure you call `ExpectLogger()`. This sets up the replay mechanism.
62+
* Then set up your loggers. The SqlServerConfigurationProvider logs from Debug up.
63+
* By the time you get to configure services, you should be able to get a `ILoggerFactory`. There is an extension method, `AttachLoggerToSqlServerProvider` on `IConfigurationRoot` that will attach the logger.
64+
65+
```csharp
66+
await Host.CreateDefaultBuilder(args)
67+
.ConfigureAppConfiguration(builder =>
68+
{
69+
builder.AddSqlServer(opts =>
70+
{
71+
opts.FromExistingConfiguration()
72+
.ExpectLogger();
73+
});
74+
})
75+
.ConfigureLogging(builder =>
76+
{
77+
builder.AddConsole();
78+
builder.AddDebug();
79+
builder.SetMinimumLevel(LogLevel.Debug);
80+
})
81+
.ConfigureServices((ctx, services) =>
82+
{
83+
// Attach the logger to the SQL Server Configuration Provider
84+
IConfigurationRoot configRoot = (IConfigurationRoot) ctx.Configuration;
85+
configRoot.AttachLoggerToSqlServerProvider(services.BuildServiceProvider().GetService<ILoggerFactory>());
86+
})
87+
88+
```
89+
90+
CAUTION: If you call `ExpectLogger` and never attach a logger, it will just hold on to the log messages for the lifetime of the application in memory.
5891

5992
## Contributing / Getting Started
6093

release-notes/wip-release-notes.md

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,9 @@
44

55
Date: ???
66

7-
### Bugs
8-
97
### Features
108

11-
### Miscellaneous
12-
13-
### Dependent Packages
14-
15-
- .NET 5.0
16-
- No changes
17-
- .NET Core 3.1
18-
- No changes
19-
- General
20-
- No changes
9+
- #11: Add logging
2110

2211
---
2312

src/Example/Program.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,20 @@ await Host.CreateDefaultBuilder(args)
1212
builder.AddUserSecrets<Program>();
1313
builder.AddSqlServer(opts =>
1414
{
15-
opts.FromExistingConfiguration();
15+
opts.FromExistingConfiguration()
16+
.ExpectLogger();
1617
});
1718
})
1819
.ConfigureLogging(builder =>
1920
{
2021
builder.AddConsole();
2122
builder.AddDebug();
23+
builder.SetMinimumLevel(LogLevel.Debug);
2224
})
2325
.ConfigureServices((ctx, services) =>
2426
{
2527
IConfigurationRoot configRoot = (IConfigurationRoot) ctx.Configuration;
28+
configRoot.AttachLoggerToSqlServerProvider(services.BuildServiceProvider().GetService<ILoggerFactory>());
2629
services.AddTransient<IHostedService, TheHostedService>();
2730
services.AddSingleton(configRoot);
2831
services.Configure<MyFeatureConfiguration>(configRoot.GetSection("MyConfiguration"));

src/Example/TheHostedService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public TheHostedService(
3636
_timer.Elapsed += TimerOnElapsed;
3737
featureValues.OnChange((_, s) =>
3838
{
39-
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Change Detected. {s}");
39+
_logger.LogInformation($"Change Detected. {s}", s);
4040
});
4141
}
4242

@@ -47,7 +47,7 @@ private async void TimerOnElapsed(object? sender, ElapsedEventArgs e)
4747
WriteIndented = true,
4848
};
4949
string json = JsonSerializer.Serialize(_featureValues.CurrentValue, jsonOptions);
50-
Console.Clear();
50+
Console.WriteLine(Environment.NewLine);
5151
_logger.LogInformation(
5252
"At {Time} the object looks like:\n{Json}",
5353
e.SignalTime,
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34

45
namespace Stravaig.Configuration.SqlServer.Tests;
56

67
public class FakeDataLoader : IDataLoader
78
{
89
public KeyValuePair<string, string>[] FakeData { get; set; } = Array.Empty<KeyValuePair<string, string>>();
9-
public IEnumerable<KeyValuePair<string, string>> RetrieveData(SqlServerConfigurationSource source)
10+
11+
public IDictionary<string, string> RetrieveData(SqlServerConfigurationSource source)
1012
{
11-
return FakeData;
13+
return FakeData.ToDictionary(k => k.Key, v => v.Value);
1214
}
1315
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
1+
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2+
<s:Boolean x:Key="/Default/UserDictionary/Words/=Materialise/@EntryIndexedValue">True</s:Boolean>
23
<s:Boolean x:Key="/Default/UserDictionary/Words/=Nulling/@EntryIndexedValue">True</s:Boolean>
34
<s:Boolean x:Key="/Default/UserDictionary/Words/=Stravaig/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Linq;
2+
using Microsoft.Extensions.Configuration;
3+
using Microsoft.Extensions.Logging;
4+
using Microsoft.Extensions.Logging.Abstractions;
5+
6+
namespace Stravaig.Configuration.SqlServer;
7+
8+
public static class ConfigurationRootExtensions
9+
{
10+
public static IConfigurationRoot AttachLoggerToSqlServerProvider(this IConfigurationRoot configRoot, ILoggerFactory? loggerFactory)
11+
{
12+
loggerFactory ??= NullLoggerFactory.Instance;
13+
14+
var providers = configRoot.Providers
15+
.OfType<SqlServerConfigurationProvider>();
16+
foreach (var provider in providers)
17+
{
18+
provider.AttachLogger(loggerFactory);
19+
}
20+
21+
return configRoot;
22+
}
23+
}

src/Stravaig.Configuration.SqlServer/DataLoader.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,33 @@
33

44
namespace Stravaig.Configuration.SqlServer;
55

6-
public interface IDataLoader
7-
{
8-
IEnumerable<KeyValuePair<string, string>> RetrieveData(SqlServerConfigurationSource source);
9-
}
106
public class DataLoader : IDataLoader
117
{
128
private const string RetrieveSqlTemplate = "SELECT [ConfigKey], [ConfigValue] FROM [{0}].[{1}]";
139
private const int KeyColumnPosition = 0;
1410
private const int ValueColumnPosition = 1;
1511

16-
public IEnumerable<KeyValuePair<string, string>> RetrieveData(SqlServerConfigurationSource source)
12+
public IDictionary<string, string> RetrieveData(SqlServerConfigurationSource source)
1713
{
1814
var sql = RetrieveSql(source.SchemaName, source.TableName);
1915
using SqlConnection connection = new SqlConnection(source.ConnectionString);
2016
connection.Open();
2117
var cmd = new SqlCommand(sql, connection);
2218
using var reader = cmd.ExecuteReader();
19+
return MaterialiseData(reader);
20+
}
21+
22+
private static IDictionary<string, string> MaterialiseData(SqlDataReader reader)
23+
{
24+
Dictionary<string, string> results = new ();
2325
while (reader.Read())
2426
{
2527
var key = reader.GetString(KeyColumnPosition);
2628
var value = reader.GetString(ValueColumnPosition);
27-
yield return new KeyValuePair<string, string>(key, value);
29+
results.Add(key,value);
2830
}
31+
32+
return results;
2933
}
3034

3135
private string RetrieveSql(string schemaName, string tableName) =>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System.Collections.Generic;
2+
3+
namespace Stravaig.Configuration.SqlServer;
4+
5+
public interface IDataLoader
6+
{
7+
IDictionary<string, string> RetrieveData(SqlServerConfigurationSource source);
8+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
using Microsoft.Extensions.Logging;
2+
13
namespace Stravaig.Configuration.SqlServer;
24

35
public interface ISqlServerConfigurationWatcher
46
{
57
void EnsureStarted();
8+
void AttachLogger(ILogger logger);
69
}

0 commit comments

Comments
 (0)