feat: scaffolding for background tasks complete
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace gaseous_tools
|
||||
@@ -40,6 +41,35 @@ namespace gaseous_tools
|
||||
}
|
||||
}
|
||||
|
||||
public static string LogPath
|
||||
{
|
||||
get
|
||||
{
|
||||
string logPath = Path.Combine(ConfigurationPath, "Logs");
|
||||
if (!Directory.Exists(logPath)) {
|
||||
Directory.CreateDirectory(logPath);
|
||||
}
|
||||
return logPath;
|
||||
}
|
||||
}
|
||||
|
||||
public static string LogFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
string logPathName = Path.Combine(LogPath, "Log " + DateTime.Now.ToUniversalTime().ToString("yyyyMMdd") + ".txt");
|
||||
return logPathName;
|
||||
}
|
||||
}
|
||||
|
||||
public static ConfigFile.Logging LoggingConfiguration
|
||||
{
|
||||
get
|
||||
{
|
||||
return _config.LoggingConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
static Config()
|
||||
{
|
||||
if (_config == null)
|
||||
@@ -61,8 +91,7 @@ namespace gaseous_tools
|
||||
// no config file!
|
||||
// use defaults and save
|
||||
_config = new ConfigFile();
|
||||
string configRaw = Newtonsoft.Json.JsonConvert.SerializeObject(_config, Newtonsoft.Json.Formatting.Indented);
|
||||
File.WriteAllText(ConfigurationFilePath, configRaw);
|
||||
UpdateConfig();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +102,14 @@ namespace gaseous_tools
|
||||
public static void UpdateConfig()
|
||||
{
|
||||
// save any updates to the configuration
|
||||
string configRaw = Newtonsoft.Json.JsonConvert.SerializeObject(_config, Newtonsoft.Json.Formatting.Indented);
|
||||
Newtonsoft.Json.JsonSerializerSettings serializerSettings = new Newtonsoft.Json.JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
|
||||
Formatting = Newtonsoft.Json.Formatting.Indented
|
||||
};
|
||||
serializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
|
||||
string configRaw = Newtonsoft.Json.JsonConvert.SerializeObject(_config, serializerSettings);
|
||||
|
||||
if (File.Exists(ConfigurationFilePath_Backup))
|
||||
{
|
||||
File.Delete(ConfigurationFilePath_Backup);
|
||||
@@ -85,7 +121,7 @@ namespace gaseous_tools
|
||||
File.WriteAllText(ConfigurationFilePath, configRaw);
|
||||
}
|
||||
|
||||
private static string ReadSetting(string SettingName, string DefaultValue)
|
||||
public static string ReadSetting(string SettingName, string DefaultValue)
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "SELECT * FROM settings WHERE setting = @settingname";
|
||||
@@ -93,19 +129,28 @@ namespace gaseous_tools
|
||||
dbDict.Add("settingname", SettingName);
|
||||
dbDict.Add("value", DefaultValue);
|
||||
|
||||
DataTable dbResponse = db.ExecuteCMD(sql, dbDict);
|
||||
if (dbResponse.Rows.Count == 0)
|
||||
try
|
||||
{
|
||||
// no value with that name stored - respond with the default value
|
||||
return DefaultValue;
|
||||
Logging.Log(Logging.LogType.Debug, "Database", "Reading setting '" + SettingName + "'");
|
||||
DataTable dbResponse = db.ExecuteCMD(sql, dbDict);
|
||||
if (dbResponse.Rows.Count == 0)
|
||||
{
|
||||
// no value with that name stored - respond with the default value
|
||||
return DefaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (string)dbResponse.Rows[0][0];
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (string)dbResponse.Rows[0][0];
|
||||
Logging.Log(Logging.LogType.Critical, "Database", "Failed reading setting " + SettingName, ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetSetting(string SettingName, string Value)
|
||||
public static void SetSetting(string SettingName, string Value)
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "REPLACE INTO settings (setting, value) VALUES (@settingname, @value)";
|
||||
@@ -113,7 +158,16 @@ namespace gaseous_tools
|
||||
dbDict.Add("settingname", SettingName);
|
||||
dbDict.Add("value", Value);
|
||||
|
||||
db.ExecuteCMD(sql, dbDict);
|
||||
Logging.Log(Logging.LogType.Debug, "Database", "Storing setting '" + SettingName + "' to value: '" + Value + "'");
|
||||
try
|
||||
{
|
||||
db.ExecuteCMD(sql, dbDict);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Critical, "Database", "Failed storing setting" + SettingName, ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public class ConfigFile
|
||||
@@ -123,6 +177,8 @@ namespace gaseous_tools
|
||||
[JsonIgnore]
|
||||
public Library LibraryConfiguration = new Library();
|
||||
|
||||
public Logging LoggingConfiguration = new Logging();
|
||||
|
||||
public class Database
|
||||
{
|
||||
public string HostName = "localhost";
|
||||
@@ -180,6 +236,19 @@ namespace gaseous_tools
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Logging
|
||||
{
|
||||
public bool DebugLogging = false;
|
||||
|
||||
public LoggingFormat LogFormat = Logging.LoggingFormat.Json;
|
||||
|
||||
public enum LoggingFormat
|
||||
{
|
||||
Json,
|
||||
Text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ namespace gaseous_tools
|
||||
// check if the database exists first - first run must have permissions to create a database
|
||||
string sql = "CREATE DATABASE IF NOT EXISTS `" + Config.DatabaseConfiguration.DatabaseName + "`;";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
Logging.Log(Logging.LogType.Information, "Database", "Creating database if it doesn't exist");
|
||||
ExecuteCMD(sql, dbDict, 30, "server=" + Config.DatabaseConfiguration.HostName + ";port=" + Config.DatabaseConfiguration.Port + ";userid=" + Config.DatabaseConfiguration.UserName + ";password=" + Config.DatabaseConfiguration.Password);
|
||||
|
||||
// check if schema version table is in place - if not, create the schema version table
|
||||
@@ -71,8 +72,9 @@ namespace gaseous_tools
|
||||
DataTable SchemaVersionPresent = ExecuteCMD(sql, dbDict);
|
||||
if (SchemaVersionPresent.Rows.Count == 0)
|
||||
{
|
||||
// no schema table present - create it
|
||||
sql = "CREATE TABLE `schema_version` (`schema_version` INT NOT NULL, PRIMARY KEY (`schema_version`)); INSERT INTO `schema_version` (`schema_version`) VALUES (0);";
|
||||
// no schema table present - create it
|
||||
Logging.Log(Logging.LogType.Information, "Database", "Schema version table doesn't exist. Creating it.");
|
||||
sql = "CREATE TABLE `schema_version` (`schema_version` INT NOT NULL, PRIMARY KEY (`schema_version`)); INSERT INTO `schema_version` (`schema_version`) VALUES (0);";
|
||||
ExecuteCMD(sql, dbDict);
|
||||
}
|
||||
|
||||
@@ -87,7 +89,7 @@ namespace gaseous_tools
|
||||
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||
using (StreamReader reader = new StreamReader(stream))
|
||||
{
|
||||
dbScript = reader.ReadToEnd();
|
||||
dbScript = reader.ReadToEnd();
|
||||
|
||||
// apply script
|
||||
sql = "SELECT schema_version FROM schema_version;";
|
||||
@@ -95,16 +97,19 @@ namespace gaseous_tools
|
||||
DataTable SchemaVersion = ExecuteCMD(sql, dbDict);
|
||||
if (SchemaVersion.Rows.Count == 0)
|
||||
{
|
||||
// something is broken here... where's the table?
|
||||
throw new Exception("schema_version table is missing!");
|
||||
// something is broken here... where's the table?
|
||||
Logging.Log(Logging.LogType.Critical, "Database", "Schema table missing! This shouldn't happen!");
|
||||
throw new Exception("schema_version table is missing!");
|
||||
}
|
||||
else
|
||||
{
|
||||
int SchemaVer = (int)SchemaVersion.Rows[0][0];
|
||||
if (SchemaVer < i)
|
||||
Logging.Log(Logging.LogType.Information, "Database", "Schema version is " + SchemaVer);
|
||||
if (SchemaVer < i)
|
||||
{
|
||||
// apply schema!
|
||||
ExecuteCMD(dbScript, dbDict);
|
||||
// apply schema!
|
||||
Logging.Log(Logging.LogType.Information, "Database", "Schema update available - applying");
|
||||
ExecuteCMD(dbScript, dbDict);
|
||||
|
||||
sql = "UPDATE schema_version SET schema_version=@schemaver";
|
||||
dbDict = new Dictionary<string, object>();
|
||||
@@ -115,7 +120,8 @@ namespace gaseous_tools
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
Logging.Log(Logging.LogType.Information, "Database", "Database setup complete");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +167,7 @@ namespace gaseous_tools
|
||||
{
|
||||
DataTable RetTable = new DataTable();
|
||||
|
||||
Logging.Log(Logging.LogType.Debug, "Database", "Connecting to database");
|
||||
MySqlConnection conn = new MySqlConnection(DBConn);
|
||||
conn.Open();
|
||||
|
||||
@@ -178,12 +185,20 @@ namespace gaseous_tools
|
||||
|
||||
try
|
||||
{
|
||||
RetTable.Load(cmd.ExecuteReader());
|
||||
Logging.Log(Logging.LogType.Debug, "Database", "Executing sql: '" + SQL + "'");
|
||||
if (Parameters.Count > 0)
|
||||
{
|
||||
string dictValues = string.Join(";", Parameters.Select(x => string.Join("=", x.Key, x.Value)));
|
||||
Logging.Log(Logging.LogType.Debug, "Database", "Parameters: " + dictValues);
|
||||
}
|
||||
RetTable.Load(cmd.ExecuteReader());
|
||||
} catch (Exception ex) {
|
||||
Logging.Log(Logging.LogType.Critical, "Database", "Error while executing '" + SQL + "'", ex);
|
||||
Trace.WriteLine("Error executing " + SQL);
|
||||
Trace.WriteLine("Full exception: " + ex.ToString());
|
||||
}
|
||||
|
||||
Logging.Log(Logging.LogType.Debug, "Database", "Closing database connection");
|
||||
conn.Close();
|
||||
|
||||
return RetTable;
|
||||
|
||||
102
gaseous-tools/Logging.cs
Normal file
102
gaseous-tools/Logging.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
namespace gaseous_tools
|
||||
{
|
||||
public class Logging
|
||||
{
|
||||
static public void Log(LogType EventType, string Section, string Message, Exception? ExceptionValue = null)
|
||||
{
|
||||
LogItem logItem = new LogItem
|
||||
{
|
||||
EventTime = DateTime.UtcNow,
|
||||
EventType = EventType,
|
||||
Section = Section,
|
||||
Message = Message,
|
||||
ExceptionValue = ExceptionValue
|
||||
};
|
||||
|
||||
bool AllowWrite = false;
|
||||
if (EventType == LogType.Debug)
|
||||
{
|
||||
if (Config.LoggingConfiguration.DebugLogging == true)
|
||||
{
|
||||
AllowWrite = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AllowWrite = true;
|
||||
}
|
||||
|
||||
if (AllowWrite == true)
|
||||
{
|
||||
// console output
|
||||
string TraceOutput = logItem.EventTime.ToString("yyyyMMdd HHmmss") + ": " + logItem.EventType.ToString() + ": " + logItem.Section + ": " + logItem.Message;
|
||||
if (logItem.ExceptionValue != null)
|
||||
{
|
||||
TraceOutput += Environment.NewLine + logItem.ExceptionValue.ToString();
|
||||
}
|
||||
Console.WriteLine(TraceOutput);
|
||||
|
||||
StreamWriter LogFile = File.AppendText(Config.LogFilePath);
|
||||
switch (Config.LoggingConfiguration.LogFormat)
|
||||
{
|
||||
case Config.ConfigFile.Logging.LoggingFormat.Text:
|
||||
LogFile.WriteLine(TraceOutput);
|
||||
break;
|
||||
|
||||
case Config.ConfigFile.Logging.LoggingFormat.Json:
|
||||
Newtonsoft.Json.JsonSerializerSettings serializerSettings = new Newtonsoft.Json.JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
|
||||
Formatting = Newtonsoft.Json.Formatting.Indented
|
||||
};
|
||||
serializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
|
||||
string JsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(logItem, serializerSettings);
|
||||
LogFile.WriteLine(JsonOutput);
|
||||
break;
|
||||
}
|
||||
LogFile.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public enum LogType
|
||||
{
|
||||
Information = 0,
|
||||
Debug = 1,
|
||||
Warning = 2,
|
||||
Critical = 3
|
||||
}
|
||||
|
||||
public class LogItem
|
||||
{
|
||||
public DateTime EventTime { get; set; }
|
||||
public LogType EventType { get; set; }
|
||||
private string _Section = "";
|
||||
public string Section
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Section;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Section = value;
|
||||
}
|
||||
}
|
||||
private string _Message = "";
|
||||
public string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Message;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Message = value;
|
||||
}
|
||||
}
|
||||
public Exception? ExceptionValue { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user