Salmon/Salmon.Service/Program.cs

183 lines
4.4 KiB
C#

using Salmon.Core;
using Salmon.Service;
using System.Diagnostics;
using System.Text.Json;
const string ENV_PERIOD = "SALMON_PERIOD";
const string ENV_URI = "SALMON_URI";
Console.WriteLine($"Salmon.Service initializing...");
int? period = null;
Uri? uri = null;
bool? monitor_hardware = null;
bool? monitor_localsoftware = null;
List<Salmon.Service.Watchers.Base> watchers = new();
bool? watch_config = true;
// 1: use environment variable
var period_env = Environment.GetEnvironmentVariable(ENV_PERIOD);
if (period_env != null)
{
if (int.TryParse(period_env, out int p))
period = p;
else
Console.WriteLine($"Cannot use env variable {ENV_PERIOD}, should be an int in milliseconds.");
}
var uri_env = Environment.GetEnvironmentVariable(ENV_URI);
if(uri_env != null)
{
if (Uri.TryCreate(uri_env, UriKind.Absolute, out var u))
uri = u;
else
Console.WriteLine($"Cannot use env variable {ENV_URI}, url is malformated.");
}
// 2: override with configuration file
string configpath = "config.json";
Func<bool, Task<int>> reloadConfigFile = new(async (bool configFileMustExists ) =>
{
await Task.Delay(500);
if (!File.Exists(configpath))
{
if (!configFileMustExists)
return 0;
Console.WriteLine($"Cannot find config file\"{configpath}\".");
return 1;
}
string content;
try
{
content = File.ReadAllText(configpath);
}
catch(Exception ex)
{
Console.WriteLine($"Cannot open config file\"{configpath}\": {ex}.");
return 1;
}
Console.WriteLine("Found a configuration file, parsing...");
Configuration? conf = null;
try
{
conf = JsonSerializer.Deserialize<Configuration>(content);
}
catch (Exception e)
{
Console.WriteLine($"Cannot parse config file \"{configpath}\", {e}.");
return 1;
}
if (conf == null)
{
Console.WriteLine($"Cannot parse config file \"{configpath}\".");
return 1;
}
if (conf.Url != null)
uri = conf.Url;
if (conf.Period != null)
period = conf.Period;
if (conf.MonitorHardware != null)
monitor_hardware = conf.MonitorHardware;
if (conf.MonitorLocalSoftware != null)
monitor_localsoftware = conf.MonitorLocalSoftware;
if (conf.Watch != null)
watchers = conf.Watch;
return 0;
});
if (await reloadConfigFile(false) != 0)
return 0;
//todo: override with parameter
// 3 : override with argument
// 4 : override with default
period ??= 60000;
monitor_hardware ??= true;
monitor_localsoftware ??= true;
// 5 : Check if valid
if(uri == null)
{
Console.WriteLine($"Cannot start: not any URI defined.");
return 1;
}
// Initialisation
Transmitter transmitter = new();
FileSystemWatcher configWatcher;
Console.WriteLine($"Salmon.Service started at {DateTime.Now}.");
if(configpath != null && watch_config == true)
{
FileInfo fi = new (configpath);
//watch configuration if needed
configWatcher = new FileSystemWatcher(fi.DirectoryName);
configWatcher.Filter = fi.Name;
configWatcher.NotifyFilter = NotifyFilters.CreationTime
| NotifyFilters.LastWrite;
configWatcher.Changed += async (object sender, FileSystemEventArgs e) =>
{
if (await reloadConfigFile(false) != 0)
Console.WriteLine("Cannot use modified config file, using last valid file.");
else
Console.WriteLine("Config file reloaded.");
};
configWatcher.EnableRaisingEvents = true;
}
while ( true )
{
var software = Salmon.Model.Monitor.Software.FromLocal();
List<Element> tosend = new();
tosend.Add(software);
if(monitor_hardware == true)
{
var hardwares = Salmon.Model.Monitor.Hardware.FromAllHardware();
tosend.AddRange(hardwares);
}
foreach (var w in watchers)
try
{
foreach (var el in await w.ForgeElements())
tosend.Add(el);
}
catch(Exception e)
{
Console.WriteLine($"Error while forging element: {e}.");
}
try
{
await transmitter.SendAsync(uri, tosend);
}
catch(HttpRequestException e)
{
Console.WriteLine($"[{e.StatusCode}] Sending data failed: {e.Message}.");
}
catch(Exception e)
{
Console.WriteLine($"Sending data failed: {e}");
}
await Task.Delay(period.Value);
}