diff --git a/Directory.Packages.props b/Directory.Packages.props
index 3bca99a9..15bf141d 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -20,8 +20,6 @@
-
-
@@ -42,6 +40,7 @@
+
diff --git a/Wino.Core.Domain/Interfaces/IApplicationConfiguration.cs b/Wino.Core.Domain/Interfaces/IApplicationConfiguration.cs
index f2efb5d7..b87c0a56 100644
--- a/Wino.Core.Domain/Interfaces/IApplicationConfiguration.cs
+++ b/Wino.Core.Domain/Interfaces/IApplicationConfiguration.cs
@@ -23,5 +23,10 @@
/// Files here are short-lived and can be deleted by system.
///
string ApplicationTempFolderPath { get; set; }
+
+ ///
+ /// Application insights instrumentation key.
+ ///
+ string ApplicationInsightsInstrumentationKey { get; }
}
}
diff --git a/Wino.Core.Domain/Interfaces/IPreferencesService.cs b/Wino.Core.Domain/Interfaces/IPreferencesService.cs
index 9ef30635..afb0c515 100644
--- a/Wino.Core.Domain/Interfaces/IPreferencesService.cs
+++ b/Wino.Core.Domain/Interfaces/IPreferencesService.cs
@@ -187,6 +187,7 @@ namespace Wino.Core.Domain.Interfaces
DayOfWeek WorkingDayStart { get; set; }
DayOfWeek WorkingDayEnd { get; set; }
double HourHeight { get; set; }
+ string DiagnosticId { get; set; }
CalendarSettings GetCurrentCalendarSettings();
diff --git a/Wino.Core.Domain/Translations/en_US/resources.json b/Wino.Core.Domain/Translations/en_US/resources.json
index 5a70fd4d..e46ac92d 100644
--- a/Wino.Core.Domain/Translations/en_US/resources.json
+++ b/Wino.Core.Domain/Translations/en_US/resources.json
@@ -451,6 +451,8 @@
"SettingsDeleteProtection_Title": "Permanent Delete Protection",
"SettingsDiagnostics_Description": "For developers",
"SettingsDiagnostics_Title": "Diagnostics",
+ "SettingsDiagnostics_DiagnosticId_Title": "Diagnostic Id",
+ "SettingsDiagnostics_DiagnosticId_Description": "Share this Id with the developers when asked to get help for the issues you experience in Wino Mail.",
"SettingsDiscord_Description": "Get regular development updates, join roadmap discussions and provide feedback.",
"SettingsDiscord_Title": "Discord Channel",
"SettingsElementThemeSelectionDisabled": "Element theme selection is disabled when application theme is selected other than Default.",
diff --git a/Wino.Core.UWP/Services/PreferencesService.cs b/Wino.Core.UWP/Services/PreferencesService.cs
index 535e2f5e..fdcf13bf 100644
--- a/Wino.Core.UWP/Services/PreferencesService.cs
+++ b/Wino.Core.UWP/Services/PreferencesService.cs
@@ -229,6 +229,12 @@ namespace Wino.Core.UWP.Services
set => SaveProperty(propertyName: nameof(ServerTerminationBehavior), value);
}
+ public string DiagnosticId
+ {
+ get => _configurationService.Get(nameof(DiagnosticId), Guid.NewGuid().ToString());
+ set => SaveProperty(propertyName: nameof(DiagnosticId), value);
+ }
+
public DayOfWeek FirstDayOfWeek
{
get => _configurationService.Get(nameof(FirstDayOfWeek), DayOfWeek.Monday);
diff --git a/Wino.Core.UWP/Styles/Colors.xaml b/Wino.Core.UWP/Styles/Colors.xaml
index 853aba49..e60ea73c 100644
--- a/Wino.Core.UWP/Styles/Colors.xaml
+++ b/Wino.Core.UWP/Styles/Colors.xaml
@@ -9,6 +9,7 @@
#1abc9c
+ #ff7675
#ff7675
#1abc9c
diff --git a/Wino.Core.UWP/Wino.Core.UWP.csproj b/Wino.Core.UWP/Wino.Core.UWP.csproj
index 88bd8c3e..1bb7391b 100644
--- a/Wino.Core.UWP/Wino.Core.UWP.csproj
+++ b/Wino.Core.UWP/Wino.Core.UWP.csproj
@@ -98,7 +98,6 @@
-
diff --git a/Wino.Core.UWP/WinoApplication.cs b/Wino.Core.UWP/WinoApplication.cs
index ddeb52a0..ad492e29 100644
--- a/Wino.Core.UWP/WinoApplication.cs
+++ b/Wino.Core.UWP/WinoApplication.cs
@@ -3,9 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using Microsoft.AppCenter;
-using Microsoft.AppCenter.Analytics;
-using Microsoft.AppCenter.Crashes;
using Microsoft.Extensions.DependencyInjection;
using Nito.AsyncEx;
using Serilog;
@@ -40,24 +37,16 @@ namespace Wino.Core.UWP
protected IDatabaseService DatabaseService { get; }
protected ITranslationService TranslationService { get; }
- // Order matters.
- private List initializeServices => new List()
- {
- DatabaseService,
- TranslationService,
- ThemeService,
- };
-
- public abstract string AppCenterKey { get; }
-
protected WinoApplication()
{
- ConfigureAppCenter();
ConfigurePrelaunch();
Services = ConfigureServices();
+ AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
+ TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
UnhandledException += OnAppUnhandledException;
+
Resuming += OnResuming;
Suspending += OnSuspending;
@@ -77,6 +66,18 @@ namespace Wino.Core.UWP
ConfigureLogging();
}
+ private void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
+ => Log.Fatal(e.ExceptionObject as Exception, "AppDomain Unhandled Exception");
+
+ private void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
+ => Log.Error(e.Exception, "Unobserved Task Exception");
+
+ private void OnAppUnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
+ {
+ Log.Fatal(e.Exception, "Unhandled Exception");
+ e.Handled = true;
+ }
+
protected abstract void OnApplicationCloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e);
protected abstract IEnumerable GetActivationHandlers();
protected abstract ActivationHandler GetDefaultActivationHandler();
@@ -208,29 +209,12 @@ namespace Wino.Core.UWP
catch { }
}
-
-
private void ConfigurePrelaunch()
{
if (ApiInformation.IsMethodPresent("Windows.ApplicationModel.Core.CoreApplication", "EnablePrelaunch"))
CoreApplication.EnablePrelaunch(true);
}
- private void OnAppUnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
- {
- var parameters = new Dictionary()
- {
- { "BaseMessage", e.Exception.GetBaseException().Message },
- { "BaseStackTrace", e.Exception.GetBaseException().StackTrace },
- { "StackTrace", e.Exception.StackTrace },
- { "Message", e.Exception.Message },
- };
-
- Log.Error(e.Exception, "[Wino Crash]");
-
- Crashes.TrackError(e.Exception, parameters);
- Analytics.TrackEvent("Wino Crashed", parameters);
- }
public virtual async void OnResuming(object sender, object e)
@@ -255,8 +239,6 @@ namespace Wino.Core.UWP
public virtual void OnSuspending(object sender, SuspendingEventArgs e) { }
public abstract IServiceProvider ConfigureServices();
- public void ConfigureAppCenter()
- => AppCenter.Start(AppCenterKey, typeof(Analytics), typeof(Crashes));
public void ConfigureLogging()
{
diff --git a/Wino.Core.ViewModels/AboutPageViewModel.cs b/Wino.Core.ViewModels/AboutPageViewModel.cs
index c235089f..4eb70af3 100644
--- a/Wino.Core.ViewModels/AboutPageViewModel.cs
+++ b/Wino.Core.ViewModels/AboutPageViewModel.cs
@@ -1,6 +1,7 @@
using System;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
+using Serilog;
using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
@@ -13,6 +14,7 @@ namespace Wino.Core.ViewModels
private readonly IMailDialogService _dialogService;
private readonly INativeAppService _nativeAppService;
private readonly IApplicationConfiguration _appInitializerService;
+ private readonly IClipboardService _clipboardService;
private readonly IFileService _fileService;
private readonly ILogInitializer _logInitializer;
@@ -29,6 +31,7 @@ namespace Wino.Core.ViewModels
INativeAppService nativeAppService,
IPreferencesService preferencesService,
IApplicationConfiguration appInitializerService,
+ IClipboardService clipboardService,
IFileService fileService,
ILogInitializer logInitializer)
{
@@ -37,6 +40,7 @@ namespace Wino.Core.ViewModels
_nativeAppService = nativeAppService;
_logInitializer = logInitializer;
_appInitializerService = appInitializerService;
+ _clipboardService = clipboardService;
_fileService = fileService;
PreferencesService = preferencesService;
@@ -65,6 +69,21 @@ namespace Wino.Core.ViewModels
}
}
+ [RelayCommand]
+ private async Task CopyDiagnosticId()
+ {
+ try
+ {
+ await _clipboardService.CopyClipboardAsync(PreferencesService.DiagnosticId);
+ _dialogService.InfoBarMessage(Translator.Buttons_Copy, string.Format(Translator.ClipboardTextCopied_Message, "Id"), InfoBarMessageType.Success);
+ }
+ catch (Exception ex)
+ {
+ _dialogService.InfoBarMessage(Translator.GeneralTitle_Error, string.Format(Translator.ClipboardTextCopyFailed_Message, "Id"), InfoBarMessageType.Error);
+ Log.Error(ex, "Failed to copy diagnostic id to clipboard.");
+ }
+ }
+
[RelayCommand]
private async Task ShareWinoLogAsync()
{
diff --git a/Wino.Core.ViewModels/Wino.Core.ViewModels.csproj b/Wino.Core.ViewModels/Wino.Core.ViewModels.csproj
index 33fdcc6a..00c2b2ab 100644
--- a/Wino.Core.ViewModels/Wino.Core.ViewModels.csproj
+++ b/Wino.Core.ViewModels/Wino.Core.ViewModels.csproj
@@ -7,7 +7,6 @@
true
-
diff --git a/Wino.Core/Wino.Core.csproj b/Wino.Core/Wino.Core.csproj
index cc67afcd..1b7ec732 100644
--- a/Wino.Core/Wino.Core.csproj
+++ b/Wino.Core/Wino.Core.csproj
@@ -26,10 +26,6 @@
-
-
-
-
diff --git a/Wino.Core/WinoErrors.cs b/Wino.Core/WinoErrors.cs
deleted file mode 100644
index 1ef74d87..00000000
--- a/Wino.Core/WinoErrors.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-namespace Wino.Core
-{
- ///
- /// Error codes for Wino application.
- /// Pretty outdated.
- ///
- public static class WinoErrors
- {
- public const string AccountStructureRender = nameof(AccountStructureRender);
- public const string MimeRendering = nameof(MimeRendering);
- public const string MailRendering = nameof(MailRendering);
- public const string FolderOperationExecution = nameof(FolderOperationExecution);
- public const string StartupAccountExtendFail = nameof(StartupAccountExtendFail);
- public const string AccountNavigateInboxFail = nameof(AccountNavigateInboxFail);
- public const string AccountCreation = nameof(AccountCreation);
-
- public const string OutlookIntegratorFolderSync = nameof(OutlookIntegratorFolderSync);
- public const string GoogleSynchronizerAccountSync = nameof(GoogleSynchronizerAccountSync);
- public const string ImapFolderSync = nameof(ImapFolderSync);
-
- public const string RendererCommandMailOperation = nameof(RendererCommandMailOperation);
- public const string MailListingMailOperation = nameof(MailListingMailOperation);
-
- public const string AutoMarkAsRead = nameof(AutoMarkAsRead);
- public const string MailListGetItem = nameof(MailListGetItem);
- public const string MailListCollectionUpdate = nameof(MailListCollectionUpdate);
- public const string MailListRefreshFolder = nameof(MailListRefreshFolder);
- public const string ProcessorTaskFailed = nameof(ProcessorTaskFailed);
- public const string SearchFailed = nameof(SearchFailed);
-
- public const string BatchExecutionFailed = nameof(BatchExecutionFailed);
- public const string SingleBatchExecutionFailedGoogle = nameof(SingleBatchExecutionFailedGoogle);
-
- public const string SynchronizationWorkerException = nameof(SynchronizationWorkerException);
- public const string StoreRatingSubmission = nameof(StoreRatingSubmission);
-
- public const string OpenAttachment = nameof(OpenAttachment);
- public const string SaveAttachment = nameof(SaveAttachment);
-
- public const string OutlookMimeSaveFailure = nameof(OutlookMimeSaveFailure);
- }
-}
diff --git a/Wino.Mail.ViewModels/AccountManagementViewModel.cs b/Wino.Mail.ViewModels/AccountManagementViewModel.cs
index 4495cd37..0f0f69b4 100644
--- a/Wino.Mail.ViewModels/AccountManagementViewModel.cs
+++ b/Wino.Mail.ViewModels/AccountManagementViewModel.cs
@@ -5,9 +5,7 @@ using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
-using Microsoft.AppCenter.Crashes;
using Serilog;
-using Wino.Core;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Entities.Shared;
@@ -274,8 +272,7 @@ namespace Wino.Mail.ViewModels
}
catch (Exception ex)
{
- Log.Error(ex, WinoErrors.AccountCreation);
- Crashes.TrackError(ex);
+ Log.Error(ex, "Failed to create account.");
DialogService.InfoBarMessage(Translator.Info_AccountCreationFailedTitle, ex.Message, InfoBarMessageType.Error);
diff --git a/Wino.Mail.ViewModels/AppShellViewModel.cs b/Wino.Mail.ViewModels/AppShellViewModel.cs
index 6cfd027b..82d5a1cc 100644
--- a/Wino.Mail.ViewModels/AppShellViewModel.cs
+++ b/Wino.Mail.ViewModels/AppShellViewModel.cs
@@ -6,11 +6,9 @@ using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
-using Microsoft.AppCenter.Crashes;
using MoreLinq;
using MoreLinq.Extensions;
using Serilog;
-using Wino.Core;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Entities.Shared;
@@ -301,7 +299,7 @@ namespace Wino.Mail.ViewModels
}
catch (Exception ex)
{
- Crashes.TrackError(ex);
+ Log.Error(ex, "Failed to configure background tasks.");
_dialogService.InfoBarMessage(Translator.Info_BackgroundExecutionUnknownErrorTitle, Translator.Info_BackgroundExecutionUnknownErrorMessage, InfoBarMessageType.Error);
}
@@ -373,7 +371,7 @@ namespace Wino.Mail.ViewModels
}
catch (Exception ex)
{
- Log.Error(ex, WinoErrors.StartupAccountExtendFail);
+ Log.Error(ex, "Failed to process launch options.");
}
}
@@ -474,7 +472,7 @@ namespace Wino.Mail.ViewModels
}
catch (Exception ex)
{
- Log.Error(ex, WinoErrors.AccountNavigateInboxFail);
+ Log.Error(ex, "Failed to navigate to Inbox.");
}
}
diff --git a/Wino.Mail.ViewModels/MailListPageViewModel.cs b/Wino.Mail.ViewModels/MailListPageViewModel.cs
index 10e3dac7..af180369 100644
--- a/Wino.Mail.ViewModels/MailListPageViewModel.cs
+++ b/Wino.Mail.ViewModels/MailListPageViewModel.cs
@@ -10,11 +10,9 @@ using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
-using Microsoft.AppCenter.Crashes;
using MoreLinq;
using Nito.AsyncEx;
using Serilog;
-using Wino.Core;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Entities.Shared;
@@ -844,11 +842,9 @@ namespace Wino.Mail.ViewModels
Debugger.Break();
if (IsInSearchMode)
- Log.Error(ex, WinoErrors.SearchFailed);
+ Log.Error(ex, "Failed to perform search.");
else
- Log.Error(ex, WinoErrors.MailListRefreshFolder);
-
- Crashes.TrackError(ex);
+ Log.Error(ex, "Failed to refresh listed mails.");
}
finally
{
diff --git a/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs b/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs
index 96f428f0..5e0fdd84 100644
--- a/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs
+++ b/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs
@@ -9,10 +9,9 @@ using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using MailKit;
-using Microsoft.AppCenter.Crashes;
+
using MimeKit;
using Serilog;
-using Wino.Core;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Entities.Shared;
@@ -345,8 +344,7 @@ namespace Wino.Mail.ViewModels
{
_dialogService.InfoBarMessage(Translator.Info_MailRenderingFailedTitle, string.Format(Translator.Info_MailRenderingFailedMessage, ex.Message), InfoBarMessageType.Error);
- Crashes.TrackError(ex);
- Log.Error(ex, "Render Failed");
+ Log.Error(ex, "Failed to render mail.");
}
}
@@ -616,8 +614,7 @@ namespace Wino.Mail.ViewModels
}
catch (Exception ex)
{
- Log.Error(ex, WinoErrors.OpenAttachment);
- Crashes.TrackError(ex);
+ Log.Error(ex, "Failed to open attachment.");
_dialogService.InfoBarMessage(Translator.Info_AttachmentOpenFailedTitle, Translator.Info_AttachmentOpenFailedMessage, InfoBarMessageType.Error);
}
@@ -643,8 +640,7 @@ namespace Wino.Mail.ViewModels
}
catch (Exception ex)
{
- Log.Error(ex, WinoErrors.SaveAttachment);
- Crashes.TrackError(ex);
+ Log.Error(ex, "Failed to save attachment.");
_dialogService.InfoBarMessage(Translator.Info_AttachmentSaveFailedTitle, Translator.Info_AttachmentSaveFailedMessage, InfoBarMessageType.Error);
}
@@ -673,8 +669,7 @@ namespace Wino.Mail.ViewModels
}
catch (Exception ex)
{
- Log.Error(ex, WinoErrors.SaveAttachment);
- Crashes.TrackError(ex);
+ Log.Error(ex, "Failed to save attachment.");
_dialogService.InfoBarMessage(Translator.Info_AttachmentSaveFailedTitle, Translator.Info_AttachmentSaveFailedMessage, InfoBarMessageType.Error);
}
@@ -709,8 +704,8 @@ namespace Wino.Mail.ViewModels
}
catch (Exception ex)
{
+ Log.Error(ex, "Failed to print mail.");
_dialogService.InfoBarMessage(string.Empty, ex.Message, InfoBarMessageType.Error);
- Crashes.TrackError(ex);
}
}
@@ -735,8 +730,8 @@ namespace Wino.Mail.ViewModels
}
catch (Exception ex)
{
+ Log.Error(ex, "Failed to save as PDF.");
_dialogService.InfoBarMessage(Translator.Info_PDFSaveFailedTitle, ex.Message, InfoBarMessageType.Error);
- Crashes.TrackError(ex);
}
}
@@ -786,8 +781,7 @@ namespace Wino.Mail.ViewModels
{
_dialogService.InfoBarMessage(Translator.Info_MailRenderingFailedTitle, string.Format(Translator.Info_MailRenderingFailedMessage, ex.Message), InfoBarMessageType.Error);
- Crashes.TrackError(ex);
- Log.Error(ex, "Render Failed");
+ Log.Error(ex, "Failed to render mail.");
}
}
}
diff --git a/Wino.Mail.ViewModels/Wino.Mail.ViewModels.csproj b/Wino.Mail.ViewModels/Wino.Mail.ViewModels.csproj
index b44f763c..72e32d96 100644
--- a/Wino.Mail.ViewModels/Wino.Mail.ViewModels.csproj
+++ b/Wino.Mail.ViewModels/Wino.Mail.ViewModels.csproj
@@ -7,10 +7,9 @@
true
-
-
-
-
+
+
+
diff --git a/Wino.Mail/App.xaml.cs b/Wino.Mail/App.xaml.cs
index ec72397d..c7e3039a 100644
--- a/Wino.Mail/App.xaml.cs
+++ b/Wino.Mail/App.xaml.cs
@@ -31,8 +31,6 @@ namespace Wino
{
public sealed partial class App : WinoApplication, IRecipient
{
- public override string AppCenterKey { get; } = "90deb1d0-a77f-47d0-8a6b-7eaf111c6b72";
-
private BackgroundTaskDeferral connectionBackgroundTaskDeferral;
private BackgroundTaskDeferral toastActionBackgroundTaskDeferral;
diff --git a/Wino.Mail/Views/AboutPage.xaml b/Wino.Mail/Views/AboutPage.xaml
index 3f87887e..f67fc9f6 100644
--- a/Wino.Mail/Views/AboutPage.xaml
+++ b/Wino.Mail/Views/AboutPage.xaml
@@ -139,6 +139,31 @@
+
+
+
+
+
+
+
@@ -148,3 +173,4 @@
+
diff --git a/Wino.Mail/Wino.Mail.csproj b/Wino.Mail/Wino.Mail.csproj
index ffe1f917..957f80c8 100644
--- a/Wino.Mail/Wino.Mail.csproj
+++ b/Wino.Mail/Wino.Mail.csproj
@@ -11,7 +11,6 @@
win-$(Platform).pubxml
true
true
-
True
True
SHA256
@@ -90,15 +89,12 @@
-
-
-
+
-
-
+
diff --git a/Wino.Server/App.xaml.cs b/Wino.Server/App.xaml.cs
index 08c8affe..fe1cabf1 100644
--- a/Wino.Server/App.xaml.cs
+++ b/Wino.Server/App.xaml.cs
@@ -192,6 +192,7 @@ namespace Wino.Server
AppDomain.CurrentDomain.UnhandledException += ServerCrashed;
Application.Current.DispatcherUnhandledException += UIThreadCrash;
TaskScheduler.UnobservedTaskException += TaskCrashed;
+
// Ensure proper encodings are available for MimeKit
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
@@ -241,9 +242,9 @@ namespace Wino.Server
}
}
- private void TaskCrashed(object sender, UnobservedTaskExceptionEventArgs e) => Log.Error(e.Exception, "Task crashed.");
+ private void TaskCrashed(object sender, UnobservedTaskExceptionEventArgs e) => Log.Error(e.Exception, "Server task crashed.");
- private void UIThreadCrash(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) => Log.Error(e.Exception, "UI thread crashed.");
+ private void UIThreadCrash(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) => Log.Error(e.Exception, "Server UI thread crashed.");
private void ServerCrashed(object sender, UnhandledExceptionEventArgs e) => Log.Error((Exception)e.ExceptionObject, "Server crashed.");
diff --git a/Wino.Services/ApplicationConfiguration.cs b/Wino.Services/ApplicationConfiguration.cs
index f03369c4..3edda53f 100644
--- a/Wino.Services/ApplicationConfiguration.cs
+++ b/Wino.Services/ApplicationConfiguration.cs
@@ -9,5 +9,7 @@ namespace Wino.Services
public string ApplicationDataFolderPath { get; set; }
public string PublisherSharedFolderPath { get; set; }
public string ApplicationTempFolderPath { get; set; }
+
+ public string ApplicationInsightsInstrumentationKey => "a5a07c2f-6e24-4055-bfc9-88e87eef873a";
}
}
diff --git a/Wino.Services/LogInitializer.cs b/Wino.Services/LogInitializer.cs
index a4dae199..50898d49 100644
--- a/Wino.Services/LogInitializer.cs
+++ b/Wino.Services/LogInitializer.cs
@@ -1,7 +1,9 @@
-using Serilog;
+using Microsoft.ApplicationInsights.Extensibility;
+using Serilog;
using Serilog.Core;
using Serilog.Exceptions;
using Wino.Core.Domain.Interfaces;
+using Wino.Services.Misc;
namespace Wino.Services
{
@@ -9,10 +11,15 @@ namespace Wino.Services
{
private readonly LoggingLevelSwitch _levelSwitch = new LoggingLevelSwitch();
private readonly IPreferencesService _preferencesService;
+ private readonly IApplicationConfiguration _applicationConfiguration;
+ private readonly TelemetryConfiguration _telemetryConfiguration;
- public LogInitializer(IPreferencesService preferencesService)
+ public LogInitializer(IPreferencesService preferencesService, IApplicationConfiguration applicationConfiguration)
{
_preferencesService = preferencesService;
+ _applicationConfiguration = applicationConfiguration;
+
+ _telemetryConfiguration = new TelemetryConfiguration(applicationConfiguration.ApplicationInsightsInstrumentationKey);
RefreshLoggingLevel();
}
@@ -28,10 +35,13 @@ namespace Wino.Services
public void SetupLogger(string fullLogFilePath)
{
+ var insightsTelemetryConverter = new WinoTelemetryConverter(_preferencesService.DiagnosticId);
+
Log.Logger = new LoggerConfiguration()
.MinimumLevel.ControlledBy(_levelSwitch)
.WriteTo.File(fullLogFilePath, retainedFileCountLimit: 3, rollOnFileSizeLimit: true, rollingInterval: RollingInterval.Day)
.WriteTo.Debug()
+ .WriteTo.ApplicationInsights(_telemetryConfiguration, insightsTelemetryConverter, restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Error)
.Enrich.FromLogContext()
.Enrich.WithExceptionDetails()
.CreateLogger();
diff --git a/Wino.Services/Misc/WinoTelemetryConverter.cs b/Wino.Services/Misc/WinoTelemetryConverter.cs
new file mode 100644
index 00000000..adb300d2
--- /dev/null
+++ b/Wino.Services/Misc/WinoTelemetryConverter.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.ApplicationInsights.Channel;
+using Microsoft.ApplicationInsights.DataContracts;
+using Serilog.Events;
+using Serilog.Sinks.ApplicationInsights.TelemetryConverters;
+
+namespace Wino.Services.Misc
+{
+ internal class WinoTelemetryConverter : EventTelemetryConverter
+ {
+ private readonly string _userDiagnosticId;
+
+ public WinoTelemetryConverter(string userDiagnosticId)
+ {
+ _userDiagnosticId = userDiagnosticId;
+ }
+
+ public override IEnumerable Convert(LogEvent logEvent, IFormatProvider formatProvider)
+ {
+ foreach (ITelemetry telemetry in base.Convert(logEvent, formatProvider))
+ {
+ // Assign diagnostic id as user id.
+ telemetry.Context.User.Id = _userDiagnosticId;
+
+ yield return telemetry;
+ }
+ }
+
+ public override void ForwardPropertiesToTelemetryProperties(LogEvent logEvent, ISupportProperties telemetryProperties, IFormatProvider formatProvider)
+ {
+ ForwardPropertiesToTelemetryProperties(logEvent, telemetryProperties, formatProvider,
+ includeLogLevel: true,
+ includeRenderedMessage: true,
+ includeMessageTemplate: false);
+ }
+ }
+}
diff --git a/Wino.Services/ServicesContainerSetup.cs b/Wino.Services/ServicesContainerSetup.cs
index 89bf8b33..6ecb1941 100644
--- a/Wino.Services/ServicesContainerSetup.cs
+++ b/Wino.Services/ServicesContainerSetup.cs
@@ -29,6 +29,8 @@ namespace Wino.Services
services.AddTransient();
services.AddTransient();
services.AddTransient();
+
+
}
}
}
diff --git a/Wino.Services/Wino.Services.csproj b/Wino.Services/Wino.Services.csproj
index 8117e81f..089e7eec 100644
--- a/Wino.Services/Wino.Services.csproj
+++ b/Wino.Services/Wino.Services.csproj
@@ -7,12 +7,13 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/WinoMail.Packaging/WinoMail.Packaging.wapproj b/WinoMail.Packaging/WinoMail.Packaging.wapproj
index a6cc0375..36188528 100644
--- a/WinoMail.Packaging/WinoMail.Packaging.wapproj
+++ b/WinoMail.Packaging/WinoMail.Packaging.wapproj
@@ -141,6 +141,7 @@
+