-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
122 lines (110 loc) · 4.77 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
using AlmostBinary_Compiler.utils;
using AlmostBinary_GlobalConstants;
using CommandLine;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;
using System;
using System.IO;
using System.Reflection;
namespace AlmostBinary_Compiler
{
public class Program
{
/// <summary>
/// Used to bring at least some context to the Program class, otherwise most context fields in outputTemplate would be empty.
/// Line-No, method name .. still empty.
/// </summary>
private static ILogger StartupLogger => Serilog.Log.ForContext<Program>();
/// <summary>
/// Not outsourcable into GlobalConstants as Assembly etc. are not usable in that context.
/// </summary>
public static readonly string? PROGRAM_ENTRY_PATH = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
#region methods
public static void Main(string[] args)
{
Console.WriteLine($"Starting compiler. Received {args.Length} argument(s)."); // Logger not initialized yet
try
{
// Parse command line args
CommandLine.Parser.Default.ParseArguments<CommandLineOptions>(args).WithParsed(o =>
{
IServiceCollection services = ConfigureServices(o.Verbose);
ServiceProvider serviceProvider = services.BuildServiceProvider();
serviceProvider.GetService<Startup>().Run(o);
});
}
catch (Exception e)
{
StartupLogger.Fatal(e, $"Unexpected exception. Could not start application.");
throw;
}
finally
{
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnShutdown!);
}
}
/// <summary>
/// Is executed on proccess exit.
/// </summary>
private static void OnShutdown(object sender, EventArgs e)
{
StartupLogger.Information("Quitting compiler.");
Log.CloseAndFlush();
}
/// <summary>
/// Configures global services.
/// </summary>
private static IServiceCollection ConfigureServices(bool? setVerboseLogLevel)
{
IServiceCollection services = new ServiceCollection();
IConfiguration configuration = BuildConfiguration();
services.AddSingleton(configuration);
// Required to run application
services.AddTransient<Startup>();
Log.Logger = CraftLogger(configuration, setVerboseLogLevel == true ? LogEventLevel.Verbose : configuration.GetValue<LogEventLevel>("Logging:LogLevel"));
StartupLogger.Information("Attached and configured services.");
return services;
}
/// <summary>
/// Makes configuration accessible related to current build (debug/release).
/// </summary>
/// <returns>Global Configuration</returns>
private static IConfiguration BuildConfiguration() => new ConfigurationBuilder()
.SetBasePath(Path.Combine(
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
"Properties"))
.AddJsonFile(IGlobalConstants.APP_SETTINGS_FILE, optional: false, reloadOnChange: true)
.Build();
/// <summary>
/// Builds File- and Console logger
/// </summary>
/// <param name="configuration">Global configuration</param>
/// <returns>Logger</returns>
private static ILogger CraftLogger(IConfiguration configuration, LogEventLevel logLevel)
{
string outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} - {SourceContext}:{MemberName}:{LineNumber}{NewLine}{Exception}";
return new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Verbose()
.WriteTo.Async(f => f.File(
Path.Combine(
IGlobalConstants.PROJECT_ROOT_PATH,
configuration.GetValue<string>("Logging:LogOutputPath")
),
rollingInterval: RollingInterval.Day,
buffered: true,
restrictedToMinimumLevel: logLevel,
outputTemplate: outputTemplate))
.WriteTo.Console(
outputTemplate: outputTemplate,
restrictedToMinimumLevel: logLevel,
theme: AnsiConsoleTheme.Code
)
.CreateLogger();
}
}
#endregion
}