Esempio n. 1
0
        public static int Run <T>(string[] args, DebuggerAttachPoints attachPoints, uint timeout = 30) where T : ModularInput, new()
        {
            if (!IsAttachPointNone(attachPoints) && timeout == 0)
            {
                throw new ArgumentOutOfRangeException("timeout", timeout, "Timeout parameter must be greater than or equal to 1 second");
            }

            T          script = new T();
            Task <int> run    = script.RunAsync(args, _stdin, _stdout, _stderr, null, attachPoints, timeout);

            run.Wait();
            if (run.IsCompleted)
            {
                return(run.Result);
            }

            return(-1);
        }
Esempio n. 2
0
        internal static bool ShouldWaitForDebuggerToAttach(string[] args, DebuggerAttachPoints attachPoints)
        {
            if (IsAttachPointNone(attachPoints))
            {
                return(false);
            }

            if (args.Length > 0)
            {
                if (IsValidateArguments(args, attachPoints))
                {
                    return(true);
                }
            }
            else if (IsStreamEvents(attachPoints))
            {
                return(true);
            }

            return(false);
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
 private static bool IsValidateArguments(string[] args, DebuggerAttachPoints attachPoints)
 {
     return(args[0].ToLower().Equals("--validate-arguments") &&
            ((attachPoints & DebuggerAttachPoints.ValidateArguments) == DebuggerAttachPoints.ValidateArguments));
 }
Esempio n. 5
0
 private static bool IsStreamEvents(DebuggerAttachPoints attachPoints)
 {
     return((attachPoints & DebuggerAttachPoints.StreamEvents) == DebuggerAttachPoints.StreamEvents);
 }
Esempio n. 6
0
 private static bool IsAttachPointNone(DebuggerAttachPoints attachPoints)
 {
     return(attachPoints == DebuggerAttachPoints.None);
 }
Esempio n. 7
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);
                }