Skip to content
This repository was archived by the owner on Dec 3, 2024. It is now read-only.

Commit d12c58e

Browse files
committed
Added basic application logging feature
1 parent 3edddb8 commit d12c58e

File tree

7 files changed

+147
-0
lines changed

7 files changed

+147
-0
lines changed

XOutput/Logging/AbstractLogger.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
using System.Reflection;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace XOutput.Logging
10+
{
11+
public abstract class AbstractLogger : ILogger
12+
{
13+
protected readonly Type loggerType;
14+
15+
public AbstractLogger(Type loggerType)
16+
{
17+
this.loggerType = loggerType;
18+
}
19+
20+
protected MethodBase GetCallerMethod()
21+
{
22+
return new StackTrace().GetFrame(2).GetMethod();
23+
}
24+
25+
protected string GetCallerMethodName()
26+
{
27+
MethodBase method = new StackTrace().GetFrame(2).GetMethod();
28+
bool asyncFunction = method.DeclaringType.Name.Contains("<") && method.DeclaringType.Name.Contains(">");
29+
if (asyncFunction)
30+
{
31+
int openIndex = method.DeclaringType.Name.IndexOf("<");
32+
int closeIndex = method.DeclaringType.Name.IndexOf(">");
33+
return method.DeclaringType.Name.Substring(openIndex + 1, closeIndex - openIndex - 1);
34+
}
35+
else
36+
{
37+
return method.Name;
38+
}
39+
}
40+
41+
protected string CreatePrefix(DateTime time, string classname, string methodname)
42+
{
43+
return $"{time.ToString("yyyy-MM-dd HH\\:mm\\:ss.fff zzz")} {classname}.{methodname}: ";
44+
}
45+
46+
public abstract void Error(string log, params string[] args);
47+
public abstract void Error(Exception ex);
48+
public abstract void Info(string log, params string[] args);
49+
public abstract void Warning(string log, params string[] args);
50+
}
51+
}

XOutput/Logging/ILogger.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace XOutput.Logging
8+
{
9+
public interface ILogger
10+
{
11+
void Info(string log, params string[] args);
12+
void Warning(string log, params string[] args);
13+
void Error(string log, params string[] args);
14+
void Error(Exception ex);
15+
}
16+
}

XOutput/Logging/LoggerFactory.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace XOutput.Logging
8+
{
9+
public static class LoggerFactory
10+
{
11+
public static ILogger GetLogger(Type type)
12+
{
13+
return new TraceLogger(type);
14+
}
15+
}
16+
}

XOutput/Logging/TraceLogger.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace XOutput.Logging
9+
{
10+
public class TraceLogger : AbstractLogger
11+
{
12+
public const string LOG_FILE = "XOutput.log";
13+
14+
static TraceLogger()
15+
{
16+
Trace.AutoFlush = true;
17+
Trace.Listeners.Add(new TextWriterTraceListener(LOG_FILE));
18+
}
19+
20+
public TraceLogger(Type loggerType) : base(loggerType)
21+
{
22+
23+
}
24+
25+
public override void Error(string log, params string[] args)
26+
{
27+
Trace.TraceError(CreatePrefix(DateTime.Now, loggerType.Name, GetCallerMethodName()) + log, args);
28+
}
29+
30+
public override void Error(Exception ex)
31+
{
32+
Trace.TraceError(CreatePrefix(DateTime.Now, loggerType.Name, GetCallerMethodName()) + ex.ToString());
33+
}
34+
35+
public override void Info(string log, params string[] args)
36+
{
37+
Trace.TraceInformation(CreatePrefix(DateTime.Now, loggerType.Name, GetCallerMethodName()) + log, args);
38+
}
39+
40+
public override void Warning(string log, params string[] args)
41+
{
42+
Trace.TraceWarning(CreatePrefix(DateTime.Now, loggerType.Name, GetCallerMethodName()) + log, args);
43+
}
44+
}
45+
}

XOutput/UI/MainWindow.xaml.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Windows.Navigation;
1717
using System.Windows.Shapes;
1818
using System.Windows.Threading;
19+
using XOutput.Logging;
1920
using XOutput.UI.Component;
2021

2122
namespace XOutput.UI
@@ -25,6 +26,7 @@ namespace XOutput.UI
2526
/// </summary>
2627
public partial class MainWindow : Window, IViewBase<MainWindowViewModel, MainWindowModel>
2728
{
29+
private static readonly ILogger logger = LoggerFactory.GetLogger(typeof(MainWindow));
2830
private readonly MainWindowViewModel viewModel;
2931
public MainWindowViewModel ViewModel => viewModel;
3032

@@ -57,6 +59,7 @@ private async void Window_Loaded(object sender, RoutedEventArgs e)
5759
}
5860
}
5961
await GetData();
62+
logger.Info("The application has started.");
6063
}
6164

6265
public async Task GetData()
@@ -102,6 +105,7 @@ private void Window_Closed(object sender, EventArgs e)
102105
{
103106
viewModel.Finalizer();
104107
viewModel.Dispose();
108+
logger.Info("The application has exited.");
105109
}
106110

107111
private void CheckBox_Checked(object sender, RoutedEventArgs e)

XOutput/UI/MainWindowViewModel.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using XOutput.Input.Mapper;
1414
using XOutput.Input.XInput.SCPToolkit;
1515
using XOutput.Input.XInput.Vigem;
16+
using XOutput.Logging;
1617
using XOutput.UI.Component;
1718
using XOutput.UpdateChecker;
1819

@@ -23,6 +24,7 @@ public class MainWindowViewModel : ViewModelBase<MainWindowModel>, IDisposable
2324
private const string SettingsFilePath = "settings.txt";
2425
private const string GameControllersSettings = "joy.cpl";
2526

27+
private static readonly ILogger logger = LoggerFactory.GetLogger(typeof(MainWindowViewModel));
2628
private readonly DispatcherTimer timer = new DispatcherTimer();
2729
private readonly Devices directInputDevices = new Devices();
2830
private readonly Action<string> log;
@@ -74,10 +76,12 @@ public void Initialize()
7476
try
7577
{
7678
LoadSettings(SettingsFilePath);
79+
logger.Info("Loading settings was successful.");
7780
log(string.Format(Translate("LoadSettingsSuccess"), SettingsFilePath));
7881
}
7982
catch (Exception ex)
8083
{
84+
logger.Warning("Loading settings was unsuccessful.");
8185
string error = string.Format(Translate("LoadSettingsError"), SettingsFilePath) + Environment.NewLine + ex.Message;
8286
log(error);
8387
MessageBox.Show(error, Translate("Warning"));
@@ -88,6 +92,7 @@ public void Initialize()
8892
{
8993
if (scp)
9094
{
95+
logger.Info("SCPToolkit is installed only.");
9196
log(Translate("ScpInstalled"));
9297
}
9398
installed = true;
@@ -96,11 +101,13 @@ public void Initialize()
96101
{
97102
if (scp)
98103
{
104+
logger.Info("ViGEm is installed.");
99105
log(Translate("VigemNotInstalled"));
100106
installed = true;
101107
}
102108
else
103109
{
110+
logger.Error("Neither ViGEm nor SCPToolkit is installed.");
104111
string error = Translate("VigemAndScpNotInstalled");
105112
log(error);
106113
installed = false;
@@ -131,10 +138,12 @@ public void SaveSettings()
131138
try
132139
{
133140
settings.Save(SettingsFilePath);
141+
logger.Info("Saving settings was successful.");
134142
log(string.Format(Translate("SaveSettingsSuccess"), SettingsFilePath));
135143
}
136144
catch (Exception ex)
137145
{
146+
logger.Warning("Saving settings was unsuccessful.");
138147
string error = string.Format(Translate("SaveSettingsError"), SettingsFilePath) + Environment.NewLine + ex.Message;
139148
log(error);
140149
MessageBox.Show(error, Translate("Warning"));
@@ -178,6 +187,7 @@ public void RefreshGameControllers()
178187
{
179188
controller.Dispose();
180189
Model.Controllers.Remove(controllerView);
190+
logger.Info($"{controller.DisplayName} was disconnected.");
181191
log(string.Format(LanguageModel.Instance.Translate("ControllerDisconnected"), controller.DisplayName));
182192
}
183193
}
@@ -196,6 +206,7 @@ public void RefreshGameControllers()
196206
device.StartCapturing();
197207
device.Disconnected -= DispatchRefreshGameControllers;
198208
device.Disconnected += DispatchRefreshGameControllers;
209+
logger.Info($"{controller.DisplayName} was connected.");
199210
log(string.Format(LanguageModel.Instance.Translate("ControllerConnected"), controller.DisplayName));
200211
}
201212
}

XOutput/XOutput.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@
9595
<Compile Include="Input\XInput\Vigem\VigemXBox360Mappings.cs" />
9696
<Compile Include="Input\XInput\Vigem\VigemDevice.cs" />
9797
<Compile Include="Input\XInput\XInputHelper.cs" />
98+
<Compile Include="Logging\AbstractLogger.cs" />
99+
<Compile Include="Logging\LoggerFactory.cs" />
100+
<Compile Include="Logging\TraceLogger.cs" />
101+
<Compile Include="Logging\ILogger.cs" />
98102
<Compile Include="UI\Component\DPadModel.cs" />
99103
<Compile Include="UI\Component\DPadView.xaml.cs">
100104
<DependentUpon>DPadView.xaml</DependentUpon>

0 commit comments

Comments
 (0)