Logging Enhancements (#1521)

* Recreated Kavita Logging with Serilog instead of Default. This needs to be move out of the appsettings now, to allow auto updater to patch.

* Refactored the code to be completely configured via Code rather than appsettings.json. This is a required step for Auto Updating.

* Added in the ability to send logs directly to the UI only for users on the log route. Stopping implementation as Alerts page will handle the rest of the implementation.

* Fixed up the backup service to not rely on Config from appsettings.json

* Tweaked the Logging levels available

* Moved everything over to File-scoped namespaces

* Moved everything over to File-scoped namespaces

* Code cleanup, removed an old migration and changed so debug logging doesn't print sensitive db data

* Removed dead code
This commit is contained in:
Joseph Milazzo 2022-09-12 19:25:48 -05:00 committed by GitHub
parent 9f715cc35f
commit d1a14f7e68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
212 changed files with 16599 additions and 16834 deletions

View file

@ -4,80 +4,79 @@ using API.Entities;
using API.Entities.Enums;
using API.Entities.Metadata;
namespace API.Tests.Helpers
namespace API.Tests.Helpers;
/// <summary>
/// Used to help quickly create DB entities for Unit Testing
/// </summary>
public static class EntityFactory
{
/// <summary>
/// Used to help quickly create DB entities for Unit Testing
/// </summary>
public static class EntityFactory
public static Series CreateSeries(string name)
{
public static Series CreateSeries(string name)
return new Series()
{
return new Series()
{
Name = name,
SortName = name,
LocalizedName = name,
NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize(name),
Volumes = new List<Volume>(),
Metadata = new SeriesMetadata()
};
}
Name = name,
SortName = name,
LocalizedName = name,
NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize(name),
Volumes = new List<Volume>(),
Metadata = new SeriesMetadata()
};
}
public static Volume CreateVolume(string volumeNumber, List<Chapter> chapters = null)
public static Volume CreateVolume(string volumeNumber, List<Chapter> chapters = null)
{
var chaps = chapters ?? new List<Chapter>();
var pages = chaps.Count > 0 ? chaps.Max(c => c.Pages) : 0;
return new Volume()
{
var chaps = chapters ?? new List<Chapter>();
var pages = chaps.Count > 0 ? chaps.Max(c => c.Pages) : 0;
return new Volume()
{
Name = volumeNumber,
Number = (int) API.Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(volumeNumber),
Pages = pages,
Chapters = chaps
};
}
Name = volumeNumber,
Number = (int) API.Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(volumeNumber),
Pages = pages,
Chapters = chaps
};
}
public static Chapter CreateChapter(string range, bool isSpecial, List<MangaFile> files = null, int pageCount = 0)
public static Chapter CreateChapter(string range, bool isSpecial, List<MangaFile> files = null, int pageCount = 0)
{
return new Chapter()
{
return new Chapter()
{
IsSpecial = isSpecial,
Range = range,
Number = API.Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(range) + string.Empty,
Files = files ?? new List<MangaFile>(),
Pages = pageCount,
IsSpecial = isSpecial,
Range = range,
Number = API.Services.Tasks.Scanner.Parser.Parser.MinNumberFromRange(range) + string.Empty,
Files = files ?? new List<MangaFile>(),
Pages = pageCount,
};
}
};
}
public static MangaFile CreateMangaFile(string filename, MangaFormat format, int pages)
public static MangaFile CreateMangaFile(string filename, MangaFormat format, int pages)
{
return new MangaFile()
{
return new MangaFile()
{
FilePath = filename,
Format = format,
Pages = pages
};
}
FilePath = filename,
Format = format,
Pages = pages
};
}
public static SeriesMetadata CreateSeriesMetadata(ICollection<CollectionTag> collectionTags)
public static SeriesMetadata CreateSeriesMetadata(ICollection<CollectionTag> collectionTags)
{
return new SeriesMetadata()
{
return new SeriesMetadata()
{
CollectionTags = collectionTags
};
}
CollectionTags = collectionTags
};
}
public static CollectionTag CreateCollectionTag(int id, string title, string summary, bool promoted)
public static CollectionTag CreateCollectionTag(int id, string title, string summary, bool promoted)
{
return new CollectionTag()
{
return new CollectionTag()
{
Id = id,
NormalizedTitle = API.Services.Tasks.Scanner.Parser.Parser.Normalize(title).ToUpper(),
Title = title,
Summary = summary,
Promoted = promoted
};
}
Id = id,
NormalizedTitle = API.Services.Tasks.Scanner.Parser.Parser.Normalize(title).ToUpper(),
Title = title,
Summary = summary,
Promoted = promoted
};
}
}

View file

@ -6,68 +6,67 @@ using API.Entities.Enums;
using API.Parser;
using API.Services.Tasks.Scanner;
namespace API.Tests.Helpers
namespace API.Tests.Helpers;
public static class ParserInfoFactory
{
public static class ParserInfoFactory
public static ParserInfo CreateParsedInfo(string series, string volumes, string chapters, string filename, bool isSpecial)
{
public static ParserInfo CreateParsedInfo(string series, string volumes, string chapters, string filename, bool isSpecial)
return new ParserInfo()
{
return new ParserInfo()
{
Chapters = chapters,
Edition = "",
Format = MangaFormat.Archive,
FullFilePath = Path.Join(@"/manga/", filename),
Filename = filename,
IsSpecial = isSpecial,
Title = Path.GetFileNameWithoutExtension(filename),
Series = series,
Volumes = volumes
};
}
Chapters = chapters,
Edition = "",
Format = MangaFormat.Archive,
FullFilePath = Path.Join(@"/manga/", filename),
Filename = filename,
IsSpecial = isSpecial,
Title = Path.GetFileNameWithoutExtension(filename),
Series = series,
Volumes = volumes
};
}
public static void AddToParsedInfo(IDictionary<ParsedSeries, IList<ParserInfo>> collectedSeries, ParserInfo info)
public static void AddToParsedInfo(IDictionary<ParsedSeries, IList<ParserInfo>> collectedSeries, ParserInfo info)
{
var existingKey = collectedSeries.Keys.FirstOrDefault(ps =>
ps.Format == info.Format && ps.NormalizedName == API.Services.Tasks.Scanner.Parser.Parser.Normalize(info.Series));
existingKey ??= new ParsedSeries()
{
var existingKey = collectedSeries.Keys.FirstOrDefault(ps =>
ps.Format == info.Format && ps.NormalizedName == API.Services.Tasks.Scanner.Parser.Parser.Normalize(info.Series));
existingKey ??= new ParsedSeries()
Format = info.Format,
Name = info.Series,
NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize(info.Series)
};
if (collectedSeries.GetType() == typeof(ConcurrentDictionary<,>))
{
((ConcurrentDictionary<ParsedSeries, IList<ParserInfo>>) collectedSeries).AddOrUpdate(existingKey, new List<ParserInfo>() {info}, (_, oldValue) =>
{
Format = info.Format,
Name = info.Series,
NormalizedName = API.Services.Tasks.Scanner.Parser.Parser.Normalize(info.Series)
};
if (collectedSeries.GetType() == typeof(ConcurrentDictionary<,>))
{
((ConcurrentDictionary<ParsedSeries, IList<ParserInfo>>) collectedSeries).AddOrUpdate(existingKey, new List<ParserInfo>() {info}, (_, oldValue) =>
oldValue ??= new List<ParserInfo>();
if (!oldValue.Contains(info))
{
oldValue ??= new List<ParserInfo>();
if (!oldValue.Contains(info))
{
oldValue.Add(info);
}
oldValue.Add(info);
}
return oldValue;
});
return oldValue;
});
}
else
{
if (!collectedSeries.ContainsKey(existingKey))
{
collectedSeries.Add(existingKey, new List<ParserInfo>() {info});
}
else
{
if (!collectedSeries.ContainsKey(existingKey))
var list = collectedSeries[existingKey];
if (!list.Contains(info))
{
collectedSeries.Add(existingKey, new List<ParserInfo>() {info});
}
else
{
var list = collectedSeries[existingKey];
if (!list.Contains(info))
{
list.Add(info);
}
collectedSeries[existingKey] = list;
list.Add(info);
}
collectedSeries[existingKey] = list;
}
}
}
}

View file

@ -1,53 +1,52 @@
using System.IO;
namespace API.Tests.Helpers
namespace API.Tests.Helpers;
/// <summary>
/// Given a -testcase.txt file, will generate a folder with fake archive or book files. These files are just renamed txt files.
/// <remarks>This currently is broken - you cannot create files from a unit test it seems</remarks>
/// </summary>
public static class TestCaseGenerator
{
/// <summary>
/// Given a -testcase.txt file, will generate a folder with fake archive or book files. These files are just renamed txt files.
/// <remarks>This currently is broken - you cannot create files from a unit test it seems</remarks>
/// </summary>
public static class TestCaseGenerator
public static string GenerateFiles(string directory, string fileToExpand)
{
public static string GenerateFiles(string directory, string fileToExpand)
//var files = Directory.GetFiles(directory, fileToExpand);
var file = new FileInfo(fileToExpand);
if (!file.Exists && file.Name.EndsWith("-testcase.txt")) return string.Empty;
var baseDirectory = TestCaseGenerator.CreateTestBase(fileToExpand, directory);
var filesToCreate = File.ReadLines(file.FullName);
foreach (var fileToCreate in filesToCreate)
{
//var files = Directory.GetFiles(directory, fileToExpand);
var file = new FileInfo(fileToExpand);
if (!file.Exists && file.Name.EndsWith("-testcase.txt")) return string.Empty;
var baseDirectory = TestCaseGenerator.CreateTestBase(fileToExpand, directory);
var filesToCreate = File.ReadLines(file.FullName);
foreach (var fileToCreate in filesToCreate)
{
// var folders = DirectoryService.GetFoldersTillRoot(directory, fileToCreate);
// foreach (var VARIABLE in COLLECTION)
// {
//
// }
File.Create(fileToCreate);
}
return baseDirectory;
// var folders = DirectoryService.GetFoldersTillRoot(directory, fileToCreate);
// foreach (var VARIABLE in COLLECTION)
// {
//
// }
File.Create(fileToCreate);
}
/// <summary>
/// Creates and returns a new base directory for data creation for a given testcase
/// </summary>
/// <param name="file"></param>
/// <param name="rootDirectory"></param>
/// <returns></returns>
private static string CreateTestBase(string file, string rootDirectory)
{
var baseDir = file.Split("-testcase.txt")[0];
var newDirectory = Path.Join(rootDirectory, baseDir);
if (!Directory.Exists(newDirectory))
{
new DirectoryInfo(newDirectory).Create();
}
return newDirectory;
}
return baseDirectory;
}
}
/// <summary>
/// Creates and returns a new base directory for data creation for a given testcase
/// </summary>
/// <param name="file"></param>
/// <param name="rootDirectory"></param>
/// <returns></returns>
private static string CreateTestBase(string file, string rootDirectory)
{
var baseDir = file.Split("-testcase.txt")[0];
var newDirectory = Path.Join(rootDirectory, baseDir);
if (!Directory.Exists(newDirectory))
{
new DirectoryInfo(newDirectory).Create();
}
return newDirectory;
}
}