Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Knossos.NET/Classes/Knossos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,8 @@ public async static void LoadBasePath(bool isQuickLaunch = false)
{
await FolderSearchRecursive(globalSettings.basePath, isQuickLaunch).ConfigureAwait(false);

Log.Add(Log.LogSeverity.Information, "Knossos.LoadBasePath()", "Loaded: " + installedMods.Count() +" installed mods or tcs and " + engineBuilds.Count() + " engine builds." );

if (!isQuickLaunch)
{
//Sort/Re-sort installed mods
Expand Down
111 changes: 62 additions & 49 deletions Knossos.NET/Models/Log.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using Avalonia.Threading;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

Expand All @@ -19,7 +21,64 @@ public enum LogSeverity
Error
}

public static string LogFilePath = KnUtils.GetKnossosDataFolderPath() + Path.DirectorySeparatorChar + "Knossos.log";
private class LogEntry
{
string logString = string.Empty;
bool writeToFile = false;

public LogEntry(LogSeverity logSeverity, string from, string data)
{
logString = DateTime.Now.ToString() + " - *" + logSeverity.ToString() + "* : (" + from + ") " + data;
if (Knossos.globalSettings.enableLogFile && (int)logSeverity >= Knossos.globalSettings.logLevel)
{
writeToFile = true;
}
Task.Factory.StartNew(() => {
ProcessLogEntry();
});
}

private async void ProcessLogEntry()
{
while (!queuedLogs.Any() || queuedLogs.Peek() != this)
await Task.Delay(10);
WriteToConsole();
if (writeToFile)
WriteToFile();
queuedLogs.Dequeue();
}

private void WriteToConsole()
{
Log.WriteToConsole(logString);
}

private void WriteToFile(int attempt = 1)
{
try
{
using (var writer = new StreamWriter(LogFilePath, true))
{
writer.WriteLine(logString, Encoding.UTF8);
}
}catch(Exception ex)
{
if(attempt < maxFileWriteAttempts)
{
attempt++;
WriteToFile(attempt);
}
else
{
Log.WriteToConsole("Failed to write to the logfile, reason: " + ex.ToString() + " \nFilePath:"+ LogFilePath);
}
}
}
}

public static readonly string LogFilePath = KnUtils.GetKnossosDataFolderPath() + Path.DirectorySeparatorChar + "Knossos.log";
private static readonly int maxFileWriteAttempts = 5;
private static Queue<LogEntry> queuedLogs = new Queue<LogEntry>();

/// <summary>
/// Write a log entry to console and file
Expand All @@ -31,28 +90,7 @@ public enum LogSeverity
/// <param name="data"></param>
public static void Add(LogSeverity logSeverity, string from, string data)
{
var logString = DateTime.Now.ToString() + " - *" + logSeverity.ToString() + "* : (" + from + ") " + data;
if (Knossos.globalSettings.enableLogFile && (int)logSeverity >= Knossos.globalSettings.logLevel )
{
Task.Run(async () => {
try
{
if (!Knossos.isKnDataFolderReadOnly)
{
await WaitForFileAccess(LogFilePath);
using (var writer = new StreamWriter(LogFilePath, true))
{
writer.WriteLine(logString, Encoding.UTF8);
}
}
}
catch (Exception ex)
{
WriteToConsole(ex.Message);
}
});
}
WriteToConsole(logString);
queuedLogs.Enqueue(new LogEntry(logSeverity, from, data));
}

/// <summary>
Expand Down Expand Up @@ -83,35 +121,10 @@ public async static void WriteToConsole(string data)
await Dispatcher.UIThread.InvokeAsync(() => Knossos.WriteToUIConsole(data), DispatcherPriority.Background);
if (Debugger.IsAttached)
{
System.Diagnostics.Debug.WriteLine(data);
Debug.WriteLine(data);
}
}
catch { }
}

/// <summary>
/// Wait for the log file being available for write
/// Returns when the file is ready
/// </summary>
/// <param name="filename"></param>
private static async Task WaitForFileAccess(string filename)
{
try
{
if (File.Exists(filename))
{
using (FileStream inputStream = File.Open(filename, FileMode.Open, FileAccess.Read))
{
inputStream.Close();
return;
}
}
}
catch (IOException)
{
await Task.Delay(500);
await WaitForFileAccess(filename);
}
}
}
}
5 changes: 3 additions & 2 deletions Knossos.NET/Models/Nebula.cs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ private static bool IsModUpdate(Mod mod)
cancellationToken = null;
}
GC.Collect();
Log.Add(Log.LogSeverity.Information, "Nebula.InitialRepoLoad()", "Loaded: " + allModsInRepo.Count() + " repo entries. Engine builds: "+ builds.Count() + ", Mods: " + modsByID.Count() + ", TCs: " + modsTcs.Count() + "." );
return modUpdates;
}
catch (TaskCanceledException)
Expand Down Expand Up @@ -1170,7 +1171,7 @@ public static async Task<bool> IsModEditable(string id)
if (reply.Value.mods != null && reply.Value.mods.Any())
{
var ids = reply.Value.mods.Select(x => x.Deserialize<string>()!).ToArray()!;
Log.Add(Log.LogSeverity.Information, "Nebula.GetEditableMods", "Editable mods in Nebula: " + string.Join(", ", ids));
Log.Add(Log.LogSeverity.Information, "Nebula.GetEditableMods", "Editable mod ids in Nebula: " + string.Join(",", ids));
editableIds = ids;
return ids;
}
Expand Down Expand Up @@ -1208,7 +1209,7 @@ public static async Task<bool> IsModEditable(string id)
var mods = reply.Value.mods.Select(x => x.Deserialize<Mod>()!).ToArray()!;
foreach (var mod in mods)
{
Log.Add(Log.LogSeverity.Information, "Nebula.GetPrivateMods", "Private mod in Nebula with access: " + mod);
Log.Add(Log.LogSeverity.Information, "Nebula.GetPrivateMods", mod.ToString());
}
return mods;
}
Expand Down
3 changes: 1 addition & 2 deletions Knossos.NET/ViewModels/Templates/ModCardViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ public ModCardViewModel()

public ModCardViewModel(Mod modJson)
{
Log.Add(Log.LogSeverity.Information, "ModCardViewModel(Constructor)", "Creating mod card for " + modJson.title +" "+ modJson.version);
modJson.ClearUnusedData();
modVersions.Add(modJson);
Name = modJson.title;
Expand Down Expand Up @@ -102,7 +101,7 @@ public void AddModVersion(Mod modJson)
modVersions.Sort((o1, o2) => -SemanticVersion.Compare(o1.version, o2.version));
if (SemanticVersion.Compare(modJson.version, currentVersion) > 0)
{
Log.Add(Log.LogSeverity.Information, "ModCardViewModel.AddModVersion()", "Changing active version for " + modJson.title + " from " + modVersions[activeVersionIndex].version + " to " + modJson.version);
Log.Add(Log.LogSeverity.Information, "ModCardViewModel.AddModVersion()", "Changing active version for " + modJson.title + " from " + currentVersion + " to " + modJson.version);
activeVersionIndex = modVersions.FindIndex((m) => m.version.Equals(modJson.version));
Name = modJson.title;
ModVersion = modJson.version + " (+" + (modVersions.Count - 1) + ")";
Expand Down
1 change: 0 additions & 1 deletion Knossos.NET/ViewModels/Templates/NebulaModCardViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ public NebulaModCardViewModel()

public NebulaModCardViewModel(Mod modJson)
{
Log.Add(Log.LogSeverity.Information, "NebulaModCardViewModel(Constructor)", "Creating mod card for " + modJson);
modJson.ClearUnusedData();
this.modJson = modJson;
//Moved to load when visible only
Expand Down