Skip to content

Commit

Permalink
refactor: host builder pipeline logging
Browse files Browse the repository at this point in the history
This change moves implementations to multiple, more sensible components. It also configures SeriLog correctly in the host builder pipeline.
  • Loading branch information
BeeHiveJava committed Jul 4, 2020
1 parent 258c161 commit a89009a
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 98 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Microsoft.Extensions.Hosting;
using NetDaemon.Service.Support;
using Serilog;

namespace NetDaemon.Service.Extensions
{
public static class HostBuilderExtensions
{
// We preserve the static logger so that we can access it statically and early on in the application lifecycle.
private const bool PreserveStaticLogger = true;

public static IHostBuilder UseNetDaemon(this IHostBuilder builder)
{
return builder
.UseNetDaemonSerilog()
.ConfigureServices(services =>
{
services.AddNetDaemon();
});
}

private static IHostBuilder UseNetDaemonSerilog(this IHostBuilder builder)
{
return builder.UseSerilog(
(context, configuration) => SeriLogConfigurator.Configure(configuration),
PreserveStaticLogger
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Microsoft.Extensions.DependencyInjection;

namespace NetDaemon.Service.Extensions
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddNetDaemon(this IServiceCollection services)
{
services.AddHttpClient();
services.AddHostedService<RunnerService>();

return services;
}
}
}
79 changes: 79 additions & 0 deletions src/DaemonRunner/DaemonRunner/Service/Runner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using NetDaemon.Service.Extensions;
using NetDaemon.Service.Support;
using Serilog;

namespace NetDaemon.Service
{
public static class Runner
{
private const string _hassioConfigPath = "/data/options.json";

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseNetDaemon();

public static async Task Run(string[] args)
{
try
{
Log.Logger = SeriLogConfigurator.GetConfiguration().CreateLogger();

if (File.Exists(_hassioConfigPath))
{
try
{
var hassAddOnSettings = await JsonSerializer.DeserializeAsync<HassioConfig>(
File.OpenRead(_hassioConfigPath)).ConfigureAwait(false);
if (hassAddOnSettings.LogLevel is object)
{
SeriLogConfigurator.SetMinimumLogLevel(hassAddOnSettings.LogLevel);
}
if (hassAddOnSettings.GenerateEntitiesOnStart is object)
{
Environment.SetEnvironmentVariable("HASS_GEN_ENTITIES", hassAddOnSettings.GenerateEntitiesOnStart.ToString());
}
if (hassAddOnSettings.LogMessages is object && hassAddOnSettings.LogMessages == true)
{
Environment.SetEnvironmentVariable("HASSCLIENT_MSGLOGLEVEL", "Default");
}
if (hassAddOnSettings.ProjectFolder is object &&
string.IsNullOrEmpty(hassAddOnSettings.ProjectFolder) == false)
{
Environment.SetEnvironmentVariable("HASS_RUN_PROJECT_FOLDER", hassAddOnSettings.ProjectFolder);
}

// We are in Hassio so hard code the path
Environment.SetEnvironmentVariable("HASS_DAEMONAPPFOLDER", "/config/netdaemon");
}
catch (Exception e)
{
Log.Fatal(e, "Failed to read the Home Assistant Add-on config");
}
}
else
{
var envLogLevel = Environment.GetEnvironmentVariable("HASS_LOG_LEVEL");
if (!string.IsNullOrEmpty(envLogLevel))
{
SeriLogConfigurator.SetMinimumLogLevel(envLogLevel);
}
}

await CreateHostBuilder(args).Build().RunAsync();
}
catch (Exception e)
{
Log.Fatal(e, "Failed to start host...");
}
finally
{
Log.CloseAndFlush();
}
}
}
}
98 changes: 0 additions & 98 deletions src/DaemonRunner/DaemonRunner/Service/RunnerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,112 +8,14 @@
using System.Threading;
using System.Threading.Tasks;
using JoySoftware.HomeAssistant.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NetDaemon.Daemon;
using NetDaemon.Daemon.Storage;
using NetDaemon.Service.App;
using Serilog;
using Serilog.Core;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;

namespace NetDaemon.Service
{
public static class Runner
{
private const string _hassioConfigPath = "/data/options.json";
private static LoggingLevelSwitch _levelSwitch = new LoggingLevelSwitch();

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureServices(services =>
{
services.AddHttpClient();
services.AddHostedService<RunnerService>();
});

public static async Task Run(string[] args)
{
try
{
// Setup serilog
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.MinimumLevel.ControlledBy(_levelSwitch)
.WriteTo.Console(theme: AnsiConsoleTheme.Code)
.CreateLogger();

if (File.Exists(_hassioConfigPath))
{
try
{
var hassAddOnSettings = await JsonSerializer.DeserializeAsync<HassioConfig>(
File.OpenRead(_hassioConfigPath)).ConfigureAwait(false);
if (hassAddOnSettings.LogLevel is object)
{
_levelSwitch.MinimumLevel = hassAddOnSettings.LogLevel switch
{
"info" => LogEventLevel.Information,
"debug" => LogEventLevel.Debug,
"error" => LogEventLevel.Error,
"warning" => LogEventLevel.Warning,
"trace" => LogEventLevel.Verbose,
_ => LogEventLevel.Information
};
}
if (hassAddOnSettings.GenerateEntitiesOnStart is object)
{
Environment.SetEnvironmentVariable("HASS_GEN_ENTITIES", hassAddOnSettings.GenerateEntitiesOnStart.ToString());
}
if (hassAddOnSettings.LogMessages is object && hassAddOnSettings.LogMessages == true)
{
Environment.SetEnvironmentVariable("HASSCLIENT_MSGLOGLEVEL", "Default");
}
if (hassAddOnSettings.ProjectFolder is object &&
string.IsNullOrEmpty(hassAddOnSettings.ProjectFolder) == false)
{
Environment.SetEnvironmentVariable("HASS_RUN_PROJECT_FOLDER", hassAddOnSettings.ProjectFolder);
}

// We are in Hassio so hard code the path
Environment.SetEnvironmentVariable("HASS_DAEMONAPPFOLDER", "/config/netdaemon");
}
catch (System.Exception e)
{
Log.Fatal(e, "Failed to read the Home Assistant Add-on config");
}
}
else
{
var envLogLevel = Environment.GetEnvironmentVariable("HASS_LOG_LEVEL");
_levelSwitch.MinimumLevel = envLogLevel switch
{
"info" => LogEventLevel.Information,
"debug" => LogEventLevel.Debug,
"error" => LogEventLevel.Error,
"warning" => LogEventLevel.Warning,
"trace" => LogEventLevel.Verbose,
_ => LogEventLevel.Information
};
}

CreateHostBuilder(args).Build().Run();
}
catch (Exception e)
{
Log.Fatal(e, "Failed to start host...");
}
finally
{
Log.CloseAndFlush();
}
}
}

public class RunnerService : BackgroundService
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Serilog;
using Serilog.Core;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;

namespace NetDaemon.Service.Support
{
internal static class SeriLogConfigurator
{
private static readonly LoggingLevelSwitch LevelSwitch = new LoggingLevelSwitch();

public static LoggerConfiguration GetConfiguration()
{
return Configure(new LoggerConfiguration());
}

public static LoggerConfiguration Configure(LoggerConfiguration configuration)
{
return configuration
.MinimumLevel.ControlledBy(LevelSwitch)
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Console(theme: AnsiConsoleTheme.Code);
}

public static void SetMinimumLogLevel(string level)
{
LevelSwitch.MinimumLevel = level switch
{
"info" => LogEventLevel.Information,
"debug" => LogEventLevel.Debug,
"error" => LogEventLevel.Error,
"warning" => LogEventLevel.Warning,
"trace" => LogEventLevel.Verbose,
_ => LogEventLevel.Information
};
}
}
}

0 comments on commit a89009a

Please sign in to comment.