[fxcop] Fixes for Wox.Plugin (2of3) - Moved logger interface to Wox.Plugin (#7464)

* Moved Logger/Log.cs from Wox.Infrastructure to Wox.Plugin

- Installed Logger dependency in Wox.Plugin: NLog.Extensions.Logging
- Moved file Log.cs from Wox.Infrastructure/Logger/ to Wox.Plugin/Logger
- Moved file Constant.cs from Wox.Infrastructure to Wox.Plugin: This file was moved since Log.cs depends on this class
    - Copied Wox.Infrastructure.Helper.NonNull to Wox.Plugin.Constant since Constant.cs depends on this method
- Replaced all "using Wox.Infrastructure.Logger" to "using Wox.Plugin.Logger" in all files as needed
- Replaced Wox.Infrastructure.Constant to Wox.Plugin.Constant in all files as needed

* Removed Nlog.Extensions.Logging from Wox.Infrastructure

* Added logging and suppressed general exceptions (CA1031: Do not catch general exception types)

* Resolved fxcop errors introduced by newly added Log.cs

- CA1307: Specify StringComparison for clarity
- CA2000: Dispose objects before losing scope
- CA1062: Validate arguments of public methods

* Replaced Wox.Infrastructure.Logger with Wox.Plugin.Logger
This commit is contained in:
Avneet Kaur
2020-10-23 13:06:22 -07:00
committed by GitHub
parent 6ae8d6749a
commit beecdc8d79
44 changed files with 105 additions and 44 deletions

View File

@@ -0,0 +1,67 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace Wox.Plugin
{
public static class Constant
{
/// <summary>
/// http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy
/// </summary>
public static string NonNull(this string obj)
{
if (obj == null)
{
throw new NullReferenceException();
}
else
{
return obj;
}
}
public const string ExeFileName = "PowerLauncher";
public const string ModuleLocation = "Microsoft\\PowerToys\\PowerToys Run";
public const string Plugins = "Plugins";
public const string PortableFolderName = "UserData";
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
public static readonly string ProgramDirectory = Directory.GetParent(Assembly.Location.NonNull()).ToString();
public static readonly string ExecutablePath = Path.Combine(ProgramDirectory, ExeFileName + ".exe");
public static bool IsPortableMode { get; set; }
public static string PortableDataPath { get; set; } = Path.Combine(ProgramDirectory, PortableFolderName);
public static string DetermineDataDirectory()
{
if (Directory.Exists(PortableDataPath))
{
IsPortableMode = true;
return PortableDataPath;
}
else
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), ModuleLocation);
}
}
public static readonly string DataDirectory = DetermineDataDirectory();
public static readonly string PluginsDirectory = Path.Combine(DataDirectory, Plugins);
public static readonly string PreinstalledDirectory = Path.Combine(ProgramDirectory, Plugins);
public const string Issue = "https://aka.ms/powerToysReportBug";
public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).ProductVersion;
public static readonly int ThumbnailSize = 64;
public static readonly string DefaultIcon = Path.Combine(ProgramDirectory, "Images", "app.dark.png");
public static readonly string ErrorIcon = Path.Combine(ProgramDirectory, "Images", "app_error.dark.png");
public static readonly string LightThemedDefaultIcon = Path.Combine(ProgramDirectory, "Images", "app.light.png");
public static readonly string LightThemedErrorIcon = Path.Combine(ProgramDirectory, "Images", "app_error.light.png");
}
}

View File

@@ -0,0 +1,144 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using System.Runtime.CompilerServices;
using NLog;
using NLog.Config;
using NLog.Targets;
namespace Wox.Plugin.Logger
{
public static class Log
{
public const string DirectoryName = "Logs";
public static string CurrentLogDirectory { get; }
static Log()
{
CurrentLogDirectory = Path.Combine(Constant.DataDirectory, DirectoryName, Constant.Version);
if (!Directory.Exists(CurrentLogDirectory))
{
Directory.CreateDirectory(CurrentLogDirectory);
}
var configuration = new LoggingConfiguration();
var target = new FileTarget();
configuration.AddTarget("file", target);
// Adding CurrentCulture since this is user facing
target.FileName = CurrentLogDirectory.Replace(@"\", "/", StringComparison.CurrentCulture) + "/${shortdate}.txt";
#if DEBUG
var rule = new LoggingRule("*", LogLevel.Debug, target);
#else
var rule = new LoggingRule("*", LogLevel.Info, target);
#endif
configuration.LoggingRules.Add(rule);
LogManager.Configuration = configuration;
target.Dispose();
}
private static void LogInternalException(string message, System.Exception e, Type fullClassName, [CallerMemberName] string methodName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
var logger = GetLogger(fullClassName.FullName, methodName);
LogInternal(LogLevel.Error, message, fullClassName, logger, methodName, sourceFilePath, sourceLineNumber);
logger.Error("-------------------------- Begin exception --------------------------");
logger.Error($"\n\tMessage:\n\t {message}");
do
{
logger.Error(
$"\n\tException full name:\n\t <{e.GetType().FullName}>" +
$"\n\tException message:\n\t <{e.Message}>" +
$"\n\tException stack trace:\n\t <{e.StackTrace}>" +
$"\n\tException source:\n\t <{e.Source}>" +
$"\n\tException target site:\n\t <{e.TargetSite}>" +
$"\n\tException HResult:\n\t <{e.HResult}>");
e = e.InnerException;
}
while (e != null);
logger.Error("-------------------------- End exception --------------------------");
}
public static void Info(string message, Type fullClassName, [CallerMemberName] string methodName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
if (fullClassName == null)
{
throw new ArgumentNullException(nameof(fullClassName));
}
LogInternal(LogLevel.Info, message, fullClassName, methodName, sourceFilePath, sourceLineNumber);
}
public static void Debug(string message, Type fullClassName, [CallerMemberName] string methodName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
if (fullClassName == null)
{
throw new ArgumentNullException(nameof(fullClassName));
}
LogInternal(LogLevel.Debug, message, fullClassName, methodName, sourceFilePath, sourceLineNumber);
}
public static void Warn(string message, Type fullClassName, [CallerMemberName] string methodName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
if (fullClassName == null)
{
throw new ArgumentNullException(nameof(fullClassName));
}
LogInternal(LogLevel.Warn, message, fullClassName, methodName, sourceFilePath, sourceLineNumber);
}
public static void Error(string message, Type fullClassName, [CallerMemberName] string methodName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
if (fullClassName == null)
{
throw new ArgumentNullException(nameof(fullClassName));
}
LogInternal(LogLevel.Error, message, fullClassName, methodName, sourceFilePath, sourceLineNumber);
}
public static void Exception(string message, System.Exception ex, Type fullClassName, [CallerMemberName] string methodName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
if (fullClassName == null)
{
throw new ArgumentNullException(nameof(fullClassName));
}
LogInternalException(message, ex, fullClassName, methodName, sourceFilePath, sourceLineNumber);
}
private static void LogInternal(LogLevel level, string message, Type fullClassName, [CallerMemberName] string methodName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
var logger = GetLogger(fullClassName.FullName, methodName);
LogInternal(level, message, fullClassName, logger, methodName, sourceFilePath, sourceLineNumber);
}
private static void LogInternal(LogLevel level, string message, Type fullClassName, NLog.Logger logger, [CallerMemberName] string methodName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
// System.Diagnostics.Debug.WriteLine($" {level.Name} | {message}");
var msg = $"\n\tMessage: {message}" +
$"\n\tArea: {fullClassName}.{methodName}" +
$"\n\tSource Path: {sourceFilePath}::{sourceLineNumber}\n";
logger.Log(level, msg);
}
private static NLog.Logger GetLogger(string fullClassName, string methodName)
{
var classNameWithMethod = $"{fullClassName}.{methodName}";
return LogManager.GetLogger(classNameWithMethod);
}
}
}

View File

@@ -4,11 +4,14 @@
using System;
using System.IO;
using System.Reflection;
using Wox.Plugin.Logger;
namespace Wox.Plugin.SharedCommands
{
public static class FilesFolders
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception has been logged")]
public static void Copy(this string sourcePath, string targetPath)
{
// Get the subdirectories for the specified directory.
@@ -50,6 +53,8 @@ namespace Wox.Plugin.SharedCommands
catch (Exception e)
#pragma warning restore CS0168 // Variable is declared but never used
{
string error = $"Copying path {targetPath} has failed";
Log.Exception(error, e, MethodBase.GetCurrentMethod().DeclaringType);
#if DEBUG
throw e;
#else
@@ -59,6 +64,7 @@ namespace Wox.Plugin.SharedCommands
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception has been logged")]
public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPath)
{
try
@@ -82,15 +88,18 @@ namespace Wox.Plugin.SharedCommands
catch (Exception e)
#pragma warning restore CS0168 // Variable is declared but never used
{
string error = $"Unable to verify folders and files between {fromPath} and {toPath}";
Log.Exception(error, e, MethodBase.GetCurrentMethod().DeclaringType);
#if DEBUG
throw e;
#else
System.Windows.MessageBox.Show(string.Format("Unable to verify folders and files between {0} and {1}", fromPath, toPath));
System.Windows.MessageBox.Show(string.Format(error));
return false;
#endif
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception has been logged")]
public static void RemoveFolder(this string path)
{
try
@@ -104,10 +113,12 @@ namespace Wox.Plugin.SharedCommands
catch (Exception e)
#pragma warning restore CS0168 // Variable is declared but never used
{
string error = $"Not able to delete folder {path}, please go to the location and manually delete it";
Log.Exception(error, e, MethodBase.GetCurrentMethod().DeclaringType);
#if DEBUG
throw e;
#else
System.Windows.MessageBox.Show(string.Format("Not able to delete folder {0}, please go to the location and manually delete it", path));
System.Windows.MessageBox.Show(string.Format(error));
#endif
}
}

View File

@@ -70,6 +70,7 @@
<PackageReference Include="ControlzEx" Version="4.3.2" />
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.5" />
<PackageReference Include="PropertyChanged.Fody" Version="3.2.9">
<PrivateAssets>all</PrivateAssets>
</PackageReference>