/// <summary> /// Checks the command line params.<para/> /// arguments format: key=value or --key value /// </summary> /// <param name="args">The args.</param> public FlexibleOptions Parse(string[] args) { // 1. parse local configuration file // display the options listed in the configuration file FlexibleOptions localOptions = ParseAppSettings(); // 2. parse console arguments // parse arguments like: key=value FlexibleOptions argsOptions = ParseCommandLineArguments(args); // 3. merge arguments with app.config options. Priority: arguments > app.config Parsed = FlexibleOptions.Merge(localOptions, argsOptions); // 4. check for external config file // set config alias Parsed.SetAlias("config", "S3ConfigurationPath", "webConfigurationFile"); // load and parse web hosted configuration file (priority order: argsOptions > localOptions) ExternalFiles = Parsed.GetAsList("config", new char[] { ',', ';' }); FlexibleOptions externalLoadedOptions = ParseExternalFiles(ExternalFiles); // 5. merge options with the following priority: // 1. console arguments // 2. external file with json configuration object (local or web) // 3. local configuration file (app.config or web.config) Parsed = FlexibleOptions.Merge(Parsed, externalLoadedOptions, argsOptions); // return final merged options return(Parsed); }
public FlexibleOptions ParseExternalFiles(string[] filePaths) { // load and parse web hosted configuration file (priority order: argsOptions > localOptions) FlexibleOptions parsed = null; try { ExternalFiles = filePaths; foreach (var file in filePaths) { var loaded = LoadExtenalConfigurationFile(file.Trim(' ', '\'', '"', '[', ']')); if (parsed == null) { parsed = loaded; } else { parsed.AddRange(loaded); } } } catch (Exception ex) { if (ThrownOnError) { throw; } RaiseErrorEvent(ex); } return(parsed); }
private static FlexibleOptions parseFile (string content) { var options = new FlexibleOptions (); // detect xml if (content.TrimStart ().StartsWith ("<")) { var xmlDoc = System.Xml.Linq.XDocument.Parse (content); var root = xmlDoc.Descendants ("config").FirstOrDefault (); if (root != null && root.HasElements) { foreach (var i in root.Elements ()) { options.Set (i.Name.ToString (), i.Value); } } } else { var json = Newtonsoft.Json.Linq.JObject.Parse (content); foreach (var i in json) { options.Set (i.Key, i.Value.ToString (Newtonsoft.Json.Formatting.None)); } } return options; }
/// <summary> /// Parses command line and app.config arguments and initilialize log. /// </summary> /// <param name="args">Program arguments</param> /// <param name="thrownOnError">The thrown exception on internal initialization error.</param> /// <param name="options">The additional options.</param> /// <returns>Parsed arguments</returns> public static FlexibleOptions Initialize (string[] args, bool thrownOnError, InitializationOptions options = null) { InitOptions = options; // run default program initialization DefaultProgramInitialization (); // parse command line arguments ProgramOptions = CheckCommandLineParams (args, thrownOnError); // check for help command if (ProgramOptions.Get<bool> ("help", false) || ProgramOptions.Get<bool> ("h", false)) { show_help (""); CloseApplication (0, true); } // display program initialization header if (!Console.IsOutputRedirected) { ConsoleUtils.DisplayHeader ( typeof(ConsoleUtils).Namespace.Replace (".SimpleHelpers", ""), "options: " + (ProgramOptions == null ? "none" : "\n# " + String.Join ("\n# ", ProgramOptions.Options.Select (i => i.Key + "=" + i.Value)))); } else { var logger = GetLogger (); if (logger.IsDebugEnabled) { logger.Debug ("options: " + (ProgramOptions == null ? "none" : "\n# " + String.Join ("\n# ", ProgramOptions.Options.Select (i => i.Key + "=" + i.Value)))); } } return ProgramOptions; }
/// <summary> /// Merge together FlexibleOptions instances, the last object in the list has priority in conflict resolution (overwrite).<para/> /// Merge will return a new instance of FlexibleOptions. /// </summary> /// <param name="items"></param> /// <returns>A new instance of FlexibleOptions with merged options</returns> public static FlexibleOptions Merge(params FlexibleOptions[] items) { if (items == null || items.Length == 0) { return(new FlexibleOptions()); } // create options var lastItem = items.LastOrDefault(i => i != null); var merge = new FlexibleOptions(lastItem != null ? lastItem._caseInsensitive : true); // merge var dic = merge.Options; for (int i = 0; i < items.Length; i++) { if (items[i] == null) { continue; } // copy foreach (var o in items[i].Options) { dic[o.Key] = o.Value; } // also copy alias values if (items[i]._alias != null) { foreach (var a in items[i]._alias) { merge.SetAlias(a.Value, a.Key); } } } return(merge); }
private FlexibleOptions ParseFileContent(string content) { var options = new FlexibleOptions(); if (String.IsNullOrEmpty(content)) { return(options); } // prepare content content = content.Trim(); try { // detect xml if (content.StartsWith("<")) { var xmlDoc = System.Xml.Linq.XDocument.Parse(content); var root = xmlDoc.Descendants("config").FirstOrDefault(); if (root != null && root.HasElements) { foreach (var i in root.Elements()) { options.Set(i.Name.ToString(), i.Value); } } } // parse as json else { var json = Newtonsoft.Json.Linq.JObject.Parse(content); foreach (var i in json) { options.Set(i.Key, i.Value.ToString(Newtonsoft.Json.Formatting.None)); } } } catch (Exception ex) { if (ThrownOnError) { throw; } RaiseErrorEvent(ex); return(null); } return(options); }
public FlexibleOptions ParseCommandLineArguments(string[] args) { var argsOptions = new FlexibleOptions(); if (args != null) { string arg; bool openTag = false; string lastTag = null; for (int ix = 0; ix < args.Length; ix++) { arg = args[ix]; // check for option with key=value sintax (restriction: the previous tag must not be an open tag) // also valid for --key:value bool hasStartingMarker = arg.StartsWith("-", StringComparison.Ordinal) || arg.StartsWith("/", StringComparison.Ordinal); int p = arg.IndexOf('='); if (p > 0 && (hasStartingMarker || !openTag)) { argsOptions.Set(arg.Substring(0, p).Trim().TrimStart('-', '/'), arg.Substring(p + 1).Trim()); lastTag = null; openTag = false; } // search for tag stating with special character // a linux path should be valid: -path /home/file else if (hasStartingMarker && !(openTag && arg[0] == '/')) { lastTag = arg.Trim().TrimStart('-', '/'); argsOptions.Set(lastTag, "true"); openTag = true; } // set value of last tag else if (lastTag != null) { argsOptions.Set(lastTag, arg.Trim()); openTag = false; } } } return(argsOptions); }
/// <summary> /// Merge together FlexibleOptions instances, the last object in the list has priority in conflict resolution (overwrite).<para/> /// Merge will return a new instance of FlexibleOptions. /// </summary> /// <param name="items"></param> /// <returns>A new instance of FlexibleOptions with merged options</returns> public static FlexibleOptions Merge(params FlexibleOptions[] items) { var merge = new FlexibleOptions(); if (items == null || items.Length == 0) { return(merge); } var dic = merge.Options; for (int i = 0; i < items.Length; i++) { if (items[i] == null) { continue; } foreach (var o in items[i].Options) { dic[o.Key] = o.Value; } } return(merge); }
public FlexibleOptions ParseAppSettings() { // parse local configuration file // display the options listed in the configuration file var localOptions = new FlexibleOptions(); try { var appSettings = System.Configuration.ConfigurationManager.AppSettings; foreach (var k in appSettings.AllKeys) { localOptions.Set(k, appSettings[k]); } } catch (Exception appSettingsEx) { if (ThrownOnError) { throw; } RaiseErrorEvent(appSettingsEx); } return(localOptions); }
/// <summary> /// Initializes a new instance of the <see cref="FlexibleOptions" /> class. /// </summary> /// <param name="instance">Another FlexibleObject instance to be cloned.</param> /// <param name="caseInsensitive">If the intenal dictionary should have case insensitive keys.</param> public FlexibleOptions(FlexibleOptions instance, bool caseInsensitive) { _caseInsensitive = caseInsensitive; Options = new Dictionary <string, string> (instance.Options, _caseInsensitive ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); }
/// <summary> /// Checks the command line params.<para/> /// arguments format: key=value or --key value /// </summary> /// <param name="args">The args.</param> internal static FlexibleOptions CheckCommandLineParams (string[] args, bool thrownOnError) { FlexibleOptions mergedOptions = null; FlexibleOptions argsOptions = null; FlexibleOptions localOptions = new FlexibleOptions (); FlexibleOptions externalLoadedOptions = null; try { // parse local configuration file // display the options listed in the configuration file try { var appSettings = System.Configuration.ConfigurationManager.AppSettings; foreach (var k in appSettings.AllKeys) { localOptions.Set (k, appSettings[k]); } } catch (Exception appSettingsEx) { if (thrownOnError) throw; GetLogger ().Warn (appSettingsEx); } // parse console arguments // parse arguments like: key=value argsOptions = ParseCommandLineArguments (args); // merge arguments with app.config options. Priority: arguments > app.config mergedOptions = FlexibleOptions.Merge (localOptions, argsOptions); // adjust alias for web hosted configuration file if (String.IsNullOrEmpty (mergedOptions.Get ("config"))) mergedOptions.Set ("config", mergedOptions.Get ("S3ConfigurationPath", mergedOptions.Get ("webConfigurationFile"))); // load and parse web hosted configuration file (priority order: argsOptions > localOptions) string externalConfigFile = mergedOptions.Get ("config", ""); bool configAbortOnError = mergedOptions.Get ("configAbortOnError", true); if (!String.IsNullOrWhiteSpace (externalConfigFile)) { foreach (var file in externalConfigFile.Trim(' ', '\'', '"', '[', ']').Split (',', ';')) { GetLogger ().Debug ("Loading configuration file from {0} ...", externalConfigFile); externalLoadedOptions = FlexibleOptions.Merge (externalLoadedOptions, LoadExtenalConfigurationFile (file.Trim (' ', '\'', '"'), configAbortOnError)); } } } catch (Exception ex) { // initialize log before dealing with exceptions if (mergedOptions != null) InitializeLog (mergedOptions.Get ("logFilename"), mergedOptions.Get ("logLevel", "Info"), InitOptions, mergedOptions); if (thrownOnError) throw; GetLogger ().Error (ex); } // merge options with the following priority: // 1. console arguments // 2. external file with json configuration object (local or web) // 3. local configuration file (app.config or web.config) mergedOptions = FlexibleOptions.Merge (mergedOptions, externalLoadedOptions, argsOptions); // reinitialize log options if different from local configuration file InitializeLog (mergedOptions.Get ("logFilename"), mergedOptions.Get ("logLevel", "Info"), InitOptions, mergedOptions); // return final merged options ProgramOptions = mergedOptions; return mergedOptions; }
/// <summary> /// Log initialization. /// </summary> internal static void InitializeLog (string logFileName = null, string logLevel = null, InitializationOptions initOptions = null, FlexibleOptions appOptions = null) { // default parameters initialization from config file if (String.IsNullOrEmpty (logFileName)) logFileName = _logFileName ?? System.Configuration.ConfigurationManager.AppSettings["logFilename"]; if (String.IsNullOrEmpty (logFileName)) logFileName = ("${basedir}/log/" + typeof (ConsoleUtils).Namespace.Replace (".SimpleHelpers", "") + ".log"); if (String.IsNullOrEmpty (logLevel)) logLevel = _logLevel ?? (System.Configuration.ConfigurationManager.AppSettings["logLevel"] ?? "Info"); // check if log was initialized with same options if (_logFileName == logFileName && _logLevel == logLevel) return; // try to parse loglevel LogLevel currentLogLevel; try { currentLogLevel = LogLevel.FromString (logLevel); } catch { currentLogLevel = LogLevel.Info; } // save current log configuration _logFileName = logFileName; _logLevel = currentLogLevel.ToString (); // check initialization options var localOptions = initOptions != null ? initOptions.Clone () : new InitializationOptions (); // adjust options based on arguments if (appOptions != null) { if (!localOptions.DisableLogFile.HasValue && appOptions.HasOption ("DisableLogFile")) localOptions.DisableLogFile = appOptions.Get ("DisableLogFile", false); if (localOptions.EnableLogTargets == null && !String.IsNullOrEmpty (appOptions.Get ("EnableLogTargets"))) localOptions.EnableLogTargets = appOptions.GetAsList ("EnableLogTargets").Where (i => !String.IsNullOrWhiteSpace (i)).Select (i => i.Trim ()).ToArray (); if (localOptions.DisableLogTargets == null && !String.IsNullOrEmpty (appOptions.Get ("DisableLogTargets"))) localOptions.DisableLogTargets = appOptions.GetAsList ("DisableLogTargets").Where (i => !String.IsNullOrWhiteSpace (i)).Select (i => i.Trim ()).ToArray (); } // prepare list of enabled targets HashSet<string> enabledTargets; // if enabled log targets was provided, use it! if (localOptions.EnableLogTargets != null && localOptions.EnableLogTargets.Count > 0) { enabledTargets = new HashSet<string> (localOptions.EnableLogTargets, StringComparer.OrdinalIgnoreCase); } // else we remove disabled target... else { enabledTargets = new HashSet<string> (StringComparer.OrdinalIgnoreCase) { "console", "file" }; // set enabled targets if (localOptions.Targets != null) { foreach (var i in localOptions.Targets) { foreach (var n in GetNLogTargetName (i)) enabledTargets.Add (n); } } // remove disabled targets if (localOptions.DisableLogTargets != null) foreach (var i in localOptions.DisableLogTargets) enabledTargets.Remove (i); if (localOptions.DisableLogFile ?? false) enabledTargets.Remove ("file"); } // prepare log configuration var config = new NLog.Config.LoggingConfiguration (); // console output if (!Console.IsOutputRedirected && enabledTargets.Contains ("console")) { var consoleTarget = new NLog.Targets.ColoredConsoleTarget (); consoleTarget.Layout = "${longdate}\t${callsite}\t${level}\t${message}\t${onexception: \\:[Exception] ${exception:format=tostring}}"; config.AddTarget ("console", consoleTarget); var rule1 = new NLog.Config.LoggingRule ("*", LogLevel.Trace, consoleTarget); config.LoggingRules.Add (rule1); } // file output if (enabledTargets.Contains ("file")) { var fileTarget = new NLog.Targets.FileTarget (); fileTarget.FileName = logFileName; fileTarget.Layout = "${longdate}\t${callsite}\t${level}\t\"${message}${onexception: \t [Exception] ${exception:format=tostring}}\""; fileTarget.ConcurrentWrites = true; fileTarget.ConcurrentWriteAttemptDelay = 10; fileTarget.ConcurrentWriteAttempts = 8; fileTarget.AutoFlush = true; fileTarget.KeepFileOpen = true; fileTarget.DeleteOldFileOnStartup = false; fileTarget.ArchiveAboveSize = (localOptions.MaxLogFileSize > 0) ? localOptions.MaxLogFileSize : 4 * 1024 * 1024; // 4 Mb fileTarget.MaxArchiveFiles = (localOptions.MaxArchiveLogFiles > 0) ? localOptions.MaxArchiveLogFiles : 10; fileTarget.ArchiveNumbering = NLog.Targets.ArchiveNumberingMode.DateAndSequence; fileTarget.ArchiveDateFormat = "yyyyMMdd"; fileTarget.ArchiveFileName = System.IO.Path.ChangeExtension (logFileName, ".{#}" + System.IO.Path.GetExtension (logFileName)); // set file output to be async (commented out since doesn't work well on mono) // var wrapper = new NLog.Targets.Wrappers.AsyncTargetWrapper (fileTarget); config.AddTarget ("file", fileTarget); // configure log from configuration file var rule2 = new NLog.Config.LoggingRule ("*", currentLogLevel, fileTarget); config.LoggingRules.Add (rule2); } // External Log Target if (localOptions.Targets != null) { foreach (var t in localOptions.Targets) { if (GetNLogTargetName (t).Any (i => enabledTargets.Contains (i))) { config.AddTarget (t); config.LoggingRules.Add (new NLog.Config.LoggingRule ("*", currentLogLevel, t)); } } } // set configuration options LogManager.Configuration = config; }
/// <summary> /// Adds another FlexibleOptions overwriting existing conflicting values. /// </summary> /// <param name="item">The item.</param> public void AddRange(FlexibleOptions item) { AddRange(item.Options); }