Implement NLog for ASF logging, closes #274, #279

This commit is contained in:
JustArchi
2016-07-04 19:22:46 +02:00
parent f8ab06871f
commit 6ada40fc2f
14 changed files with 78 additions and 81 deletions

View File

@@ -81,6 +81,10 @@
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.4.0-beta13\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="protobuf-net, Version=2.0.0.668, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL"> <Reference Include="protobuf-net, Version=2.0.0.668, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
<HintPath>..\packages\protobuf-net.2.0.0.668\lib\net40\protobuf-net.dll</HintPath> <HintPath>..\packages\protobuf-net.2.0.0.668\lib\net40\protobuf-net.dll</HintPath>
<Private>True</Private> <Private>True</Private>
@@ -90,13 +94,18 @@
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Configuration.Install" /> <Reference Include="System.Configuration.Install" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security" /> <Reference Include="System.Security" />
<Reference Include="System.ServiceModel" /> <Reference Include="System.ServiceModel" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.ServiceProcess" /> <Reference Include="System.ServiceProcess" />
<Reference Include="System.Transactions" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -25,43 +25,61 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using NLog;
using NLog.Config;
using NLog.Targets;
namespace ArchiSteamFarm { namespace ArchiSteamFarm {
internal static class Logging { internal static class Logging {
private static readonly object FileLock = new object(); private const string Layout = @"${date:format=yyyy-MM-dd HH\:mm\:ss}|${level:uppercase=true}|${message}${onexception:inner= ${exception:format=toString,Data}}";
private static bool LogToFile; private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
internal static void Init() { internal static void Init() {
LogToFile = Program.GlobalConfig.LogToFile; LoggingConfiguration config = new LoggingConfiguration();
if (!LogToFile) { if (Program.GlobalConfig.LogToFile) {
return; FileTarget fileTarget = new FileTarget("File") {
FileName = Program.LogFile,
Layout = Layout
};
config.AddTarget(fileTarget);
config.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, fileTarget));
} }
lock (FileLock) { if (Program.IsRunningAsService) {
if (!LogToFile) { EventLogTarget eventLogTarget = new EventLogTarget("EventLog") {
return; Layout = Layout
} };
try { config.AddTarget(eventLogTarget);
File.Delete(Program.LogFile); config.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, eventLogTarget));
} catch (Exception e) {
LogToFile = false;
LogGenericException(e);
}
} }
ColoredConsoleTarget consoleTarget = new ColoredConsoleTarget("Console") {
Layout = Layout
};
config.AddTarget(consoleTarget);
config.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, consoleTarget));
LogManager.Configuration = config;
} }
// Ideally, those two should disable/enable only console logging
// But for some reason removing console rule/target doesn't seem to work
internal static void OnUserInputStart() => LogManager.DisableLogging();
internal static void OnUserInputEnd() => LogManager.EnableLogging();
internal static void LogGenericWTF(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) { internal static void LogGenericWTF(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
if (string.IsNullOrEmpty(message)) { if (string.IsNullOrEmpty(message)) {
LogNullError(nameof(message), botName); LogNullError(nameof(message), botName);
return; return;
} }
Log("[!!] WTF: " + previousMethodName + "() <" + botName + "> " + message + ", WTF?"); Logger.Error($"{botName}|{previousMethodName}() {message}");
} }
internal static void LogGenericError(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) { internal static void LogGenericError(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
@@ -70,24 +88,16 @@ namespace ArchiSteamFarm {
return; return;
} }
Log("[!!] ERROR: " + previousMethodName + "() <" + botName + "> " + message); Logger.Error($"{botName}|{previousMethodName}() {message}");
} }
internal static void LogGenericException(Exception exception, string botName = "Main", [CallerMemberName] string previousMethodName = null) { internal static void LogGenericException(Exception exception, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
while (true) { if (exception == null) {
if (exception == null) { LogNullError(nameof(exception), botName);
LogNullError(nameof(exception), botName); return;
return;
}
Log("[!] EXCEPTION: " + previousMethodName + "() <" + botName + "> " + exception.Message + Environment.NewLine + "StackTrace:" + Environment.NewLine + exception.StackTrace);
if (exception.InnerException != null) {
exception = exception.InnerException;
continue;
}
break;
} }
Logger.Error(exception, $"{botName}|{previousMethodName}()");
} }
internal static void LogGenericWarning(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) { internal static void LogGenericWarning(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
@@ -96,7 +106,7 @@ namespace ArchiSteamFarm {
return; return;
} }
Log("[!] WARNING: " + previousMethodName + "() <" + botName + "> " + message); Logger.Warn($"{botName}|{previousMethodName}() {message}");
} }
internal static void LogGenericInfo(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) { internal static void LogGenericInfo(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
@@ -105,20 +115,15 @@ namespace ArchiSteamFarm {
return; return;
} }
Log("[*] INFO: " + previousMethodName + "() <" + botName + "> " + message); Logger.Info($"{botName}|{previousMethodName}() {message}");
} }
[SuppressMessage("ReSharper", "ExplicitCallerInfoArgument")]
internal static void LogNullError(string nullObjectName, string botName = "Main", [CallerMemberName] string previousMethodName = null) { internal static void LogNullError(string nullObjectName, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
while (true) { if (string.IsNullOrEmpty(nullObjectName)) {
if (string.IsNullOrEmpty(nullObjectName)) { return;
nullObjectName = nameof(nullObjectName);
continue;
}
LogGenericError(nullObjectName + " is null!", botName, previousMethodName);
break;
} }
Logger.Error($"{botName}|{previousMethodName}() {nullObjectName} is null!");
} }
[Conditional("DEBUG")] [Conditional("DEBUG")]
@@ -129,42 +134,7 @@ namespace ArchiSteamFarm {
return; return;
} }
Log("[#] DEBUG: " + previousMethodName + "() <" + botName + "> " + message); Logger.Debug($"{botName}|{previousMethodName}() {message}");
}
private static void Log(string message) {
if (string.IsNullOrEmpty(message)) {
LogNullError(nameof(message));
return;
}
string loggedMessage = DateTime.Now + " " + message + Environment.NewLine;
// Write on console only when not awaiting response from user
if (!Program.ConsoleIsBusy) {
try {
Console.Write(loggedMessage);
} catch {
// Ignored
}
}
if (!LogToFile) {
return;
}
lock (FileLock) {
if (!LogToFile) {
return;
}
try {
File.AppendAllText(Program.LogFile, loggedMessage);
} catch (Exception e) {
LogToFile = false;
LogGenericException(e);
}
}
} }
} }
} }

View File

@@ -77,9 +77,9 @@ namespace ArchiSteamFarm {
private static readonly string ExecutableDirectory = Path.GetDirectoryName(ExecutableFile); private static readonly string ExecutableDirectory = Path.GetDirectoryName(ExecutableFile);
private static readonly WCF WCF = new WCF(); private static readonly WCF WCF = new WCF();
internal static bool IsRunningAsService { get; private set; }
internal static GlobalConfig GlobalConfig { get; private set; } internal static GlobalConfig GlobalConfig { get; private set; }
internal static GlobalDatabase GlobalDatabase { get; private set; } internal static GlobalDatabase GlobalDatabase { get; private set; }
internal static bool ConsoleIsBusy { get; private set; }
private static Timer AutoUpdatesTimer; private static Timer AutoUpdatesTimer;
private static EMode Mode = EMode.Normal; private static EMode Mode = EMode.Normal;
@@ -286,7 +286,7 @@ namespace ArchiSteamFarm {
string result; string result;
lock (ConsoleLock) { lock (ConsoleLock) {
ConsoleIsBusy = true; Logging.OnUserInputStart();
switch (userInputType) { switch (userInputType) {
case EUserInputType.DeviceID: case EUserInputType.DeviceID:
Console.Write("<" + botName + "> Please enter your Device ID (including \"android:\"): "); Console.Write("<" + botName + "> Please enter your Device ID (including \"android:\"): ");
@@ -330,7 +330,7 @@ namespace ArchiSteamFarm {
Console.Clear(); // For security purposes Console.Clear(); // For security purposes
} }
ConsoleIsBusy = false; Logging.OnUserInputEnd();
} }
return !string.IsNullOrEmpty(result) ? result.Trim() : null; return !string.IsNullOrEmpty(result) ? result.Trim() : null;
@@ -520,6 +520,7 @@ namespace ArchiSteamFarm {
foreach (string botName in Directory.EnumerateFiles(ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) { foreach (string botName in Directory.EnumerateFiles(ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) {
switch (botName) { switch (botName) {
case ASF: case ASF:
case "Main":
case "example": case "example":
case "minimal": case "minimal":
continue; continue;
@@ -553,6 +554,7 @@ namespace ArchiSteamFarm {
Exit(); Exit();
} else { } else {
// Service // Service
IsRunningAsService = true;
using (Service service = new Service()) { using (Service service = new Service()) {
ServiceBase.Run(service); ServiceBase.Run(service);
} }

View File

@@ -4,6 +4,7 @@
<package id="Fody" version="1.30.0-beta01" targetFramework="net461" developmentDependency="true" /> <package id="Fody" version="1.30.0-beta01" targetFramework="net461" developmentDependency="true" />
<package id="HtmlAgilityPack" version="1.4.9.4" targetFramework="net461" /> <package id="HtmlAgilityPack" version="1.4.9.4" targetFramework="net461" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" /> <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
<package id="NLog" version="4.4.0-beta13" targetFramework="net461" />
<package id="protobuf-net" version="2.0.0.668" targetFramework="net45" /> <package id="protobuf-net" version="2.0.0.668" targetFramework="net45" />
<package id="SteamKit2" version="1.7.0" targetFramework="net452" /> <package id="SteamKit2" version="1.7.0" targetFramework="net452" />
</packages> </packages>

View File

@@ -60,6 +60,7 @@ namespace ConfigGenerator {
string botName = Path.GetFileNameWithoutExtension(configFile); string botName = Path.GetFileNameWithoutExtension(configFile);
switch (botName) { switch (botName) {
case Program.ASF: case Program.ASF:
case "Main":
case "example": case "example":
case "minimal": case "minimal":
continue; continue;
@@ -155,6 +156,20 @@ namespace ConfigGenerator {
// Get rid of any potential whitespaces in bot name // Get rid of any potential whitespaces in bot name
input = Regex.Replace(input, @"\s+", ""); input = Regex.Replace(input, @"\s+", "");
if (string.IsNullOrEmpty(input)) {
Logging.LogGenericErrorWithoutStacktrace("Your bot name is empty!");
return;
}
switch (input) {
case Program.ASF:
case "Main":
case "example":
case "minimal":
Logging.LogGenericErrorWithoutStacktrace("This name is reserved!");
return;
}
if (ASFConfig.ASFConfigs.Select(config => Path.GetFileNameWithoutExtension(config.FilePath)).Any(fileNameWithoutExtension => (fileNameWithoutExtension == null) || fileNameWithoutExtension.Equals(input))) { if (ASFConfig.ASFConfigs.Select(config => Path.GetFileNameWithoutExtension(config.FilePath)).Any(fileNameWithoutExtension => (fileNameWithoutExtension == null) || fileNameWithoutExtension.Equals(input))) {
Logging.LogGenericErrorWithoutStacktrace("Bot with such name exists already!"); Logging.LogGenericErrorWithoutStacktrace("Bot with such name exists already!");
return; return;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.