using Salmon.Core; using Salmon.Service; using System.Text.Json; using Wood; const string ENV_PERIOD = "SALMON_PERIOD"; const string ENV_URI = "SALMON_URI"; LogManager.Information($"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 LogManager.Information($"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 LogManager.Information($"Cannot use env variable ", ENV_URI, ", url is malformated."); } // Initialisation Transmitter transmitter = new(); // 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; LogManager.Error($"Cannot find config file \"", configpath, "\"."); return 1; } string content; try { content = File.ReadAllText(configpath); } catch(Exception ex) { LogManager.Information($"Cannot open config file\"", configpath, "\": {ex}."); return 1; } LogManager.Information("Found a configuration file, parsing..."); Configuration? conf = null; try { conf = JsonSerializer.Deserialize(content); } catch (Exception e) { LogManager.Error($"Cannot parse config file \", ",configpath,"\", {e}."); return 1; } if (conf == null) { LogManager.Error($"Cannot parse config file \"", configpath, "\"."); return 1; } if (conf.Url != null) { uri = conf.Url; transmitter.BaseUrl = uri; } if (conf.Period != null) period = conf.Period; if (conf.MonitorHardware != null) monitor_hardware = conf.MonitorHardware; if (conf.MonitorLocalSoftware != null) monitor_localsoftware = conf.MonitorLocalSoftware; foreach (var w in watchers) w.OnStop(); if (conf.Watch != null) watchers = conf.Watch; foreach (var w in watchers) { w.Transmitter = transmitter; w.OnStart(); } 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) { LogManager.Error($"Cannot start: not any URI defined."); return 1; } FileSystemWatcher configWatcher; LogManager.Information($"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) LogManager.Warn("Cannot use modified config file, using last valid file."); else LogManager.Information("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) { LogManager.Error($"Error while forging element: ", e ,"."); } try { await transmitter.SendAsync(tosend); } catch(HttpRequestException e) { LogManager.Error($"[", e.StatusCode, "] Sending data failed: ", e.Message, "."); } catch(Exception e) { LogManager.Error($"Sending data failed: ", e,"."); } await Task.Delay(period.Value); }