Skip to content

Commit b803aa1

Browse files
authored
feat: add logging to App (#78)
Adds logging to the Coder Desktop application.
1 parent e5d9dc1 commit b803aa1

File tree

10 files changed

+788
-606
lines changed

10 files changed

+788
-606
lines changed

App/App.csproj

+6-3
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@
6161
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
6262
</PackageReference>
6363
<PackageReference Include="H.NotifyIcon.WinUI" Version="2.2.0" />
64-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.1" />
65-
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.1" />
66-
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.1" />
64+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
65+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.4" />
66+
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.4" />
6767
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.250108002" />
68+
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
69+
<PackageReference Include="Serilog.Settings.Configuration" Version="9.0.0" />
70+
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
6871
<PackageReference Include="WinUIEx" Version="2.5.1" />
6972
</ItemGroup>
7073

App/App.xaml.cs

+75-19
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
using Microsoft.Win32;
1717
using Microsoft.Windows.AppLifecycle;
1818
using Windows.ApplicationModel.Activation;
19+
using Microsoft.Extensions.Logging;
20+
using Serilog;
21+
using System.Collections.Generic;
1922

2023
namespace Coder.Desktop.App;
2124

@@ -24,22 +27,39 @@ public partial class App : Application
2427
private readonly IServiceProvider _services;
2528

2629
private bool _handleWindowClosed = true;
30+
private const string MutagenControllerConfigSection = "MutagenController";
2731

2832
#if !DEBUG
29-
private const string MutagenControllerConfigSection = "AppMutagenController";
33+
private const string ConfigSubKey = @"SOFTWARE\Coder Desktop\App";
34+
private const string logFilename = "app.log";
3035
#else
31-
private const string MutagenControllerConfigSection = "DebugAppMutagenController";
36+
private const string ConfigSubKey = @"SOFTWARE\Coder Desktop\DebugApp";
37+
private const string logFilename = "debug-app.log";
3238
#endif
3339

40+
private readonly ILogger<App> _logger;
41+
3442
public App()
3543
{
3644
var builder = Host.CreateApplicationBuilder();
45+
var configBuilder = builder.Configuration as IConfigurationBuilder;
3746

38-
(builder.Configuration as IConfigurationBuilder).Add(
39-
new RegistryConfigurationSource(Registry.LocalMachine, @"SOFTWARE\Coder Desktop"));
47+
// Add config in increasing order of precedence: first builtin defaults, then HKLM, finally HKCU
48+
// so that the user's settings in the registry take precedence.
49+
AddDefaultConfig(configBuilder);
50+
configBuilder.Add(
51+
new RegistryConfigurationSource(Registry.LocalMachine, ConfigSubKey));
52+
configBuilder.Add(
53+
new RegistryConfigurationSource(Registry.CurrentUser, ConfigSubKey));
4054

4155
var services = builder.Services;
4256

57+
// Logging
58+
builder.Services.AddSerilog((_, loggerConfig) =>
59+
{
60+
loggerConfig.ReadFrom.Configuration(builder.Configuration);
61+
});
62+
4363
services.AddSingleton<ICredentialManager, CredentialManager>();
4464
services.AddSingleton<IRpcController, RpcController>();
4565

@@ -69,12 +89,14 @@ public App()
6989
services.AddTransient<TrayWindow>();
7090

7191
_services = services.BuildServiceProvider();
92+
_logger = (ILogger<App>)(_services.GetService(typeof(ILogger<App>))!);
7293

7394
InitializeComponent();
7495
}
7596

7697
public async Task ExitApplication()
7798
{
99+
_logger.LogDebug("exiting app");
78100
_handleWindowClosed = false;
79101
Exit();
80102
var syncController = _services.GetRequiredService<ISyncSessionController>();
@@ -87,36 +109,39 @@ public async Task ExitApplication()
87109

88110
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
89111
{
112+
_logger.LogInformation("new instance launched");
90113
// Start connecting to the manager in the background.
91114
var rpcController = _services.GetRequiredService<IRpcController>();
92115
if (rpcController.GetState().RpcLifecycle == RpcLifecycle.Disconnected)
93116
// Passing in a CT with no cancellation is desired here, because
94117
// the named pipe open will block until the pipe comes up.
95-
// TODO: log
96-
_ = rpcController.Reconnect(CancellationToken.None).ContinueWith(t =>
118+
_logger.LogDebug("reconnecting with VPN service");
119+
_ = rpcController.Reconnect(CancellationToken.None).ContinueWith(t =>
120+
{
121+
if (t.Exception != null)
97122
{
123+
_logger.LogError(t.Exception, "failed to connect to VPN service");
98124
#if DEBUG
99-
if (t.Exception != null)
100-
{
101-
Debug.WriteLine(t.Exception);
102-
Debugger.Break();
103-
}
125+
Debug.WriteLine(t.Exception);
126+
Debugger.Break();
104127
#endif
105-
});
128+
}
129+
});
106130

107131
// Load the credentials in the background.
108132
var credentialManagerCts = new CancellationTokenSource(TimeSpan.FromSeconds(15));
109133
var credentialManager = _services.GetRequiredService<ICredentialManager>();
110134
_ = credentialManager.LoadCredentials(credentialManagerCts.Token).ContinueWith(t =>
111135
{
112-
// TODO: log
113-
#if DEBUG
114136
if (t.Exception != null)
115137
{
138+
_logger.LogError(t.Exception, "failed to load credentials");
139+
#if DEBUG
116140
Debug.WriteLine(t.Exception);
117141
Debugger.Break();
118-
}
119142
#endif
143+
}
144+
120145
credentialManagerCts.Dispose();
121146
}, CancellationToken.None);
122147

@@ -125,10 +150,14 @@ protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs ar
125150
var syncSessionController = _services.GetRequiredService<ISyncSessionController>();
126151
_ = syncSessionController.RefreshState(syncSessionCts.Token).ContinueWith(t =>
127152
{
128-
// TODO: log
153+
if (t.IsCanceled || t.Exception != null)
154+
{
155+
_logger.LogError(t.Exception, "failed to refresh sync state (canceled = {canceled})", t.IsCanceled);
129156
#if DEBUG
130-
if (t.IsCanceled || t.Exception != null) Debugger.Break();
157+
Debugger.Break();
131158
#endif
159+
}
160+
132161
syncSessionCts.Dispose();
133162
}, CancellationToken.None);
134163

@@ -148,17 +177,44 @@ public void OnActivated(object? sender, AppActivationArguments args)
148177
{
149178
case ExtendedActivationKind.Protocol:
150179
var protoArgs = args.Data as IProtocolActivatedEventArgs;
180+
if (protoArgs == null)
181+
{
182+
_logger.LogWarning("URI activation with null data");
183+
return;
184+
}
185+
151186
HandleURIActivation(protoArgs.Uri);
152187
break;
153188

154189
default:
155-
// TODO: log
190+
_logger.LogWarning("activation for {kind}, which is unhandled", args.Kind);
156191
break;
157192
}
158193
}
159194

160195
public void HandleURIActivation(Uri uri)
161196
{
162-
// TODO: handle
197+
// don't log the query string as that's where we include some sensitive information like passwords
198+
_logger.LogInformation("handling URI activation for {path}", uri.AbsolutePath);
199+
}
200+
201+
private static void AddDefaultConfig(IConfigurationBuilder builder)
202+
{
203+
var logPath = Path.Combine(
204+
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
205+
"CoderDesktop",
206+
logFilename);
207+
builder.AddInMemoryCollection(new Dictionary<string, string?>
208+
{
209+
[MutagenControllerConfigSection + ":MutagenExecutablePath"] = @"C:\mutagen.exe",
210+
["Serilog:Using:0"] = "Serilog.Sinks.File",
211+
["Serilog:MinimumLevel"] = "Information",
212+
["Serilog:Enrich:0"] = "FromLogContext",
213+
["Serilog:WriteTo:0:Name"] = "File",
214+
["Serilog:WriteTo:0:Args:path"] = logPath,
215+
["Serilog:WriteTo:0:Args:outputTemplate"] =
216+
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {SourceContext} - {Message:lj}{NewLine}{Exception}",
217+
["Serilog:WriteTo:0:Args:rollingInterval"] = "Day",
218+
});
163219
}
164220
}

0 commit comments

Comments
 (0)