Skip to content

Commit

Permalink
Add ApplicationInsights.
Browse files Browse the repository at this point in the history
  • Loading branch information
Grabacr07 committed Sep 2, 2018
1 parent f15b2db commit 0927397
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 57 deletions.
7 changes: 6 additions & 1 deletion source/SylphyHorn.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<s:String x:Key="/Default/CodeStyle/CSharpUsing/KeepImports/=System_002ECollections_002EGeneric/@EntryIndexedValue">System.Collections.Generic</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpUsing/KeepImports/=System_002ELinq/@EntryIndexedValue">System.Linq</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpUsing/KeepImports/=System_002EThreading_002ETasks/@EntryIndexedValue">System.Threading.Tasks</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CPU/@EntryIndexedValue">CPU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OS/@EntryIndexedValue">OS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UI/@EntryIndexedValue">UI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb"&gt;&lt;ExtraRule Prefix="PART_" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
Expand Down Expand Up @@ -323,4 +324,8 @@
<s:Boolean x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=B8EA9D2C30004A46B0D5683B9811888E/MatchStrings/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=B8EA9D2C30004A46B0D5683B9811888E/Name/@EntryValue">To be determined</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=B8EA9D2C30004A46B0D5683B9811888E/Pattern/@EntryValue">\bTBD\b</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=B8EA9D2C30004A46B0D5683B9811888E/TodoIconStyle/@EntryValue">Edit</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=B8EA9D2C30004A46B0D5683B9811888E/TodoIconStyle/@EntryValue">Edit</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Baloon/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=subkey/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sylphy/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=tasktray/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
2 changes: 1 addition & 1 deletion source/SylphyHorn/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib"/>
<probing privatePath="lib" />
<dependentAssembly>
<assemblyIdentity name="Livet" publicKeyToken="b0b1d3f711ef38cb" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.3.0.0" newVersion="1.3.0.0" />
Expand Down
107 changes: 107 additions & 0 deletions source/SylphyHorn/Application.Static.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using MetroTrilithon.Linq;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using SylphyHorn.Interop;
using SylphyHorn.Properties;

namespace SylphyHorn
{
partial class Application
{
public static CommandLineArgs Args { get; private set; }

public static TelemetryClient TelemetryClient { get; }

public new static Application Current => (Application)System.Windows.Application.Current;

static Application()
{
AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;

TelemetryClient = new TelemetryClient();
TelemetryClient.Context.Session.Id = Guid.NewGuid().ToString();
TelemetryClient.Context.Device.OperatingSystem = Environment.OSVersion.ToString();
TelemetryClient.Context.Component.Version = ProductInfo.VersionString;
#if DEBUG
TelemetryClient.Context.User.Id = Environment.UserName;
#endif
SetInstrumentationKey();
}

static partial void SetInstrumentationKey();

private static void HandleUnhandledException(object sender, UnhandledExceptionEventArgs args)
{
if ((DateTime.Now - Process.GetCurrentProcess().StartTime).TotalMinutes >= 3)
{
// 3 分以上生きてたら安定稼働と見做して再起動させる
Restart();
}
else
{
ReportException("AppDomain", sender, args.ExceptionObject as Exception);
}
}

private static void Restart()
{
if (Args != null)
{
var restartCount = Args.Restarted ?? 0;

Process.Start(
Environment.GetCommandLineArgs()[0],
Args.Options
.Where(x => x.Key != Args.GetKey(nameof(CommandLineArgs.Restarted)))
.Concat(EnumerableEx.Return(Args.CreateOption(nameof(CommandLineArgs.Restarted), (restartCount + 1).ToString())))
.Select(x => x.ToString())
.JoinString(" "));
}
}


private static void ReportException(string caller, object sender, Exception exception)
{
try
{
var now = DateTimeOffset.Now;
var path = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
ProductInfo.Company,
ProductInfo.Product,
"ErrorReports",
$"ErrorReport-{now:yyyyMMdd-HHmmss}-{now.Millisecond:000}.log");

var message = $@"*** Error Report ({caller}) ***
{ProductInfo.Product} ver.{ProductInfo.VersionString}
{now}
{new SystemEnvironment()}
Sender: {(sender is Type t ? t : sender?.GetType())?.FullName}
Exception: {exception?.GetType().FullName}
{exception}
";
// ReSharper disable once AssignNullToNotNullAttribute
Directory.CreateDirectory(Path.GetDirectoryName(path));
File.AppendAllText(path, message);

TelemetryClient.TrackException(exception);
TelemetryClient.TrackTrace(message, SeverityLevel.Critical);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}

Current.Shutdown();
}
}
}
7 changes: 7 additions & 0 deletions source/SylphyHorn/Application.iKey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

namespace SylphyHorn
{
partial class Application
{
}
}
46 changes: 3 additions & 43 deletions source/SylphyHorn/Application.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Threading;
using Livet;
using MetroRadiance.UI;
using MetroTrilithon.Lifetime;
using MetroTrilithon.Linq;
using MetroTrilithon.Threading.Tasks;
using StatefulModel;
using SylphyHorn.Serialization;
Expand All @@ -25,15 +23,6 @@ sealed partial class Application : IDisposableHolder
= false;
#endif

public static CommandLineArgs Args { get; private set; }

public new static Application Current => (Application)System.Windows.Application.Current;

static Application()
{
AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;
}

private readonly MultipleDisposable _compositeDisposable = new MultipleDisposable();

internal HookService HookService { get; private set; }
Expand All @@ -46,7 +35,7 @@ protected override void OnStartup(StartupEventArgs e)

if (Args.Setup)
{
SetupShortcut();
this.SetupShortcut();
}

#if !DEBUG
Expand Down Expand Up @@ -94,7 +83,7 @@ protected override void OnStartup(StartupEventArgs e)
appInstance.CommandLineArgsReceived += (sender, message) =>
{
var args = new CommandLineArgs(message.CommandLineArgs);
if (args.Setup) SetupShortcut();
if (args.Setup) this.SetupShortcut();
};
#endif

Expand All @@ -121,7 +110,7 @@ protected override void OnExit(ExitEventArgs e)
((IDisposable)this).Dispose();
}

private static void SetupShortcut()
private void SetupShortcut()
{
var startup = new Startup();
if (!startup.IsExists)
Expand All @@ -136,35 +125,6 @@ private void HandleDispatcherUnhandledException(object sender, DispatcherUnhandl
args.Handled = true;
}

private static void HandleUnhandledException(object sender, UnhandledExceptionEventArgs args)
{
if ((DateTime.Now - Process.GetCurrentProcess().StartTime).TotalMinutes >= 3)
{
// 3 分以上生きてたら安定稼働と見做して再起動させる
Restart();
}
else
{
// ToDo: Exception dialog
}
}

private static void Restart()
{
if (Args != null)
{
var restartCount = Args.Restarted ?? 0;

Process.Start(
Environment.GetCommandLineArgs()[0],
Args.Options
.Where(x => x.Key != Args.GetKey(nameof(CommandLineArgs.Restarted)))
.Concat(EnumerableEx.Return(Args.CreateOption(nameof(CommandLineArgs.Restarted), (restartCount + 1).ToString())))
.Select(x => x.ToString())
.JoinString(" "));
}
}

#region IDisposable members

ICollection<IDisposable> IDisposableHolder.CompositeDisposable => this._compositeDisposable;
Expand Down
49 changes: 49 additions & 0 deletions source/SylphyHorn/Interop/DotnetVersion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using Microsoft.Win32;

// This example displays output like the following:
// .NET Framework Version: 4.6.1
//
// see also: https://docs.microsoft.com/ja-jp/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

namespace SylphyHorn.Interop
{
public class DotnetVersion
{
public static string GetVersion()
{
const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
var version = "";

using (var ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey))
{
if (ndpKey?.GetValue("Release") is int value)
{
version = GetVersionCore(value);
}
}

if (string.IsNullOrEmpty(version))
{
version = Environment.Version.ToString();
}

return $".NET Framework Version: {version}";
}

private static string GetVersionCore(int releaseKey)
{
if (releaseKey >= 461808) return "4.7.2 or later";
if (releaseKey >= 461308) return "4.7.1";
if (releaseKey >= 460798) return "4.7";
if (releaseKey >= 394802) return "4.6.2";
if (releaseKey >= 394254) return "4.6.1";
if (releaseKey >= 393295) return "4.6";
if (releaseKey >= 379893) return "4.5.2";
if (releaseKey >= 378675) return "4.5.1";
if (releaseKey >= 378389) return "4.5";

return "";
}
}
}
76 changes: 76 additions & 0 deletions source/SylphyHorn/Interop/SystemEnvironment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;

namespace SylphyHorn.Interop
{
public class SystemEnvironment
{
public string OS { get; }
public string OSVersion { get; }
public string Architecture { get; }

public string CPU { get; }
public string TotalPhysicalMemorySize { get; }
public string FreePhysicalMemorySize { get; }

public string DotNetVersion { get; }

public string ErrorMessage { get; }

public SystemEnvironment()
{
try
{
using (var managementClass = new ManagementClass("Win32_OperatingSystem"))
using (var managementObject = managementClass.GetInstances().OfType<ManagementObject>().FirstOrDefault())
{
if (managementObject == null) return;

this.OS = managementObject["Caption"].ToString();
this.OSVersion = managementObject["Version"].ToString();
this.Architecture = managementObject["OSArchitecture"].ToString();

this.TotalPhysicalMemorySize = $"{managementObject["TotalVisibleMemorySize"]:N0} KB";
this.FreePhysicalMemorySize = $"{managementObject["FreePhysicalMemory"]:N0} KB";
}


using (var managementClass = new ManagementClass("Win32_Processor"))
using (var managementObject = managementClass.GetInstances().OfType<ManagementObject>().FirstOrDefault())
{
if (managementObject == null) return;

this.CPU = managementObject["Name"].ToString();
}

this.DotNetVersion = DotnetVersion.GetVersion();
}
catch (Exception ex)
{
this.ErrorMessage = ex.Message;
}
}

public override string ToString()
{
if (!string.IsNullOrEmpty(this.ErrorMessage))
{
return $@"SystemEnvironment
({this.ErrorMessage})";
}

return $@"SystemEnvironment
OS: {this.OS}
OSVersion: {this.OSVersion}
Architecture: {this.Architecture}
Runtime: {this.DotNetVersion}
CPU: {this.CPU}
RAM (Total): {this.TotalPhysicalMemorySize}
RAM (Free): {this.FreePhysicalMemorySize}";

}
}
}
Loading

0 comments on commit 0927397

Please sign in to comment.