diff --git a/ArchiSteamFarm/ArchiSteamFarm.csproj b/ArchiSteamFarm/ArchiSteamFarm.csproj
index d1c021a77..8e8841669 100644
--- a/ArchiSteamFarm/ArchiSteamFarm.csproj
+++ b/ArchiSteamFarm/ArchiSteamFarm.csproj
@@ -81,6 +81,10 @@
..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
True
+
+ ..\packages\NLog.4.4.0-beta13\lib\net45\NLog.dll
+ True
+
..\packages\protobuf-net.2.0.0.668\lib\net40\protobuf-net.dll
True
@@ -90,13 +94,18 @@
True
+
+
+
+
+
diff --git a/ArchiSteamFarm/Logging.cs b/ArchiSteamFarm/Logging.cs
index 613fc5b47..8927ee2ff 100644
--- a/ArchiSteamFarm/Logging.cs
+++ b/ArchiSteamFarm/Logging.cs
@@ -25,43 +25,61 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
-using System.IO;
using System.Runtime.CompilerServices;
+using NLog;
+using NLog.Config;
+using NLog.Targets;
namespace ArchiSteamFarm {
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() {
- LogToFile = Program.GlobalConfig.LogToFile;
+ LoggingConfiguration config = new LoggingConfiguration();
- if (!LogToFile) {
- return;
+ if (Program.GlobalConfig.LogToFile) {
+ FileTarget fileTarget = new FileTarget("File") {
+ FileName = Program.LogFile,
+ Layout = Layout
+ };
+
+ config.AddTarget(fileTarget);
+ config.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, fileTarget));
}
- lock (FileLock) {
- if (!LogToFile) {
- return;
- }
+ if (Program.IsRunningAsService) {
+ EventLogTarget eventLogTarget = new EventLogTarget("EventLog") {
+ Layout = Layout
+ };
- try {
- File.Delete(Program.LogFile);
- } catch (Exception e) {
- LogToFile = false;
- LogGenericException(e);
- }
+ config.AddTarget(eventLogTarget);
+ config.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, eventLogTarget));
}
+
+ 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) {
if (string.IsNullOrEmpty(message)) {
LogNullError(nameof(message), botName);
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) {
@@ -70,24 +88,16 @@ namespace ArchiSteamFarm {
return;
}
- Log("[!!] ERROR: " + previousMethodName + "() <" + botName + "> " + message);
+ Logger.Error($"{botName}|{previousMethodName}() {message}");
}
internal static void LogGenericException(Exception exception, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
- while (true) {
- if (exception == null) {
- LogNullError(nameof(exception), botName);
- return;
- }
-
- Log("[!] EXCEPTION: " + previousMethodName + "() <" + botName + "> " + exception.Message + Environment.NewLine + "StackTrace:" + Environment.NewLine + exception.StackTrace);
- if (exception.InnerException != null) {
- exception = exception.InnerException;
- continue;
- }
-
- break;
+ if (exception == null) {
+ LogNullError(nameof(exception), botName);
+ return;
}
+
+ Logger.Error(exception, $"{botName}|{previousMethodName}()");
}
internal static void LogGenericWarning(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
@@ -96,7 +106,7 @@ namespace ArchiSteamFarm {
return;
}
- Log("[!] WARNING: " + previousMethodName + "() <" + botName + "> " + message);
+ Logger.Warn($"{botName}|{previousMethodName}() {message}");
}
internal static void LogGenericInfo(string message, string botName = "Main", [CallerMemberName] string previousMethodName = null) {
@@ -105,20 +115,15 @@ namespace ArchiSteamFarm {
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) {
- while (true) {
- if (string.IsNullOrEmpty(nullObjectName)) {
- nullObjectName = nameof(nullObjectName);
- continue;
- }
-
- LogGenericError(nullObjectName + " is null!", botName, previousMethodName);
- break;
+ if (string.IsNullOrEmpty(nullObjectName)) {
+ return;
}
+
+ Logger.Error($"{botName}|{previousMethodName}() {nullObjectName} is null!");
}
[Conditional("DEBUG")]
@@ -129,42 +134,7 @@ namespace ArchiSteamFarm {
return;
}
- Log("[#] DEBUG: " + previousMethodName + "() <" + botName + "> " + 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);
- }
- }
+ Logger.Debug($"{botName}|{previousMethodName}() {message}");
}
}
}
diff --git a/ArchiSteamFarm/Program.cs b/ArchiSteamFarm/Program.cs
index b80a5a0ac..faf73ad97 100644
--- a/ArchiSteamFarm/Program.cs
+++ b/ArchiSteamFarm/Program.cs
@@ -77,9 +77,9 @@ namespace ArchiSteamFarm {
private static readonly string ExecutableDirectory = Path.GetDirectoryName(ExecutableFile);
private static readonly WCF WCF = new WCF();
+ internal static bool IsRunningAsService { get; private set; }
internal static GlobalConfig GlobalConfig { get; private set; }
internal static GlobalDatabase GlobalDatabase { get; private set; }
- internal static bool ConsoleIsBusy { get; private set; }
private static Timer AutoUpdatesTimer;
private static EMode Mode = EMode.Normal;
@@ -286,7 +286,7 @@ namespace ArchiSteamFarm {
string result;
lock (ConsoleLock) {
- ConsoleIsBusy = true;
+ Logging.OnUserInputStart();
switch (userInputType) {
case EUserInputType.DeviceID:
Console.Write("<" + botName + "> Please enter your Device ID (including \"android:\"): ");
@@ -330,7 +330,7 @@ namespace ArchiSteamFarm {
Console.Clear(); // For security purposes
}
- ConsoleIsBusy = false;
+ Logging.OnUserInputEnd();
}
return !string.IsNullOrEmpty(result) ? result.Trim() : null;
@@ -520,6 +520,7 @@ namespace ArchiSteamFarm {
foreach (string botName in Directory.EnumerateFiles(ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) {
switch (botName) {
case ASF:
+ case "Main":
case "example":
case "minimal":
continue;
@@ -553,6 +554,7 @@ namespace ArchiSteamFarm {
Exit();
} else {
// Service
+ IsRunningAsService = true;
using (Service service = new Service()) {
ServiceBase.Run(service);
}
diff --git a/ArchiSteamFarm/packages.config b/ArchiSteamFarm/packages.config
index a866853fd..45c0b7174 100644
--- a/ArchiSteamFarm/packages.config
+++ b/ArchiSteamFarm/packages.config
@@ -4,6 +4,7 @@
+
\ No newline at end of file
diff --git a/ConfigGenerator/MainForm.cs b/ConfigGenerator/MainForm.cs
index 9b7331651..bb5048495 100644
--- a/ConfigGenerator/MainForm.cs
+++ b/ConfigGenerator/MainForm.cs
@@ -60,6 +60,7 @@ namespace ConfigGenerator {
string botName = Path.GetFileNameWithoutExtension(configFile);
switch (botName) {
case Program.ASF:
+ case "Main":
case "example":
case "minimal":
continue;
@@ -155,6 +156,20 @@ namespace ConfigGenerator {
// Get rid of any potential whitespaces in bot name
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))) {
Logging.LogGenericErrorWithoutStacktrace("Bot with such name exists already!");
return;
diff --git a/packages/NLog.4.4.0-beta13/NLog.4.4.0-beta13.nupkg b/packages/NLog.4.4.0-beta13/NLog.4.4.0-beta13.nupkg
new file mode 100644
index 000000000..508520f44
Binary files /dev/null and b/packages/NLog.4.4.0-beta13/NLog.4.4.0-beta13.nupkg differ
diff --git a/packages/NLog.4.4.0-beta13/lib/net35/NLog.dll b/packages/NLog.4.4.0-beta13/lib/net35/NLog.dll
new file mode 100644
index 000000000..bea438f33
Binary files /dev/null and b/packages/NLog.4.4.0-beta13/lib/net35/NLog.dll differ
diff --git a/packages/NLog.4.4.0-beta13/lib/net40/NLog.dll b/packages/NLog.4.4.0-beta13/lib/net40/NLog.dll
new file mode 100644
index 000000000..64310c8df
Binary files /dev/null and b/packages/NLog.4.4.0-beta13/lib/net40/NLog.dll differ
diff --git a/packages/NLog.4.4.0-beta13/lib/net45/NLog.dll b/packages/NLog.4.4.0-beta13/lib/net45/NLog.dll
new file mode 100644
index 000000000..9e425baf1
Binary files /dev/null and b/packages/NLog.4.4.0-beta13/lib/net45/NLog.dll differ
diff --git a/packages/NLog.4.4.0-beta13/lib/netstandard1.3/NLog.dll b/packages/NLog.4.4.0-beta13/lib/netstandard1.3/NLog.dll
new file mode 100644
index 000000000..3d5a0316a
Binary files /dev/null and b/packages/NLog.4.4.0-beta13/lib/netstandard1.3/NLog.dll differ
diff --git a/packages/NLog.4.4.0-beta13/lib/netstandard1.5/NLog.dll b/packages/NLog.4.4.0-beta13/lib/netstandard1.5/NLog.dll
new file mode 100644
index 000000000..5d5ee3721
Binary files /dev/null and b/packages/NLog.4.4.0-beta13/lib/netstandard1.5/NLog.dll differ
diff --git a/packages/NLog.4.4.0-beta13/lib/sl40/NLog.dll b/packages/NLog.4.4.0-beta13/lib/sl40/NLog.dll
new file mode 100644
index 000000000..f65a9fce8
Binary files /dev/null and b/packages/NLog.4.4.0-beta13/lib/sl40/NLog.dll differ
diff --git a/packages/NLog.4.4.0-beta13/lib/sl50/NLog.dll b/packages/NLog.4.4.0-beta13/lib/sl50/NLog.dll
new file mode 100644
index 000000000..75a6555ca
Binary files /dev/null and b/packages/NLog.4.4.0-beta13/lib/sl50/NLog.dll differ
diff --git a/packages/NLog.4.4.0-beta13/lib/wp80/NLog.dll b/packages/NLog.4.4.0-beta13/lib/wp80/NLog.dll
new file mode 100644
index 000000000..64bc29184
Binary files /dev/null and b/packages/NLog.4.4.0-beta13/lib/wp80/NLog.dll differ