From c139b8045967b065be7ae1768637aaf3aef56d53 Mon Sep 17 00:00:00 2001 From: Im_Alpha Date: Tue, 4 Jan 2022 13:20:16 -0800 Subject: [PATCH] Moved logging into service layer --- .../Logging/Contracts/ILogger.cs | 16 +++++ .../Logging/Contracts/ILoggerFactory.cs | 16 +++++ .../Logging/Implementations/ConsoleLogger.cs | 16 +++++ .../Logging/Implementations/DBLogger.cs | 24 ++++++++ .../Implementations/DBLoggerFactory.cs | 20 +++++++ .../Logging/Implementations/FileLogger.cs | 24 ++++++++ .../Logging/Implementations/InMemoryLogger.cs | 58 +++++++++++++++++++ .../Logging/Implementations/LogEntry.cs | 53 +++++++++++++++++ .../Logging/Implementations/LoggingManager.cs | 45 ++++++++++++++ 9 files changed, 272 insertions(+) create mode 100644 Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Contracts/ILogger.cs create mode 100644 Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Contracts/ILoggerFactory.cs create mode 100644 Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/ConsoleLogger.cs create mode 100644 Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/DBLogger.cs create mode 100644 Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/DBLoggerFactory.cs create mode 100644 Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/FileLogger.cs create mode 100644 Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/InMemoryLogger.cs create mode 100644 Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/LogEntry.cs create mode 100644 Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/LoggingManager.cs diff --git a/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Contracts/ILogger.cs b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Contracts/ILogger.cs new file mode 100644 index 0000000..9aee5ba --- /dev/null +++ b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Contracts/ILogger.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TeamHobby.HobbyProjectGenerator.Logging +{ + public interface ILogger + { + bool Log(LogEntry log); + + // IList GetAllLogs(); + + } +} diff --git a/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Contracts/ILoggerFactory.cs b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Contracts/ILoggerFactory.cs new file mode 100644 index 0000000..cf0d199 --- /dev/null +++ b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Contracts/ILoggerFactory.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TeamHobby.HobbyProjectGenerator.Logging.Contracts +{ + public interface ILoggerFactory + { + ILogger CreateLogger() + { + return new DBLogger(); + } + } +} diff --git a/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/ConsoleLogger.cs b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/ConsoleLogger.cs new file mode 100644 index 0000000..19d2377 --- /dev/null +++ b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/ConsoleLogger.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TeamHobby.HobbyProjectGenerator.Logging +{ + public class ConsoleLogger : ILogger + { + public bool Log(LogEntry log) + { + return true; + } + } +} diff --git a/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/DBLogger.cs b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/DBLogger.cs new file mode 100644 index 0000000..132ee82 --- /dev/null +++ b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/DBLogger.cs @@ -0,0 +1,24 @@ +using System; + +namespace TeamHobby.HobbyProjectGenerator.Logging +{ + public class DBLogger : ILogger + { + public DBLogger() + { + } + + public IList GetAllLogs() + { + throw new NotImplementedException(); + } + + public bool Log(LogEntry log) + { + throw new NotImplementedException(); + } + + + } + +} \ No newline at end of file diff --git a/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/DBLoggerFactory.cs b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/DBLoggerFactory.cs new file mode 100644 index 0000000..f790cbb --- /dev/null +++ b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/DBLoggerFactory.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TeamHobby.HobbyProjectGenerator.Logging.Contracts; + +namespace TeamHobby.HobbyProjectGenerator.Logging.Implementations +{ + public class DBLoggerFactory : ILoggerFactory + { + public DBLoggerFactory() + { + } + public ILogger CreateLogger() + { + return new DBLogger(); + } + } +} diff --git a/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/FileLogger.cs b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/FileLogger.cs new file mode 100644 index 0000000..6c561b1 --- /dev/null +++ b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/FileLogger.cs @@ -0,0 +1,24 @@ +using System; +using TeamHobby.HobbyProjectGenerator.Logging.Contracts; + +namespace TeamHobby.HobbyProjectGenerator.Logging +{ + public class FileLogger : ILogger + { + public FileLogger() + { + } + + public IList GetAllLogs() + { + throw new NotImplementedException(); + } + + public bool Log(LogEntry log) + { + throw new NotImplementedException(); + } + + } + +} diff --git a/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/InMemoryLogger.cs b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/InMemoryLogger.cs new file mode 100644 index 0000000..10cbf74 --- /dev/null +++ b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/InMemoryLogger.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +namespace TeamHobby.HobbyProjectGenerator.Logging +{ + // implementation of ILogger that stores logs as they initialize + public class InMemoryLogger : ILogger + { + // make readonly to prevent it from being changed somewhere other than in the constructor + private readonly IList _logStore; + + public InMemoryLogger() + { + // list of current logs + _logStore = new List(); + } + + public InMemoryLogger(IList logStore) + { + _logStore = logStore; + } + + public bool Log(LogEntry entry) + { + if (entry is null) + { + throw new ArgumentNullException(nameof(entry)); + } + + try + { + // string interpolation to add UTC timestamp to log description + //_logStore.Add($"{DateTime.UtcNow}-> {description}"); + return true; + } + catch + { + return false; + } + } + public IList GetAllLogs() + { + return _logStore; + } + + + public override bool Equals(object? obj) + { + return obj is InMemoryLogger logger && + EqualityComparer>.Default.Equals(_logStore, logger._logStore); + } + + public override int GetHashCode() + { + return HashCode.Combine(_logStore); + } + } + +} diff --git a/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/LogEntry.cs b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/LogEntry.cs new file mode 100644 index 0000000..6fa0966 --- /dev/null +++ b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/LogEntry.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TeamHobby.HobbyProjectGenerator.Logging +{ + public enum LogLevel + { + Info, Debug, Warning, Error + } + + public enum LogCategory + { + View, Business, Server, Data, Datastore + } + + // LogEntry is a record type with init properties for each field + // ensures that log entries are immutable after initialization + public record LogEntry + { + public LogLevel level { get; init; } + public LogCategory category { get; init; } + public string user { get; init; } + public string description { get; init; } + public DateTime timestamp { get; init; } + + + // Constructor requireing only the description as an arg + // Assigns default values for LogLevel (Info), LogCategory (Server), user ("System"), and the UTC time at initialization for timestamp + public LogEntry(string description) + { + this.level = LogLevel.Info; + this.category = LogCategory.Server; + this.user = "System"; + this.description = description; + this.timestamp = DateTime.UtcNow; + } + // Constructor with args for all fields except timestamp + // timestamp is always set to the UTC time at the time of initialization + public LogEntry(LogLevel level, string user, LogCategory category, string description) + { + this.level = level; + this.category = category; + this.user = user; + this.description = description; + this.timestamp = DateTime.UtcNow; + } + + + } +} \ No newline at end of file diff --git a/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/LoggingManager.cs b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/LoggingManager.cs new file mode 100644 index 0000000..2f45c93 --- /dev/null +++ b/Source Code/TeamHobby.HobbyProjectGenerator/TeamHobby.HobbyProjectGenerator.ServiceLayer/Logging/Implementations/LoggingManager.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TeamHobby.HobbyProjectGenerator.DataAccessLayer; +using TeamHobby.HobbyProjectGenerator.Logging.Contracts; +using TeamHobby.HobbyProjectGenerator.Logging.Implementations; + + +namespace TeamHobby.HobbyProjectGenerator.Logging +{ + internal class LoggingManager + { + private readonly IDataSource _conn; + private readonly ILogger _logger; + private readonly ILoggerFactory _factory; + private readonly LogEntry _logEntry; + + // Both Constructors take an IDataSource arg to make logging extensible to future data sources + // first constructor has no additional args - defaults to using the DBFactiry implementation + public LoggingManager(IDataSource dataSource) + { + _conn = dataSource; + _factory = new DBLoggerFactory(); + _logger = _factory.CreateLogger(); + } + // second constructor takes an additional ILoggerFactory arg - allows for extensible logger types + public LoggingManager(IDataSource dataSource, ILoggerFactory factory) + { + _conn = dataSource; + _factory = factory; + _logger = _factory.CreateLogger(); + + } + + public void Process() + { + _logger.Log(_logEntry); + } + + + + } +}