예제 #1
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
                    {
                        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);
                }
예제 #2
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();
            }
        }