adding nlog, strongly typed config in DI

This commit is contained in:
andy 2021-10-11 18:17:36 +01:00
parent ab8687b41e
commit e7fbb23376
11 changed files with 117 additions and 54 deletions

10
Selector.CLI/Options.cs Normal file
View File

@ -0,0 +1,10 @@

namespace Selector.CLI
{
class RootOptions
{
public const string Key = "Selector";
public int Number { get; set; } = 2;
}
}

View File

@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using NLog.Extensions.Logging;
namespace Selector.CLI namespace Selector.CLI
{ {
@ -18,17 +19,24 @@ namespace Selector.CLI
static IHostBuilder CreateHostBuilder(string[] args) static IHostBuilder CreateHostBuilder(string[] args)
=> Host.CreateDefaultBuilder(args) => Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) => { .ConfigureServices((context, services) => {
// CONFIG
services.Configure<RootOptions>(options =>
context.Configuration.GetSection(RootOptions.Key).Bind(options)
);
// SERVICES
services.AddTransient<IPlayerWatcher, PlayerWatcher>(); services.AddTransient<IPlayerWatcher, PlayerWatcher>();
services.AddTransient<IWatcherCollection, WatcherCollection>(); services.AddTransient<IWatcherCollection, WatcherCollection>();
services.AddTransient<IEqual, UriEqual>();
// HOSTED SERVICES
services.AddHostedService<WatcherService>(); services.AddHostedService<WatcherService>();
}) })
.ConfigureLogging(builder => { .ConfigureLogging((context, builder) => {
builder builder.ClearProviders();
.AddSimpleConsole(options => { builder.SetMinimumLevel(LogLevel.Trace);
options.IncludeScopes = true; builder.AddNLog(context.Configuration);
options.SingleLine = true;
options.TimestampFormat = "yyyy-mm-dd hh:mm:ss ";
});
}); });
} }
} }

View File

@ -12,6 +12,8 @@
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<PackageReference Include="NLog" Version="4.7.11" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.4" />
<PackageReference Include="SpotifyAPI.Web" Version="6.2.2" /> <PackageReference Include="SpotifyAPI.Web" Version="6.2.2" />
</ItemGroup> </ItemGroup>
@ -23,6 +25,9 @@
<None Update="appsettings.json"> <None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Selector.CLI
{
class SelectorOptions
{
public const string Options = "Selector";
public int Number { get; set; }
}
}

View File

@ -7,35 +7,25 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Selector.CLI namespace Selector.CLI
{ {
class WatcherService : IHostedService class WatcherService : IHostedService
{ {
private readonly ILogger<WatcherService> Logger; private readonly ILogger<WatcherService> Logger;
private readonly IConfiguration Config; private readonly RootOptions Config;
public WatcherService(ILogger<WatcherService> logger, IConfiguration config) public WatcherService(ILogger<WatcherService> logger, IOptions<RootOptions> config)
{ {
Logger = logger; Logger = logger;
Config = config; Config = config.Value;
} }
public Task StartAsync(CancellationToken cancellationToken) public Task StartAsync(CancellationToken cancellationToken)
{ {
Logger.LogInformation("Starting up"); Logger.LogInformation("Starting up");
foreach ((var key, var pair) in Config.AsEnumerable())
//foreach ((var key, var pair) in Config.GetSection("Selector").AsEnumerable())
{
Logger.LogInformation($"{key} => {pair}");
}
using(Logger.BeginScope("A New Scope!"))
{
Logger.LogError("From the scope!");
}
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@ -1,20 +1,11 @@
{ {
"string config": "asdf", //"Selector": {
"Selector": { // "Number2": 4,
"Number": 4 // "Number": 4
}, //},
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information"
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"Console": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
//"Microsoft.Hosting.Lifetime": "Information"
}
} }
} }
} }

28
Selector.CLI/nlog.config Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogFile=".\selector.nlog.log"
internalLogLevel="Info" >
<variable name="format"
value="${longdate}|${level:uppercase=true}|${callsite}:${callsite-linenumber}|${message}${onexception:inner=${newline}}${exception:format=tostring,data:exceptionDataSeparator=\r\n}"/>
<!-- the targets to write to -->
<targets>
<!-- write logs to file -->
<target xsi:type="File"
name="logfile"
fileName=".\selector.log"
layout="${format}" />
<target xsi:type="Console"
name="logconsole"
layout="${format}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<logger name="Selector.*" minlevel="Trace" writeTo="logfile,logconsole" />
</rules>
</nlog>

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using SpotifyAPI.Web;
namespace Selector.Helpers
{
public static class SpotifyExtensions
{
public static string ToString(this FullTrack track) => $"{track.Name} - {track.Album.Name} - {track.Artists}";
public static string ToString(this SimpleAlbum album) => $"{album.Name} - {album.Artists}";
public static string ToString(this SimpleArtist artist) => $"{artist.Name}";
public static string ToString(this FullEpisode ep) => $"{ep.Name} - {ep.Show}";
public static string ToString(this SimpleShow show) => $"{show.Name} - {show.Publisher}";
public static string ToString(this CurrentlyPlayingContext context) => $"{context.IsPlaying}, {context.Item}, {context.Device}";
public static string ToString(this Device device) => $"{device.Id}: {device.Name} {device.VolumePercent}%";
public static string ToString(this IEnumerable<SimpleArtist> artists) => string.Join("/", artists.Select(a => a.Name));
}
}

View File

@ -7,6 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="SpotifyAPI.Web" Version="6.2.2" /> <PackageReference Include="SpotifyAPI.Web" Version="6.2.2" />
</ItemGroup> </ItemGroup>

View File

@ -4,10 +4,14 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using SpotifyAPI.Web; using SpotifyAPI.Web;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Selector namespace Selector
{ {
public class PlayerWatcher: BaseWatcher, IPlayerWatcher public class PlayerWatcher: BaseWatcher, IPlayerWatcher
{ {
private readonly ILogger<PlayerWatcher> Logger;
private readonly IPlayerClient spotifyClient; private readonly IPlayerClient spotifyClient;
private readonly IEqual eq; private readonly IEqual eq;
@ -26,10 +30,12 @@ namespace Selector
public PlayerWatcher(IPlayerClient spotifyClient, public PlayerWatcher(IPlayerClient spotifyClient,
IEqual equalityChecker, IEqual equalityChecker,
ILogger<PlayerWatcher> logger = null,
int pollPeriod = 3000) { int pollPeriod = 3000) {
this.spotifyClient = spotifyClient; this.spotifyClient = spotifyClient;
eq = equalityChecker; eq = equalityChecker;
Logger = logger ?? NullLogger<PlayerWatcher>.Instance;
PollPeriod = pollPeriod; PollPeriod = pollPeriod;
} }
@ -64,12 +70,14 @@ namespace Selector
if(previous is null if(previous is null
&& (Live.Item is FullTrack || Live.Item is FullEpisode)) && (Live.Item is FullTrack || Live.Item is FullEpisode))
{ {
Logger.LogDebug($"Playback started: {Live}");
OnPlayingChange(ListeningChangeEventArgs.From(previous, Live)); OnPlayingChange(ListeningChangeEventArgs.From(previous, Live));
} }
// STOPPED PLAYBACK // STOPPED PLAYBACK
else if((previous.Item is FullTrack || previous.Item is FullEpisode) else if((previous.Item is FullTrack || previous.Item is FullEpisode)
&& Live is null) && Live is null)
{ {
Logger.LogDebug($"Playback stopped: {previous}");
OnPlayingChange(ListeningChangeEventArgs.From(previous, Live)); OnPlayingChange(ListeningChangeEventArgs.From(previous, Live));
} }
// CONTINUING PLAYBACK // CONTINUING PLAYBACK
@ -79,16 +87,18 @@ namespace Selector
if(previous.Item is FullTrack previousTrack if(previous.Item is FullTrack previousTrack
&& Live.Item is FullTrack currentTrack) && Live.Item is FullTrack currentTrack)
{ {
if(!eq.IsEqual(previousTrack, currentTrack)) { if(!eq.IsEqual(previousTrack, currentTrack)) {
Logger.LogDebug($"Track changed: {previousTrack} -> {currentTrack}");
OnItemChange(ListeningChangeEventArgs.From(previous, Live)); OnItemChange(ListeningChangeEventArgs.From(previous, Live));
} }
if(!eq.IsEqual(previousTrack.Album, currentTrack.Album)) { if(!eq.IsEqual(previousTrack.Album, currentTrack.Album)) {
Logger.LogDebug($"Album changed: {previousTrack.Album} -> {currentTrack.Album}");
OnAlbumChange(ListeningChangeEventArgs.From(previous, Live)); OnAlbumChange(ListeningChangeEventArgs.From(previous, Live));
} }
if(!eq.IsEqual(previousTrack.Artists[0], currentTrack.Artists[0])) { if(!eq.IsEqual(previousTrack.Artists[0], currentTrack.Artists[0])) {
Logger.LogDebug($"Artist changed: {previousTrack.Artists[0]} -> {currentTrack.Artists[0]}");
OnArtistChange(ListeningChangeEventArgs.From(previous, Live)); OnArtistChange(ListeningChangeEventArgs.From(previous, Live));
} }
} }
@ -96,6 +106,7 @@ namespace Selector
else if((previous.Item is FullTrack && Live.Item is FullEpisode) else if((previous.Item is FullTrack && Live.Item is FullEpisode)
|| (previous.Item is FullEpisode && Live.Item is FullTrack)) || (previous.Item is FullEpisode && Live.Item is FullTrack))
{ {
Logger.LogDebug($"Media type changed: {previous.Item}, {previous.Item}");
OnContentChange(ListeningChangeEventArgs.From(previous, Live)); OnContentChange(ListeningChangeEventArgs.From(previous, Live));
OnItemChange(ListeningChangeEventArgs.From(previous, Live)); OnItemChange(ListeningChangeEventArgs.From(previous, Live));
} }
@ -104,6 +115,7 @@ namespace Selector
&& Live.Item is FullEpisode currentEp) && Live.Item is FullEpisode currentEp)
{ {
if(!eq.IsEqual(previousEp, currentEp)) { if(!eq.IsEqual(previousEp, currentEp)) {
Logger.LogDebug($"Podcast changed: {previousEp} -> {currentEp}");
OnItemChange(ListeningChangeEventArgs.From(previous, Live)); OnItemChange(ListeningChangeEventArgs.From(previous, Live));
} }
} }
@ -113,21 +125,25 @@ namespace Selector
// CONTEXT // CONTEXT
if(!eq.IsEqual(previous.Context, Live.Context)) { if(!eq.IsEqual(previous.Context, Live.Context)) {
Logger.LogDebug($"Context changed: {previous.Context} -> {Live.Context}");
OnContextChange(ListeningChangeEventArgs.From(previous, Live)); OnContextChange(ListeningChangeEventArgs.From(previous, Live));
} }
// DEVICE // DEVICE
if(!eq.IsEqual(previous?.Device, Live?.Device)) { if(!eq.IsEqual(previous?.Device, Live?.Device)) {
Logger.LogDebug($"Device changed: {previous?.Device} -> {Live?.Device}");
OnDeviceChange(ListeningChangeEventArgs.From(previous, Live)); OnDeviceChange(ListeningChangeEventArgs.From(previous, Live));
} }
// IS PLAYING // IS PLAYING
if(previous.IsPlaying != Live.IsPlaying) { if(previous.IsPlaying != Live.IsPlaying) {
Logger.LogDebug($"Playing state changed: {previous.IsPlaying} -> {Live.IsPlaying}");
OnPlayingChange(ListeningChangeEventArgs.From(previous, Live)); OnPlayingChange(ListeningChangeEventArgs.From(previous, Live));
} }
// VOLUME // VOLUME
if(previous.Device.VolumePercent != Live.Device.VolumePercent) { if(previous.Device.VolumePercent != Live.Device.VolumePercent) {
Logger.LogDebug($"Volume changed: {previous.Device.VolumePercent}% -> {Live.Device.VolumePercent}%");
OnVolumeChange(ListeningChangeEventArgs.From(previous, Live)); OnVolumeChange(ListeningChangeEventArgs.From(previous, Live));
} }
} }

View File

@ -1,3 +1,5 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
@ -10,12 +12,13 @@ namespace Selector
{ {
public class WatcherCollection: IWatcherCollection, IDisposable, IEnumerable<WatcherContext> public class WatcherCollection: IWatcherCollection, IDisposable, IEnumerable<WatcherContext>
{ {
private readonly ILogger<WatcherCollection> Logger;
public bool IsRunning { get; private set; } = true; public bool IsRunning { get; private set; } = true;
private List<WatcherContext> Watchers { get; set; } = new(); private List<WatcherContext> Watchers { get; set; } = new();
public WatcherCollection() public WatcherCollection(ILogger<WatcherCollection> logger = null)
{ {
Logger = logger ?? NullLogger<WatcherCollection>.Instance;
} }
public int Count => Watchers.Count; public int Count => Watchers.Count;
@ -42,6 +45,7 @@ namespace Selector
public void Start() public void Start()
{ {
Logger.LogDebug($"Starting {Count} watchers");
foreach(var watcher in Watchers) foreach(var watcher in Watchers)
{ {
watcher.Start(); watcher.Start();
@ -51,7 +55,8 @@ namespace Selector
public void Stop() public void Stop()
{ {
foreach(var watcher in Watchers) Logger.LogDebug($"Stopping {Count} watchers");
foreach (var watcher in Watchers)
{ {
watcher.Stop(); watcher.Stop();
} }