public void Can_read_overwrites() { BitArray bitArray = new BitArray(6); for (int i = 0; i < 2 * 2 * 2 * 2 * 2 * 2; i++) { ConfigProvider configProvider = new ConfigProvider(); bitArray.Set(0, (i >> 0) % 2 == 1); bitArray.Set(1, (i >> 1) % 2 == 1); bitArray.Set(2, (i >> 2) % 2 == 1); bitArray.Set(3, (i >> 3) % 2 == 1); bitArray.Set(4, (i >> 4) % 2 == 1); bitArray.Set(5, (i >> 5) % 2 == 1); Dictionary <string, string> args = new Dictionary <string, string>(); if (bitArray.Get(4)) { args.Add("JsonRpc.Enabled", bitArray.Get(5).ToString()); } Environment.SetEnvironmentVariable("NETHERMIND_JSONRPCCONFIG_ENABLED", null, EnvironmentVariableTarget.Process); if (bitArray.Get(2)) { Environment.SetEnvironmentVariable("NETHERMIND_JSONRPCCONFIG_ENABLED", bitArray.Get(3).ToString(), EnvironmentVariableTarget.Process); } Dictionary <string, string> fakeJson = new Dictionary <string, string>(); if (bitArray.Get(0)) { fakeJson.Add("JsonRpc.Enabled", bitArray.Get(1).ToString()); } configProvider.AddSource(new ArgsConfigSource(args)); configProvider.AddSource(new EnvConfigSource()); configProvider.AddSource(new ArgsConfigSource(fakeJson)); var config = configProvider.GetConfig <IJsonRpcConfig>(); bool expectedResult = bitArray.Get(4) ? bitArray.Get(5) : bitArray.Get(2) ? bitArray.Get(3) : bitArray.Get(0) ? bitArray.Get(1) : false; Assert.AreEqual(expectedResult, config.Enabled, bitArray.ToBitString()); } }
public void Can_read_overwrites() { BitArray bitArray = new BitArray(6); for (int i = 0; i < 2 * 2 * 2 * 2 * 2 * 2; i++) { ConfigProvider configProvider = new ConfigProvider(); bitArray.Set(0, (i >> 0) % 2 == 1); bitArray.Set(1, (i >> 1) % 2 == 1); bitArray.Set(2, (i >> 2) % 2 == 1); bitArray.Set(3, (i >> 3) % 2 == 1); bitArray.Set(4, (i >> 4) % 2 == 1); bitArray.Set(5, (i >> 5) % 2 == 1); Dictionary <string, string> args = new Dictionary <string, string>(); if (bitArray.Get(4)) { args.Add("StatsConfig.CaptureNodeStatsEventHistory", bitArray.Get(5).ToString()); } Environment.SetEnvironmentVariable("NETHERMIND_STATSCONFIG_CAPTURENODESTATSEVENTHISTORY", null, EnvironmentVariableTarget.Process); if (bitArray.Get(2)) { Environment.SetEnvironmentVariable("NETHERMIND_STATSCONFIG_CAPTURENODESTATSEVENTHISTORY", bitArray.Get(3).ToString(), EnvironmentVariableTarget.Process); } Dictionary <string, string> fakeJson = new Dictionary <string, string>(); if (bitArray.Get(0)) { fakeJson.Add("StatsConfig.CaptureNodeStatsEventHistory", bitArray.Get(1).ToString()); } configProvider.AddSource(new ArgsConfigSource(args)); configProvider.AddSource(new EnvConfigSource()); configProvider.AddSource(new ArgsConfigSource(fakeJson)); var config = configProvider.GetConfig <IStatsConfig>(); bool expectedResult = bitArray.Get(4) ? bitArray.Get(5) : bitArray.Get(2) ? bitArray.Get(3) : bitArray.Get(0) ? bitArray.Get(1) : false; Assert.AreEqual(expectedResult, config.CaptureNodeStatsEventHistory, bitArray.ToBitString()); } }
[Timeout(12000)] // just to make sure we are not on infinite loop on steps because of incorrect dependencies public async Task Smoke_cancel(string chainSpecPath) { Type type1 = typeof(ITxPoolConfig); Type type2 = typeof(INetworkConfig); Type type3 = typeof(IKeyStoreConfig); Type type4 = typeof(IDbConfig); Type type5 = typeof(IStatsConfig); Type type6 = typeof(IKafkaConfig); Type type7 = typeof(IEthStatsConfig); Type type8 = typeof(ISyncConfig); Type type9 = typeof(IBloomConfig); var configProvider = new ConfigProvider(); configProvider.AddSource(new ConfigSource(chainSpecPath)); Console.WriteLine(type1.Name); Console.WriteLine(type2.Name); Console.WriteLine(type3.Name); Console.WriteLine(type4.Name); Console.WriteLine(type5.Name); Console.WriteLine(type6.Name); Console.WriteLine(type7.Name); Console.WriteLine(type8.Name); Console.WriteLine(type9.Name); var tempPath = Path.Combine(Path.GetTempPath(), "test_" + Guid.NewGuid()); Directory.CreateDirectory(tempPath); try { configProvider.GetConfig <IInitConfig>().BaseDbPath = tempPath; EthereumRunner runner = new EthereumRunner( new RpcModuleProvider(new JsonRpcConfig(), LimboLogs.Instance), configProvider, NUnitLogManager.Instance, Substitute.For <IGrpcServer>(), Substitute.For <INdmConsumerChannelManager>(), Substitute.For <INdmDataPublisher>(), Substitute.For <INdmInitializer>(), Substitute.For <IWebSocketsManager>(), new EthereumJsonSerializer(), Substitute.For <IMonitoringService>()); CancellationTokenSource cts = new CancellationTokenSource(); Task task = runner.Start(cts.Token); cts.Cancel(); await task; } finally { // rocks db still has a lock on a file called "LOCK". Directory.Delete(tempPath, true); } }
private static ConfigProvider GetConfigProviderFromFile(string configFile) { ConfigProvider configProvider = new ConfigProvider(); var configPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "configs", configFile); configProvider.AddSource(new JsonConfigSource(configPath)); return(configProvider); }
public void Setup() { // by pre-caching configs providers we make the tests do lot less work Parallel.ForEach(Directory.GetFiles("configs"), configFile => { var configProvider = new ConfigProvider(); configProvider.AddSource(new JsonConfigSource(configFile)); _cachedProviders.Add(configProvider); }); }
[Timeout(120000)] // just to make sure we are not on infinite loop on steps because of incorrect dependencies public async Task Smoke(string chainSpecPath) { Type type1 = typeof(ITxPoolConfig); Type type2 = typeof(INetworkConfig); Type type3 = typeof(IKeyStoreConfig); Type type4 = typeof(IDbConfig); Type type5 = typeof(IStatsConfig); Type type6 = typeof(IKafkaConfig); Type type7 = typeof(IEthStatsConfig); Type type8 = typeof(ISyncConfig); Type type9 = typeof(IBloomConfig); var configProvider = new ConfigProvider(); configProvider.AddSource(new ConfigSource(chainSpecPath)); Console.WriteLine(type1.Name); Console.WriteLine(type2.Name); Console.WriteLine(type3.Name); Console.WriteLine(type4.Name); Console.WriteLine(type5.Name); Console.WriteLine(type6.Name); Console.WriteLine(type7.Name); Console.WriteLine(type8.Name); Console.WriteLine(type9.Name); EthereumRunner runner = new EthereumRunner( new RpcModuleProvider(new JsonRpcConfig(), LimboLogs.Instance), configProvider, LimboLogs.Instance, Substitute.For <IGrpcServer>(), Substitute.For <INdmConsumerChannelManager>(), Substitute.For <INdmDataPublisher>(), Substitute.For <INdmInitializer>(), Substitute.For <IWebSocketsManager>(), new EthereumJsonSerializer(), Substitute.For <IMonitoringService>()); await runner.Start(); await runner.StopAsync(); }
protected override (CommandLineApplication, Func <IConfigProvider>, Func <string>) BuildCommandLineApp() { var pluginsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins"); if (Directory.Exists(pluginsDirectory)) { var plugins = Directory.GetFiles(pluginsDirectory, "*.dll"); foreach (var plugin in plugins) { var pluginName = plugin.Contains("/") ? plugin.Split("/").Last() : plugin.Split("\\").Last(); if (Logger.IsInfo) { Logger.Info($"Loading an external assembly: {pluginName}"); } AssemblyLoadContext.Default.LoadFromAssemblyPath(plugin); } } var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList(); loadedAssemblies .SelectMany(x => x.GetReferencedAssemblies()) .Distinct() .Where(y => loadedAssemblies.Any((a) => a.FullName == y.FullName) == false) .ToList() .ForEach(x => loadedAssemblies.Add(AppDomain.CurrentDomain.Load(x))); var configurationType = typeof(IConfig); var configs = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a => a.GetTypes()) .Where(t => configurationType.IsAssignableFrom(t) && !t.IsInterface) .ToList(); var app = new CommandLineApplication { Name = "Nethermind.Runner" }; app.HelpOption("-?|-h|--help"); var configFile = app.Option("-c|--config <configFile>", "config file path", CommandOptionType.SingleValue); var dbBasePath = app.Option("-d|--baseDbPath <baseDbPath>", "base db path", CommandOptionType.SingleValue); var logLevelOverride = app.Option("-l|--log <logLevel>", "log level", CommandOptionType.SingleValue); foreach (Type configType in configs) { foreach (PropertyInfo propertyInfo in configType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { app.Option($"--{configType.Name.Replace("Config", String.Empty)}.{propertyInfo.Name}", $"{configType.Name}.{propertyInfo.Name}", CommandOptionType.SingleValue); } } IConfigProvider BuildConfigProvider() { // TODO: dynamically switch log levels from CLI! if (logLevelOverride.HasValue()) { string logLevel = logLevelOverride.Value(); NLog.LogLevel nLogLevel = NLog.LogLevel.Info; switch (logLevel.ToUpperInvariant()) { case "OFF": nLogLevel = NLog.LogLevel.Off; break; case "ERROR": nLogLevel = NLog.LogLevel.Error; break; case "WARN": nLogLevel = NLog.LogLevel.Warn; break; case "INFO": nLogLevel = NLog.LogLevel.Info; break; case "DEBUG": nLogLevel = NLog.LogLevel.Debug; break; case "TRACE": nLogLevel = NLog.LogLevel.Trace; break; } Console.WriteLine($"Enabling log level override: {logLevel.ToUpperInvariant()}"); foreach (var rule in LogManager.Configuration.LoggingRules) { rule.DisableLoggingForLevels(NLog.LogLevel.Trace, nLogLevel); rule.EnableLoggingForLevels(nLogLevel, NLog.LogLevel.Off); } //Call to update existing Loggers created with GetLogger() or //GetCurrentClassLogger() LogManager.ReconfigExistingLoggers(); } ConfigProvider configProvider = new ConfigProvider(); Dictionary <string, string> args = new Dictionary <string, string>(); foreach (CommandOption commandOption in app.Options) { if (commandOption.HasValue()) { args.Add(commandOption.LongName, commandOption.Value()); } } IConfigSource argsSource = new ArgsConfigSource(args); configProvider.AddSource(argsSource); configProvider.AddSource(new EnvConfigSource()); string configFilePath = configFile.HasValue() ? configFile.Value() : _defaultConfigFile; var configPathVariable = Environment.GetEnvironmentVariable("NETHERMIND_CONFIG"); if (!string.IsNullOrWhiteSpace(configPathVariable)) { configFilePath = configPathVariable; } if (!Path.HasExtension(configFilePath) && !configFilePath.Contains(Path.DirectorySeparatorChar)) { string redirectedConfigPath = Path.Combine("configs", string.Concat(configFilePath, ".cfg")); Console.WriteLine($"Redirecting config {configFilePath} to {redirectedConfigPath}"); configFilePath = redirectedConfigPath; } Console.WriteLine($"Reading config file from {configFilePath}"); configProvider.AddSource(new JsonConfigSource(configFilePath)); return(configProvider); } string GetBaseDbPath() { return(dbBasePath.HasValue() ? dbBasePath.Value() : null); } return(app, BuildConfigProvider, GetBaseDbPath); }
protected override (CommandLineApplication, Func <IConfigProvider>, Func <string>) BuildCommandLineApp() { var app = new CommandLineApplication { Name = "ChainLoader" }; app.HelpOption("-?|-h|--help"); var configFile = app.Option("-c|--config <configFile>", "config file path", CommandOptionType.SingleValue); var dbBasePath = app.Option("-d|--baseDbPath <baseDbPath>", "base db path", CommandOptionType.SingleValue); foreach (Type configType in _configs) { foreach (PropertyInfo propertyInfo in configType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { app.Option($"--{configType.Name}.{propertyInfo.Name}", $"{configType.Name}.{propertyInfo.Name}", CommandOptionType.SingleValue); } } IConfigProvider BuildConfigProvider() { ConfigProvider configProvider = new ConfigProvider(); Dictionary <string, string> args = new Dictionary <string, string>(); foreach (CommandOption commandOption in app.Options) { if (commandOption.HasValue()) { args.Add(commandOption.LongName, commandOption.Value()); } } IConfigSource argsSource = new ArgsConfigSource(args); configProvider.AddSource(argsSource); configProvider.AddSource(new EnvConfigSource()); string configFilePath = configFile.HasValue() ? configFile.Value() : _defaultConfigFile; var configPathVariable = Environment.GetEnvironmentVariable("NETHERMIND_CONFIG"); if (!string.IsNullOrWhiteSpace(configPathVariable)) { configFilePath = configPathVariable; } if (!Path.HasExtension(configFilePath) && !configFilePath.Contains(Path.DirectorySeparatorChar)) { string redirectedConfigPath = Path.Combine("configs", string.Concat(configFilePath, ".cfg")); Console.WriteLine($"Redirecting config {configFilePath} to {redirectedConfigPath}"); configFilePath = redirectedConfigPath; } Console.WriteLine($"Reading config file from {configFilePath}"); configProvider.AddSource(new JsonConfigSource(configFilePath)); return(configProvider); } string GetBaseDbPath() { return(dbBasePath.HasValue() ? dbBasePath.Value() : null); } return(app, BuildConfigProvider, GetBaseDbPath); }
private static IConfigProvider BuildConfigProvider( CommandLineApplication app, CommandOption loggerConfigSource, CommandOption logLevelOverride, CommandOption configsDirectory, CommandOption configFile) { ILogger logger = SimpleConsoleLogger.Instance; if (loggerConfigSource.HasValue()) { string nLogPath = loggerConfigSource.Value(); logger.Info($"Loading NLog configuration file from {nLogPath}."); try { LogManager.Configuration = new XmlLoggingConfiguration(nLogPath); } catch (Exception e) { logger.Info($"Failed to load NLog configuration from {nLogPath}. {e}"); } } else { logger.Info($"Loading standard NLog.config file from {"NLog.config".GetApplicationResourcePath()}."); Stopwatch stopwatch = Stopwatch.StartNew(); LogManager.Configuration = new XmlLoggingConfiguration("NLog.config".GetApplicationResourcePath()); stopwatch.Stop(); logger.Info($"NLog.config loaded in {stopwatch.ElapsedMilliseconds}ms."); } // TODO: dynamically switch log levels from CLI! if (logLevelOverride.HasValue()) { NLogConfigurator.ConfigureLogLevels(logLevelOverride); } ConfigProvider configProvider = new ConfigProvider(); Dictionary <string, string> configArgs = new Dictionary <string, string>(); foreach (CommandOption commandOption in app.Options) { if (commandOption.HasValue()) { configArgs.Add(commandOption.LongName, commandOption.Value()); } } IConfigSource argsSource = new ArgsConfigSource(configArgs); configProvider.AddSource(argsSource); configProvider.AddSource(new EnvConfigSource()); string configDir = configsDirectory.HasValue() ? configsDirectory.Value() : DefaultConfigsDirectory; string configFilePath = configFile.HasValue() ? configFile.Value() : DefaultConfigFile; string?configPathVariable = Environment.GetEnvironmentVariable("NETHERMIND_CONFIG"); if (!string.IsNullOrWhiteSpace(configPathVariable)) { configFilePath = configPathVariable; } if (!PathUtils.IsExplicitlyRelative(configFilePath)) { if (configDir == DefaultConfigsDirectory) { configFilePath = configFilePath.GetApplicationResourcePath(); } else { configFilePath = Path.Combine(configDir, string.Concat(configFilePath)); } } if (!Path.HasExtension(configFilePath) && !configFilePath.Contains(Path.DirectorySeparatorChar)) { string redirectedConfigPath = Path.Combine(configDir, string.Concat(configFilePath, ".cfg")); configFilePath = redirectedConfigPath; if (!File.Exists(configFilePath)) { throw new InvalidOperationException($"Configuration: {configFilePath} was not found."); } } if (!Path.HasExtension(configFilePath)) { configFilePath = string.Concat(configFilePath, ".cfg"); } // Fallback to "{executingDirectory}/configs/{configFile}" if "configs" catalog was not specified. if (!File.Exists(configFilePath)) { string configName = Path.GetFileName(configFilePath); string?configDirectory = Path.GetDirectoryName(configFilePath); string redirectedConfigPath = Path.Combine(configDirectory ?? string.Empty, configDir, configName); configFilePath = redirectedConfigPath; if (!File.Exists(configFilePath)) { throw new InvalidOperationException($"Configuration: {configFilePath} was not found."); } } logger.Info($"Reading config file from {configFilePath}"); configProvider.AddSource(new JsonConfigSource(configFilePath)); configProvider.Initialize(); logger.Info("Configuration initialized."); return(configProvider); }
public JsonConfigProvider(string jsonConfigFile) { _provider.AddSource(new JsonConfigSource(jsonConfigFile)); }
protected override (CommandLineApplication, Func <IConfigProvider>, Func <string?>) BuildCommandLineApp() { string pluginsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory ?? string.Empty, "plugins"); if (Directory.Exists(pluginsDirectory)) { var plugins = Directory.GetFiles(pluginsDirectory, "*.dll"); foreach (string plugin in plugins) { Console.WriteLine($"Loading plugin {plugin} from {pluginsDirectory}"); string pluginName = plugin.Contains("/") ? plugin.Split("/").Last() : plugin.Split("\\").Last(); AssemblyLoadContext.Default.LoadFromAssemblyPath(plugin); } } else { Console.WriteLine($"Could not find plugins directory at: {pluginsDirectory}"); } var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList(); loadedAssemblies .SelectMany(x => x.GetReferencedAssemblies()) .Distinct() .Where(y => loadedAssemblies.Any((a) => a.FullName == y.FullName) == false) .ToList() .ForEach(x => loadedAssemblies.Add(AppDomain.CurrentDomain.Load(x))); Type configurationType = typeof(IConfig); List <Type> configTypes = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a => a.GetTypes()) .Where(t => configurationType.IsAssignableFrom(t) && !t.IsInterface) .ToList(); CommandLineApplication app = new CommandLineApplication { Name = "Nethermind.Runner" }; app.HelpOption("-?|-h|--help"); app.VersionOption("-v|--version", () => ClientVersion.Version, () => ClientVersion.Description); NLog.GlobalDiagnosticsContext.Set("version", ClientVersion.Version); CommandOption configFile = app.Option("-c|--config <configFile>", "config file path", CommandOptionType.SingleValue); CommandOption dbBasePath = app.Option("-d|--baseDbPath <baseDbPath>", "base db path", CommandOptionType.SingleValue); CommandOption logLevelOverride = app.Option("-l|--log <logLevel>", "log level", CommandOptionType.SingleValue); CommandOption configsDirectory = app.Option("-cd|--configsDirectory <configsDirectory>", "configs directory", CommandOptionType.SingleValue); CommandOption loggerConfigSource = app.Option("-lcs|--loggerConfigSource <loggerConfigSource>", "path to the NLog config file", CommandOptionType.SingleValue); foreach (Type configType in configTypes) { if (configType == null) { continue; } foreach (PropertyInfo propertyInfo in configType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { Type? interfaceType = configType.GetInterface("I" + configType.Name); PropertyInfo?interfaceProperty = interfaceType?.GetProperty(propertyInfo.Name); ConfigItemAttribute?configItemAttribute = interfaceProperty?.GetCustomAttribute <ConfigItemAttribute>(); app.Option($"--{configType.Name.Replace("Config", String.Empty)}.{propertyInfo.Name}", $"{(configItemAttribute == null ? "<missing documentation>" : configItemAttribute.Description ?? "<missing documentation>")}", CommandOptionType.SingleValue); } } IConfigProvider BuildConfigProvider() { if (loggerConfigSource.HasValue()) { string nLogPath = loggerConfigSource.Value(); Console.WriteLine($"Loading NLog configuration file from {nLogPath}."); try { LogManager.Configuration = new XmlLoggingConfiguration(nLogPath); } catch (Exception e) { Console.WriteLine($"Failed to load NLog configuration from {nLogPath}. {e}"); } } else { Console.WriteLine($"Loading standard NLog.config file from {"NLog.config".GetApplicationResourcePath()}."); LogManager.Configuration = new XmlLoggingConfiguration("NLog.config".GetApplicationResourcePath()); } // TODO: dynamically switch log levels from CLI! if (logLevelOverride.HasValue()) { (new NLogConfigurator()).ConfigureLogLevels(logLevelOverride); } ConfigProvider configProvider = new ConfigProvider(); Dictionary <string, string> args = new Dictionary <string, string>(); foreach (CommandOption commandOption in app.Options) { if (commandOption.HasValue()) { args.Add(commandOption.LongName, commandOption.Value()); } } IConfigSource argsSource = new ArgsConfigSource(args); configProvider.AddSource(argsSource); configProvider.AddSource(new EnvConfigSource()); string configDir = configsDirectory.HasValue() ? configsDirectory.Value() : DefaultConfigsDirectory; string configFilePath = configFile.HasValue() ? configFile.Value() : _defaultConfigFile; string?configPathVariable = Environment.GetEnvironmentVariable("NETHERMIND_CONFIG"); if (!string.IsNullOrWhiteSpace(configPathVariable)) { configFilePath = configPathVariable; } if (!PathUtils.IsExplicitlyRelative(configFilePath)) { if (configDir == DefaultConfigsDirectory) { configFilePath = configFilePath.GetApplicationResourcePath(); } else { configFilePath = Path.Combine(configDir, string.Concat(configFilePath)); } } if (!Path.HasExtension(configFilePath) && !configFilePath.Contains(Path.DirectorySeparatorChar)) { string redirectedConfigPath = Path.Combine(configDir, string.Concat(configFilePath, ".cfg")); configFilePath = redirectedConfigPath; if (!File.Exists(configFilePath)) { throw new InvalidOperationException($"Configuration: {configFilePath} was not found."); } } if (!Path.HasExtension(configFilePath)) { configFilePath = string.Concat(configFilePath, ".cfg"); } // Fallback to "{executingDirectory}/configs/{configFile}" if "configs" catalog was not specified. if (!File.Exists(configFilePath)) { string configName = Path.GetFileName(configFilePath); string?configDirectory = Path.GetDirectoryName(configFilePath); string redirectedConfigPath = Path.Combine(configDirectory ?? string.Empty, configDir, configName); configFilePath = redirectedConfigPath; if (!File.Exists(configFilePath)) { throw new InvalidOperationException($"Configuration: {configFilePath} was not found."); } } Console.WriteLine($"Reading config file from {configFilePath}"); configProvider.AddSource(new JsonConfigSource(configFilePath)); configTypes.ForEach(configType => configProvider.RegisterCategory(configType.Name, configType)); return(configProvider); } string?GetBaseDbPath() { return(dbBasePath.HasValue() ? dbBasePath.Value() : null); } return(app, BuildConfigProvider, GetBaseDbPath); }
protected override (CommandLineApplication, Func <IConfigProvider>, Func <string>) BuildCommandLineApp() { var app = new CommandLineApplication { Name = "Nethermind.Runner" }; app.HelpOption("-?|-h|--help"); var configFile = app.Option("-c|--config <configFile>", "config file path", CommandOptionType.SingleValue); var dbBasePath = app.Option("-d|--baseDbPath <baseDbPath>", "base db path", CommandOptionType.SingleValue); var logLevelOverride = app.Option("-l|--log <logLevel>", "log level", CommandOptionType.SingleValue); foreach (Type configType in _configs) { foreach (PropertyInfo propertyInfo in configType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { app.Option($"--{configType.Name}.{propertyInfo.Name}", $"{configType.Name}.{propertyInfo.Name}", CommandOptionType.SingleValue); } } IConfigProvider BuildConfigProvider() { // TODO: dynamically switch log levels from CLI! if (logLevelOverride.HasValue()) { string logLevel = logLevelOverride.Value(); NLog.LogLevel nLogLevel = NLog.LogLevel.Info; switch (logLevel.ToUpperInvariant()) { case "OFF": nLogLevel = NLog.LogLevel.Off; break; case "ERROR": nLogLevel = NLog.LogLevel.Error; break; case "WARN": nLogLevel = NLog.LogLevel.Warn; break; case "INFO": nLogLevel = NLog.LogLevel.Info; break; case "DEBUG": nLogLevel = NLog.LogLevel.Debug; break; case "TRACE": nLogLevel = NLog.LogLevel.Trace; break; } Console.WriteLine($"Enabling log level override: {logLevel.ToUpperInvariant()}"); foreach (var rule in LogManager.Configuration.LoggingRules) { rule.DisableLoggingForLevels(NLog.LogLevel.Trace, nLogLevel); rule.EnableLoggingForLevels(nLogLevel, NLog.LogLevel.Off); } //Call to update existing Loggers created with GetLogger() or //GetCurrentClassLogger() LogManager.ReconfigExistingLoggers(); } ConfigProvider configProvider = new ConfigProvider(); Dictionary <string, string> args = new Dictionary <string, string>(); foreach (CommandOption commandOption in app.Options) { if (commandOption.HasValue()) { args.Add(commandOption.LongName, commandOption.Value()); } } IConfigSource argsSource = new ArgsConfigSource(args); configProvider.AddSource(argsSource); configProvider.AddSource(new EnvConfigSource()); string configFilePath = configFile.HasValue() ? configFile.Value() : _defaultConfigFile; var configPathVariable = Environment.GetEnvironmentVariable("NETHERMIND_CONFIG"); if (!string.IsNullOrWhiteSpace(configPathVariable)) { configFilePath = configPathVariable; } if (!Path.HasExtension(configFilePath) && !configFilePath.Contains(Path.DirectorySeparatorChar)) { string redirectedConfigPath = Path.Combine("configs", string.Concat(configFilePath, ".cfg")); Console.WriteLine($"Redirecting config {configFilePath} to {redirectedConfigPath}"); configFilePath = redirectedConfigPath; } Console.WriteLine($"Reading config file from {configFilePath}"); configProvider.AddSource(new JsonConfigSource(configFilePath)); return(configProvider); } string GetBaseDbPath() { return(dbBasePath.HasValue() ? dbBasePath.Value() : null); } return(app, BuildConfigProvider, GetBaseDbPath); }