1
0
mirror of https://github.com/bitwarden/mobile synced 2026-01-08 11:33:31 +00:00

BEEEP: Abstract and Centralize Logging (#1663)

* Abstracted App Center Logging into its own component, so that we can have it centralized in one place and we avoid checking for FDroid on all the places we want to use it

* Implemented the new logger where Crashes.TrackError was being used except on some specific cases

* Improved logging, added a debug logger and removed AppCenter to be used on DEBUG
This commit is contained in:
Federico Maccaroni
2022-03-02 14:15:16 -03:00
committed by GitHub
parent 34d0ecf64b
commit db7ca3b93e
32 changed files with 328 additions and 147 deletions

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Bit.Core.Abstractions
{
public interface ILogger
{
/// <summary>
/// Logs something that is not in itself an exception, e.g. a wrong flow or value that needs to be reported
/// and looked into.
/// </summary>
/// <param name="message">A text to be used as the issue's title</param>
/// <param name="extraData">Additional data</param>
void Error(string message,
IDictionary<string, string> extraData = null,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0);
/// <summary>
/// Logs an exception
/// </summary>
void Exception(Exception ex);
}
}

View File

@@ -1,6 +1,6 @@
namespace Bit.Core.Abstractions
{
public interface ILogService
public interface INativeLogService
{
void Debug(string message);
void Error(string message);

View File

@@ -15,6 +15,8 @@
<ItemGroup>
<None Remove="Resources\eff_long_word_list.txt" />
<None Remove="Resources\public_suffix_list.dat" />
<None Remove="Microsoft.AppCenter.Crashes" />
<None Remove="Services\Logging\" />
</ItemGroup>
<ItemGroup>
@@ -31,4 +33,7 @@
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Services\Logging\" />
</ItemGroup>
</Project>

View File

@@ -3,7 +3,7 @@ using System;
namespace Bit.Core.Services
{
public class ConsoleLogService : ILogService
public class ConsoleLogService : INativeLogService
{
public void Debug(string message)
{

View File

@@ -0,0 +1,50 @@
#if !FDROID
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using Bit.Core.Abstractions;
namespace Bit.Core.Services
{
public class DebugLogger : ILogger
{
static ILogger _instance;
public static ILogger Instance
{
get
{
if (_instance is null)
{
_instance = new DebugLogger();
}
return _instance;
}
}
protected DebugLogger()
{
}
public void Error(string message, IDictionary<string, string> extraData = null, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
var classAndMethod = $"{Path.GetFileNameWithoutExtension(sourceFilePath)}.{memberName}";
var filePathAndLineNumber = $"{Path.GetFileName(sourceFilePath)}:{sourceLineNumber}";
if (string.IsNullOrEmpty(message))
{
Debug.WriteLine($"Error found in: {classAndMethod})");
return;
}
Debug.WriteLine($"File: {filePathAndLineNumber}");
Debug.WriteLine($"Method: {memberName}");
Debug.WriteLine($"Message: {message}");
}
public void Exception(Exception ex) => Debug.WriteLine(ex);
}
}
#endif

View File

@@ -0,0 +1,71 @@
#if !FDROID
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using Bit.Core.Abstractions;
using Microsoft.AppCenter.Crashes;
namespace Bit.Core.Services
{
public class Logger : ILogger
{
static ILogger _instance;
public static ILogger Instance
{
get
{
if (_instance is null)
{
_instance = new Logger();
}
return _instance;
}
}
protected Logger()
{
}
public void Error(string message,
IDictionary<string, string> extraData = null,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
var classAndMethod = $"{Path.GetFileNameWithoutExtension(sourceFilePath)}.{memberName}";
var filePathAndLineNumber = $"{Path.GetFileName(sourceFilePath)}:{sourceLineNumber}";
var properties = new Dictionary<string, string>
{
["File"] = filePathAndLineNumber,
["Method"] = memberName
};
var exception = new Exception(message ?? $"Error found in: {classAndMethod}");
if (extraData == null)
{
Crashes.TrackError(exception, properties);
}
else
{
var data = properties.Concat(extraData).ToDictionary(x => x.Key, x => x.Value);
Crashes.TrackError(exception, data);
}
}
public void Exception(Exception exception)
{
try
{
Crashes.TrackError(exception);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
}
#endif

View File

@@ -0,0 +1,33 @@
using System;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
#if !FDROID
using Microsoft.AppCenter.Crashes;
#endif
namespace Bit.Core.Services
{
public static class LoggerHelper
{
/// <summary>
/// Logs the exception even if the service can't be resolved.
/// Useful when we need to log an exception in situations where the ServiceContainer may not be initialized.
/// </summary>
/// <param name="ex"></param>
public static void LogEvenIfCantBeResolved(Exception ex)
{
if (ServiceContainer.Resolve<ILogger>("logger", true) is ILogger logger)
{
logger.Exception(ex);
}
else
{
#if !FDROID
// just in case the caller throws the exception in a moment where the logger can't be resolved
// we need to track the error as well
Crashes.TrackError(ex);
#endif
}
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Bit.Core.Abstractions;
namespace Bit.Core.Services
{
/// <summary>
/// A logger that does nothing, this is useful on e.g. FDroid, where we cannot use logging through AppCenter
/// </summary>
public class StubLogger : ILogger
{
public void Error(string message, IDictionary<string, string> extraData = null, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
}
public void Exception(Exception ex)
{
}
}
}

View File

@@ -1,8 +1,6 @@
using System;
using System.Threading.Tasks;
#if !FDROID
using Microsoft.AppCenter.Crashes;
#endif
using Bit.Core.Services;
namespace Bit.Core.Utilities
{
@@ -22,9 +20,7 @@ namespace Bit.Core.Utilities
}
catch (Exception ex)
{
#if !FDROID
Crashes.TrackError(ex);
#endif
LoggerHelper.LogEvenIfCantBeResolved(ex);
onException?.Invoke(ex);
}
}