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 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> 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(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 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); }