Merge branch 'newMain'
This commit is contained in:
commit
271f2df7f9
@ -3,12 +3,18 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TeamHobby.HobbyProjectGenerator.Logging.Contracts;
|
||||
|
||||
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
|
||||
{
|
||||
public interface ILogger
|
||||
public interface ILogger
|
||||
{
|
||||
bool Log(LogEntry log);
|
||||
// private IDataSource<string> _datasource = T;
|
||||
// attempts to connect to the data source provided by the type T
|
||||
// returns true if the connection is successful
|
||||
|
||||
// public bool Connect();
|
||||
public bool Log(LogEntry Log);
|
||||
|
||||
// IList<string> GetAllLogs();
|
||||
|
||||
|
||||
@ -8,9 +8,9 @@ namespace TeamHobby.HobbyProjectGenerator.ServiceLayer.Contracts
|
||||
{
|
||||
public interface ILoggerFactory
|
||||
{
|
||||
ILogger CreateLogger()
|
||||
{
|
||||
return new DBLogger();
|
||||
}
|
||||
|
||||
ILogger CreateLogger();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TeamHobby.HobbyProjectGenerator.Logging.Contracts;
|
||||
|
||||
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
|
||||
{
|
||||
|
||||
@ -1,24 +1,200 @@
|
||||
using System;
|
||||
using System.Data.Odbc;
|
||||
using TeamHobby.HobbyProjectGenerator.DataAccessLayer;
|
||||
using TeamHobby.HobbyProjectGenerator.Logging.Contracts;
|
||||
|
||||
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
|
||||
{
|
||||
public class DBLogger : ILogger
|
||||
public class DBLogger : ILogger
|
||||
{
|
||||
private SqlDAO _datasource;
|
||||
public DBLogger()
|
||||
{
|
||||
}
|
||||
|
||||
public IList<string> GetAllLogs()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// SELECT * FROM log
|
||||
// public IList<LogEntry> GetAllLogs()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
//INSERT INTO log(LvName, catName, userOP, logMessage) VALUES ('Debug','Data', 'SYSTEM', 'testing insert method')
|
||||
|
||||
// public bool Connect(SqlDAO logDatabase) {
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
public bool IsActive() {
|
||||
string dbInfo = "DRIVER={MariaDB ODBC 3.1 Driver};" +
|
||||
"TCPIP=1;" +
|
||||
"SERVER=ocalhost;" +
|
||||
"DATABASE=hbby;" +
|
||||
"UID=ot;" + // omit password to force SQLException for incorrect passeword
|
||||
"PASSWORD=wrong" +
|
||||
"OPTION=3";
|
||||
// bool isActive = true;
|
||||
OdbcConnection active = new OdbcConnection(dbInfo);
|
||||
try {
|
||||
active.Open();
|
||||
return false;
|
||||
}
|
||||
catch (OdbcException ex) {
|
||||
// Console.WriteLine(ex.Message);
|
||||
if (ex.ErrorCode == -2146232009 ) {
|
||||
//Console.WriteLine(ex.ErrorCode);
|
||||
Console.WriteLine("Database is active");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
Console.WriteLine("Database is inactive");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// Console.WriteLine("closed1");
|
||||
active.Close();
|
||||
}
|
||||
// return false;
|
||||
}
|
||||
|
||||
public bool IsAccessible() {
|
||||
string dbInfo = "DRIVER={MariaDB ODBC 3.1 Driver};" +
|
||||
"TCPIP=1;" +
|
||||
"SERVER=localhost;" +
|
||||
"DATABASE=hobby;" +
|
||||
"UID=root;" +
|
||||
"PASSWORD=Teamhobby;" +
|
||||
"OPTION=3";
|
||||
OdbcConnection access = new OdbcConnection(dbInfo);
|
||||
try {
|
||||
access.Open();
|
||||
Console.WriteLine("Database is active and accessible by the system");
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
Console.WriteLine("Database is active but inaccessible to the system at this time.");
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
access.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasCapacity() {
|
||||
string dbInfo = "DRIVER={MariaDB ODBC 3.1 Driver};" +
|
||||
"TCPIP=1;" +
|
||||
"SERVER=localhost;" +
|
||||
"DATABASE=hobby;" +
|
||||
"UID=root;" +
|
||||
"PASSWORD=Teamhobby;" +
|
||||
"OPTION=3";
|
||||
OdbcConnection conn = new OdbcConnection(dbInfo);
|
||||
|
||||
// get the current capacity of the database in MB using the query:
|
||||
// SELECT SUM(storage.MB) as CURRENT_CAPACITY_MB FROM (SELECT table_schema as name, ROUND(SUM(data_length + index_length)/1024/1024,1) as MB FROM information_schema.tables GROUP BY table_schema) as storage;
|
||||
|
||||
string sqlCurrentCap = $"SELECT SUM(storage.mb) as currentCap FROM (SELECT table_schema as name, ROUND(SUM(data_length + index_length)/1024/1024,1) as mb FROM information_schema.tables GROUP BY table_schema) as storage;";
|
||||
|
||||
// get the max capacity in GB; too big to be shown as MB
|
||||
string sqlMaxCap = $"SELECT SUM(storage.mb) as maxCap FROM (SELECT table_schema as name, ROUND(SUM(max_data_length + max_index_length)/1024,1) as mb FROM information_schema.tables GROUP BY table_schema) as storage;";
|
||||
|
||||
// query the data base to get currentCap; the current storage capacity of the system's database (in megabytes)
|
||||
conn.Open();
|
||||
OdbcCommand command1 = new OdbcCommand(sqlCurrentCap, conn);
|
||||
OdbcDataReader result1 = command1.ExecuteReader();
|
||||
double currentCap = 0;
|
||||
while (result1.Read()) {
|
||||
//Console.WriteLine(result1[0].GetType());
|
||||
//Console.WriteLine("currentCap = {0}", result1[0]);
|
||||
currentCap = result1.GetDouble(0);
|
||||
}
|
||||
|
||||
// Console.WriteLine(currentCap);
|
||||
//float currentCap1 = (float) currentCap;
|
||||
result1.Close();
|
||||
command1.Dispose();
|
||||
conn.Close();
|
||||
// Console.WriteLine("close conn");
|
||||
|
||||
// query the data base again to get maxCap; the maximum possible storage capacity of the system's database (in megabytes)
|
||||
conn.Open();
|
||||
// Console.WriteLine("open conn");
|
||||
OdbcCommand command2 = new OdbcCommand(sqlMaxCap, conn);
|
||||
OdbcDataReader result2 = command2.ExecuteReader();
|
||||
// Console.WriteLine("open reader 1");
|
||||
double maxCap = 0;
|
||||
try {
|
||||
while (result2.Read()) {
|
||||
//Console.WriteLine(result2[0].GetType());
|
||||
maxCap = result2.GetDouble(0);
|
||||
// Console.WriteLine("maxCap = {0}", result2[0]);
|
||||
}
|
||||
// compare currentCap to maxCap
|
||||
// return true if there is at least 1MB of free space available
|
||||
// decrement max by 1 MB to allow for any required space from new logs
|
||||
if ( (currentCap * 1024) < (maxCap - 1024) ) {
|
||||
// Console.WriteLine(maxCap);
|
||||
Console.WriteLine("Database has sufficient storage capacity to be written to at this time.\n Current Capacity: {0} MB\n Max Capacity: {1} MB\n", currentCap, maxCap);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Console.WriteLine("Insufficient Storage Capacity to log entry to database.\n Current Capacity: {0} MB \n Max Capacity: {1} MB \n", currentCap, maxCap);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
result2.Close();
|
||||
command2.Dispose();
|
||||
conn.Close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Console.WriteLine("close conn 2");
|
||||
//Console.WriteLine(maxCap);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public bool Log(LogEntry log)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
log.ShowLog();
|
||||
|
||||
//bool status = HasCapacity();
|
||||
if ( (IsActive() == false || IsAccessible() == false) || (HasCapacity() == false) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
else {
|
||||
// SqlDAO sqlDS = (SqlDAO)_datasource;
|
||||
string dbInfo = "DRIVER={MariaDB ODBC 3.1 Driver};" +
|
||||
"TCPIP=1;" +
|
||||
"SERVER=localhost;" +
|
||||
"DATABASE=hobby;" +
|
||||
"UID=root;" +
|
||||
"PASSWORD=Teamhobby;" +
|
||||
"OPTION=3";
|
||||
_datasource = new SqlDAO(dbInfo);
|
||||
|
||||
//bool storage = HasCapacity();
|
||||
try
|
||||
{
|
||||
// once connection is confirmed, try inserting the log via SQL statements
|
||||
string sqlLog = $"INSERT INTO log (Lvname, catName, userOP, logMessage) VALUES ('{log.GetLevel()}','{log.GetCategory()}', " + $"'{log.GetUser()}', '{log.GetDescription()}');";
|
||||
|
||||
bool insertNewLog = _datasource.WriteData(sqlLog);
|
||||
//Console.WriteLine($"Logging Succeeded: The following entry was written to the database: {log}");
|
||||
// Console.WriteLine(_datasource.ReadData($"SELECT * FROM log;"));
|
||||
return insertNewLog;
|
||||
}
|
||||
// if failed, that means the connection was a sucess but actually writing to the database failed
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Failed to write log to database; likely due to error in SQL syntax");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -11,9 +11,10 @@ namespace TeamHobby.HobbyProjectGenerator.ServiceLayer.Implementations
|
||||
{
|
||||
public DBLoggerFactory()
|
||||
{
|
||||
//this._logDatabase = logDatabase;
|
||||
}
|
||||
public ILogger CreateLogger()
|
||||
{
|
||||
|
||||
public ILogger CreateLogger() {
|
||||
return new DBLogger();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using TeamHobby.HobbyProjectGenerator.Logging.Contracts;
|
||||
using TeamHobby.HobbyProjectGenerator.ServiceLayer.Contracts;
|
||||
|
||||
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
|
||||
|
||||
@ -1,59 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
|
||||
{
|
||||
// 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<string> _logStore;
|
||||
|
||||
public InMemoryLogger()
|
||||
{
|
||||
// list of current logs
|
||||
_logStore = new List<string>();
|
||||
}
|
||||
|
||||
public InMemoryLogger(IList<string> 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<string> GetAllLogs()
|
||||
{
|
||||
return _logStore;
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is InMemoryLogger logger &&
|
||||
EqualityComparer<IList<string>>.Default.Equals(_logStore, logger._logStore);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(_logStore);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -4,9 +4,8 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
|
||||
{
|
||||
public enum LogLevel
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
Info, Debug, Warning, Error
|
||||
}
|
||||
@ -16,38 +15,60 @@ namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
|
||||
View, Business, Server, Data, Datastore
|
||||
}
|
||||
|
||||
|
||||
namespace TeamHobby.HobbyProjectGenerator.Logging.Contracts
|
||||
{
|
||||
// LogEntry is a record type with init properties for each field
|
||||
// ensures that log entries are immutable after initialization
|
||||
// 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; }
|
||||
private LogLevel _level { get; init; }
|
||||
private LogCategory _category { get; init; }
|
||||
private string _user { get; init; }
|
||||
private string _description { 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)
|
||||
public LogEntry(LogLevel level, LogCategory category, string user, string description)
|
||||
{
|
||||
this.level = level;
|
||||
this.category = category;
|
||||
this.user = user;
|
||||
this.description = description;
|
||||
this.timestamp = DateTime.UtcNow;
|
||||
this._level = level;
|
||||
this._category = category;
|
||||
this._user = user;
|
||||
this._description = description;
|
||||
}
|
||||
|
||||
// Constructor requiring 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.Debug;
|
||||
// this._category = LogCategory.Server;
|
||||
// this._user = "SYSTEM";
|
||||
// this._description = description;
|
||||
// }
|
||||
|
||||
public LogLevel GetLevel() {
|
||||
return this._level;
|
||||
}
|
||||
|
||||
public LogCategory GetCategory() {
|
||||
return this._category;
|
||||
}
|
||||
|
||||
public string GetUser() {
|
||||
return this._user;
|
||||
}
|
||||
|
||||
public string GetDescription() {
|
||||
return this._description;
|
||||
}
|
||||
|
||||
public void ShowLog() {
|
||||
Console.WriteLine("Timestamp: {0} | Level: {1}, | Category: {2}, | User: {3}, | Description: '{4}' ", DateTime.Now, this._level.ToString(),this._category.ToString(), this._user, this._description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -4,42 +4,88 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TeamHobby.HobbyProjectGenerator.DataAccessLayer;
|
||||
using TeamHobby.HobbyProjectGenerator.Logging.Contracts;
|
||||
using TeamHobby.HobbyProjectGenerator.ServiceLayer.Contracts;
|
||||
using TeamHobby.HobbyProjectGenerator.ServiceLayer.Implementations;
|
||||
|
||||
|
||||
namespace TeamHobby.HobbyProjectGenerator.ServiceLayer
|
||||
{
|
||||
internal class LoggingManager
|
||||
|
||||
public class LoggingManager
|
||||
{
|
||||
private readonly IDataSource<string> _conn;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILoggerFactory _factory;
|
||||
private readonly LogEntry _logEntry;
|
||||
// private static IDataSource<string> _datasource;
|
||||
private ILogger _logger;
|
||||
private ILoggerFactory _factory;
|
||||
private LogEntry _logEntry;
|
||||
|
||||
// assign default values for LogEntry fields
|
||||
// these are not readonly because they can be overwritten to specify logging at specific field(s) from the main controller by using the public setters for each field
|
||||
private LogLevel _level = LogLevel.Debug;
|
||||
private LogCategory _category = LogCategory.Server;
|
||||
private string _user = "System";
|
||||
|
||||
// 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<string> dataSource)
|
||||
// first constructor has no additional args - defaults to using a DBLoggerFactory to log to database
|
||||
public LoggingManager()
|
||||
{
|
||||
_conn = dataSource;
|
||||
// _datasource = datasource;
|
||||
_logEntry = new LogEntry(_level, _category, _user, "Logging Manager instantiated");
|
||||
_factory = new DBLoggerFactory();
|
||||
_logger = _factory.CreateLogger();
|
||||
}
|
||||
// second constructor takes an additional ILoggerFactory arg - allows for extensible logger types
|
||||
public LoggingManager(IDataSource<string> dataSource, ILoggerFactory factory)
|
||||
public LoggingManager(ILoggerFactory factory)
|
||||
{
|
||||
_conn = dataSource;
|
||||
//_datasource = datasource;
|
||||
_logEntry = new LogEntry(_level, _category, _user, "Logging Manager instantiated");
|
||||
_factory = factory;
|
||||
_logger = _factory.CreateLogger();
|
||||
|
||||
}
|
||||
|
||||
public void Process()
|
||||
{
|
||||
_logger.Log(_logEntry);
|
||||
// // used to create a template entry with the desired fields to write entries at
|
||||
// public void CreateLog(LogLevel level, LogCategory category, string user, string description) {
|
||||
// _logEntry = new LogEntry(level,
|
||||
// category, user, description);
|
||||
// _logger.Log(_logEntry);
|
||||
// }
|
||||
|
||||
// creates a LogEntry object using a description arg
|
||||
// uses whateever the current assignments for the other fields ares
|
||||
public bool CreateLog(string description) {
|
||||
// creates a LogEntry using the passed in description and current assignements from the necessary fields
|
||||
_logEntry = new LogEntry(_level, _category, _user, description);
|
||||
|
||||
// attempt to log the LogEntry by calling the _logger's Log() method
|
||||
try {
|
||||
_logger.Log(_logEntry);
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Level(LogLevel level) {
|
||||
this._level = level;
|
||||
}
|
||||
|
||||
public void Category(LogCategory category) {
|
||||
this._category = category;
|
||||
}
|
||||
|
||||
public void User(string user) {
|
||||
this._user = user;
|
||||
}
|
||||
|
||||
// public static void Source(IDataSource<string> datasource) {
|
||||
// _datasource = datasource;
|
||||
// }
|
||||
|
||||
// public static IDataSource<string> GetDataSource() {
|
||||
// return _datasource;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user