/// <summary> /// Performs the action specified by the <paramref name="args"/> parameter. /// </summary> /// <param name="args"> /// Command-line arguments provided by Splunk when it invokes the /// modular input program. Implementers should pass the arguments to /// the main method of the program as the value of this parameter. /// </param> /// <returns> /// <param name="stdin"> /// Reader to use for the stdin stream /// </param> /// <param name="stdout"> /// Writer to use for the stdout stream /// </param> /// <param name="stderr"> /// Writer to use for the stderr stream /// </param> /// <param name="progress"> /// Reports back progress as events are written to the <see cref="EventWriter"/> /// </param> /// <param name="attachPoints"> /// Defines the <see cref="DebuggerAttachPoints"/> for this input /// </param> /// <param name="timeout"> /// Number of seconds to wait for a debugger to attach before continuing processing. /// </param> /// A value which should be used as the exit code from the modular /// input program. A value of <c>0</c> indicates success. A non-zero /// value indicates failure. /// </returns> /// <remarks> /// If the <paramref name="args"/> are not in the supported set of values, /// the method will do nothing and return a non-zero value. Any /// exceptions and internal progress messages encountered during /// execution are written to the splunkd log file. /// </remarks> public async Task <int> RunAsync(string[] args, TextReader stdin = null, TextWriter stdout = null, TextWriter stderr = null, IProgress <EventWrittenProgressReport> progress = null, DebuggerAttachPoints attachPoints = DebuggerAttachPoints.None, uint timeout = 0 ) { EventWriter writer = null; string name = this.GetType().FullName; try { /// Console default is OEM text encoding, which is not handled by Splunk, //// resulting in loss of chars such as O with an umlaut (\u0150) //// Splunk's default is UTF8. if (stdin == null) { stdin = Console.In; Console.InputEncoding = Encoding.UTF8; } if (stdout == null) { stdout = Console.Out; Console.OutputEncoding = Encoding.UTF8; } if (stderr == null) { stderr = Console.Error; Console.OutputEncoding = Encoding.UTF8; } if (progress == null) { progress = new Progress <EventWrittenProgressReport>(); } writer = new EventWriter(stdout, stderr, progress); // Check if the developer has specified they want to attach a debugger bool wait = ShouldWaitForDebuggerToAttach(args, attachPoints); // If a debugger is going to attach if (wait) { WaitForAttach(timeout); } if (args.Length == 0) { try { var serializer = new XmlSerializer(typeof(InputDefinitionCollection)); var inputDefinitions = (InputDefinitionCollection)serializer.Deserialize(stdin); var instances = new List <Task>(); foreach (InputDefinition inputDefinition in inputDefinitions) { var inputTask = this.StreamEventsAsync(inputDefinition, writer); instances.Add(inputTask); # pragma warning disable 4014 inputTask.ContinueWith(t => { if (inputTask.Exception != null) { var message = RemoveNewLines(inputTask.Exception.InnerException.ToString()); writer.LogAsync(Severity.Fatal, string.Format("Exception during streaming: name={0} | {1}", inputDefinition.Name, message)).Wait(); } }); # pragma warning restore 4014 } try { await Task.WhenAll(instances.ToArray()); } catch { } await writer.CompleteAsync(); } catch (Exception e) { var message = RemoveNewLines(e.ToString()); writer.LogAsync(Severity.Fatal, string.Format("Exception during streaming: name={0} | {1}", name, message)).Wait(); return(-1); } return(0); }
/// <summary> /// Performs the action specified by the <paramref name="args"/> parameter. /// </summary> /// <param name="args"> /// Command-line arguments provided by Splunk when it invokes the /// modular input program. Implementers should pass the arguments to /// the main method of the program as the value of this parameter. /// </param> /// <returns> /// <param name="stdin"> /// Reader to use for the stdin stream /// </param> /// <param name="stdout"> /// Writer to use for the stdout stream /// </param> /// <param name="stderr"> /// Writer to use for the stderr stream /// </param> /// <param name="progress"> /// Reports back progress as events are written to the <see cref="EventWriter"/> /// </param> /// <param name="attachPoints"> /// Defines the <see cref="DebuggerAttachPoints"/> for this input /// </param> /// <param name="timeout"> /// Number of seconds to wait for a debugger to attach before continuing processing. /// </param> /// A value which should be used as the exit code from the modular /// input program. A value of <c>0</c> indicates success. A non-zero /// value indicates failure. /// </returns> /// <remarks> /// If the <paramref name="args"/> are not in the supported set of values, /// the method will do nothing and return a non-zero value. Any /// exceptions and internal progress messages encountered during /// execution are written to the splunkd log file. /// </remarks> public async Task <int> RunAsync(string[] args, TextReader stdin = null, TextWriter stdout = null, TextWriter stderr = null, IProgress <EventWrittenProgressReport> progress = null, DebuggerAttachPoints attachPoints = DebuggerAttachPoints.None, uint timeout = 0 ) { EventWriter writer = null; string name = this.GetType().FullName; try { /// Console default is OEM text encoding, which is not handled by Splunk, //// resulting in loss of chars such as O with an umlaut (\u0150) //// Splunk's default is UTF8. if (stdin == null) { stdin = Console.In; Console.InputEncoding = Encoding.UTF8; } if (stdout == null) { stdout = Console.Out; Console.OutputEncoding = Encoding.UTF8; } if (stderr == null) { stderr = Console.Error; Console.OutputEncoding = Encoding.UTF8; } if (progress == null) { progress = new Progress <EventWrittenProgressReport>(); } writer = new EventWriter(stdout, stderr, progress); // Check if the developer has specified they want to attach a debugger bool wait = ShouldWaitForDebuggerToAttach(args, attachPoints); // If a debugger is going to attach if (wait) { WaitForAttach(timeout); } if (args.Length == 0) { try { List <Task> instances = new List <Task>(); InputDefinitionCollection inputDefinitions = (InputDefinitionCollection) new XmlSerializer(typeof(InputDefinitionCollection)). Deserialize(stdin); foreach (InputDefinition inputDefinition in inputDefinitions) { var inputTask = this.StreamEventsAsync(inputDefinition, writer); instances.Add(inputTask); var inputName = inputDefinition.Name; inputTask.ContinueWith(t => { if (inputTask.Exception != null) { var message = RemoveNewLines(inputTask.Exception.InnerException.ToString()); writer.LogAsync(Severity.Fatal, string.Format("Exception during streaming: name={0} | {1}", inputName, message)) .Wait(); } }); } try { await Task.WhenAll(instances.ToArray()); } catch { } await writer.CompleteAsync(); } catch (Exception e) { var message = RemoveNewLines(e.ToString()); writer.LogAsync(Severity.Fatal, string.Format("Exception during streaming: name={0} | {1}", name, message)) .Wait(); return(-1); } return(0); } if (args[0].ToLower().Equals("--scheme")) { Scheme scheme = null; try { scheme = this.Scheme; if (scheme != null) { StringWriter stringWriter = new StringWriter(); new XmlSerializer(typeof(Scheme)).Serialize(stringWriter, scheme); stdout.WriteLine(stringWriter.ToString()); return(0); } throw new NullReferenceException("Scheme was null; could not serialize."); } catch (Exception e) { var message = RemoveNewLines(e.ToString()); writer.LogAsync(Severity.Fatal, string.Format("Exception getting scheme: name={0} | {1}", name, message)) .Wait(); return(-1); } finally { writer.CompleteAsync().Wait(); } } if (args[0].ToLower().Equals("--validate-arguments")) { string errorMessage = null; string inputDoc = null; try { inputDoc = await stdin.ReadToEndAsync(); inputDoc = RemoveNewLines(inputDoc); writer.LogAsync(Severity.Info, inputDoc).Wait(); Validation validation = (Validation) new XmlSerializer(typeof(Validation)). Deserialize(new StringReader(inputDoc)); name = validation.Name; bool validationSuccessful = true; Scheme scheme = this.Scheme; foreach (Argument arg in scheme.Arguments) { if (arg.ValidationDelegate != null) { if (!arg.ValidationDelegate(validation.Parameters[arg.Name], out errorMessage)) { validationSuccessful = false; break; } } } if (validationSuccessful && this.Validate(validation, out errorMessage)) { return(0); // Validation succeeded } } catch (Exception e) { var message = RemoveNewLines(e.ToString()); errorMessage = e.Message; writer.LogAsync(Severity.Fatal, string.Format("Exception during validation: name={0} | {1}", name, message)) .Wait(); } finally { writer.CompleteAsync().Wait(); } if (errorMessage != null) { using (var xmlWriter = XmlWriter.Create(stdout, new XmlWriterSettings { Async = true, ConformanceLevel = ConformanceLevel.Fragment })) { await xmlWriter.WriteStartElementAsync(prefix : null, localName : "error", ns : null); await xmlWriter.WriteElementStringAsync(prefix : null, localName : "message", ns : null, value : errorMessage); await xmlWriter.WriteEndElementAsync(); } } return(-1); } } catch (Exception e) { if (writer != null) { var message = RemoveNewLines(e.ToString()); writer.LogAsync(Severity.Error, string.Format("Exception during execution: name={0} | {1}", name, message)).Wait(); } } finally { if (writer != null) { writer.CompleteAsync().Wait(); } } await writer.LogAsync(Severity.Error, string.Format("Exception during execution: Invalid arguments: name={0}", name)); return(-1); }
/// <summary> /// Performs the action specified by the <paramref name="args"/> parameter. /// </summary> /// <param name="args"> /// Command-line arguments provided by Splunk when it invokes the /// modular input program. Implementers should pass the arguments to /// the main method of the program as the value of this parameter. /// </param> /// <returns> /// A value which should be used as the exit code from the modular /// input program. A value of <c>0</c> indicates success. A non-zero /// value indicates failure. /// </returns> /// <remarks> /// If the <paramref name="args"/> are not in the supported set of values, /// the method will do nothing and return a non-zero value. Any /// exceptions and internal progress messages encountered during /// execution are written to the splunkd log file. /// </remarks> public async Task <int> RunAsync(string[] args, TextReader stdin = null, TextWriter stdout = null, TextWriter stderr = null, IProgress <EventWrittenProgressReport> progress = null) { if (progress == null) { progress = new Progress <EventWrittenProgressReport>(); } /// Console default is OEM text encoding, which is not handled by Splunk, //// resulting in loss of chars such as O with an umlaut (\u0150) //// Splunk's default is UTF8. if (stdin == null) { stdin = Console.In; Console.InputEncoding = Encoding.UTF8; } if (stdout == null) { stdout = Console.Out; Console.OutputEncoding = Encoding.UTF8; } if (stderr == null) { stderr = Console.Error; Console.OutputEncoding = Encoding.UTF8; } EventWriter writer = new EventWriter(stdout, stderr, progress); try { if (args.Length == 0) { List <Task> instances = new List <Task>(); InputDefinitionCollection inputDefinitions = (InputDefinitionCollection) new XmlSerializer(typeof(InputDefinitionCollection)). Deserialize(stdin); foreach (InputDefinition inputDefinition in inputDefinitions) { instances.Add(this.StreamEventsAsync(inputDefinition, writer)); } await Task.WhenAll(instances.ToArray()); return(0); } else if (args[0].ToLower().Equals("--scheme")) { Scheme scheme = this.Scheme; if (scheme != null) { StringWriter stringWriter = new StringWriter(); new XmlSerializer(typeof(Scheme)).Serialize(stringWriter, scheme); stdout.WriteLine(stringWriter.ToString()); return(0); } else { throw new NullReferenceException("Scheme was null; could not serialize."); } } else if (args[0].ToLower().Equals("--validate-arguments")) { string errorMessage = null; Validation validation = (Validation) new XmlSerializer(typeof(Validation)). Deserialize(stdin); try { bool validationSuccessful = true; Scheme scheme = this.Scheme; foreach (Argument arg in scheme.Arguments) { if (arg.ValidationDelegate != null) { if (!arg.ValidationDelegate(validation.Parameters[arg.Name], out errorMessage)) { validationSuccessful = false; break; } } } if (validationSuccessful && this.Validate(validation, out errorMessage)) { return(0); // Validation succeeded } } catch (Exception) { } using (var xmlWriter = XmlWriter.Create(stdout, new XmlWriterSettings { Async = true, ConformanceLevel = ConformanceLevel.Fragment })) { await xmlWriter.WriteStartElementAsync(prefix : null, localName : "error", ns : null); await xmlWriter.WriteElementStringAsync(prefix : null, localName : "message", ns : null, value : errorMessage); await xmlWriter.WriteEndElementAsync(); } return(-1); } else { await writer.LogAsync("ERROR", "Invalid arguments to modular input."); return(-1); } } catch (Exception e) { var full = e.ToString().Replace(Environment.NewLine, " | "); writer.LogAsync(string.Format("Unhandled exception: {0}", full), "FATAL").Wait(); return(-1); } finally { writer.CompleteAsync().Wait(); } }