Beispiel #1
0
        /// <summary>
        /// Print the output and exit from the program
        /// </summary>
        public static void Finish(Boolean exception)
        {
            int executedStepCounter = StepTimingsCollection.Count();

            bool enableGlobalOutput = false;

            bool globalTimeoutOccurred = false;
            int globalTimeoutExitCode = 3;

            //contains the message to send into the standard output
            string outString = "all steps are ok";

            string serviceName = "";

            //contains the nagios performance string
            string nagiosPerformance = "";

            //contains the exit code of Al'exa
            int standardOutputExitCode = 0; //default exit code is 0, all ok

            //they will contain step with an error state
            List<String> OkStep = new List<String>();
            List<String> CriticalStep = new List<String>();
            List<String> WarningStep = new List<String>();
            List<String> TimeoutStep = new List<String>();

            //list for all steps that have not been executed
            List<UnknownStepStruct> unknownStepList = new List<UnknownStepStruct>();

            //declare the output file
            XmlDocument outputFile = new XmlDocument();

            //set the xml encoding
            XmlDeclaration xDecl = outputFile.CreateXmlDeclaration("1.0", System.Text.Encoding.UTF8.WebName, null);
            outputFile.AppendChild(xDecl);

            //add root node
            XmlElement xRoot = outputFile.CreateElement("", "output", "");
            outputFile.AppendChild(xRoot);

            try
            {
                //check if we have to write the global output into the output file
                if (Global.xmlNode.SelectSingleNode("performance").Attributes["output"].Value.ToLower() == "yes")
                    enableGlobalOutput = true;
            }
            catch{}

            if (enableGlobalOutput)
            {
                //declare the global node (and its child node) that will be written to the output file
                XmlElement global = outputFile.CreateElement("global");
                XmlElement globalPerformance = outputFile.CreateElement("performance");
                //globalPerformance.SetAttribute("start", DateTimeToUnixTimestamp(Global.startTime).ToString());d_MM_yyyy_HH.mm.ss
                globalPerformance.SetAttribute("start", Global.startTime.ToString("HH:mm:ss"));
                //globalPerformance.SetAttribute("end", DateTimeToUnixTimestamp(Global.endTime).ToString());
                globalPerformance.SetAttribute("end", Global.endTime.ToString("HH:mm:ss"));
                globalPerformance.SetAttribute("duration", Global.duration.ToString());
                XmlElement globalDate = outputFile.CreateElement("date");
                globalDate.InnerText = Global.startTime.ToString("dd/MM/yyyy");
                //set the exit code of the global node
                XmlElement globalExitcode = outputFile.CreateElement("exitcode");
                globalExitcode.InnerText = "0";

                try
                {
                    //set the name of global node
                    string globalName = Global.xmlNode.SelectSingleNode("name").InnerText;
                    global.SetAttribute("name", globalName);

                    serviceName = Global.xmlNode.SelectSingleNode("name").InnerText;
                    outString = "'" + serviceName + "' service is ok, all steps are ok";

                    //add the duration of global step to the nagios performance string
                    nagiosPerformance = nagiosPerformance + globalName + "=" + Global.duration.ToString() + "ms";
                }
                catch
                {
                    //add the duration of global step to the nagios performance string
                    nagiosPerformance = nagiosPerformance + "Global=" + Global.duration.ToString() + "ms";
                }

                try
                {
                    //set the description of global node
                    string description = Global.xmlNode.SelectSingleNode("description").InnerText;
                    global.SetAttribute("description", description);
                }
                catch { }

                //add current step to the OkStep Array
                try
                {
                    OkStep.Add(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                }
                catch
                {
                    OkStep.Add("global step;" + globalPerformance.Attributes["duration"].Value);
                }

                try
                {
                    //set global warning value into the output file
                    long warningValue = long.Parse(Global.xmlNode.SelectSingleNode("performance").Attributes["warning"].Value);
                    globalPerformance.SetAttribute("warning", warningValue.ToString());

                    //add warning threshold to the nagios performance string
                    nagiosPerformance = nagiosPerformance + ";" + warningValue.ToString();

                    //check if the global step has exceeded the warning threshold
                    if (Global.duration >= warningValue)
                    {
                        //change global exit code
                        globalExitcode.InnerText = "1";

                        //change the standard output exit code
                        standardOutputExitCode = 1;

                        //add this step to the warning steps
                        try
                        {
                            WarningStep.Add(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                        }
                        catch
                        {
                            WarningStep.Add("global step;" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                        }

                    }
                }
                catch
                {
                    //if no warning threshold is set then add only a semicolon to the nagios performance string
                    nagiosPerformance = nagiosPerformance + ";";
                }

                try
                {
                    //set global critical value into the output file
                    long criticalValue = long.Parse(Global.xmlNode.SelectSingleNode("performance").Attributes["critical"].Value);
                    globalPerformance.SetAttribute("critical", criticalValue.ToString());

                    //add critical threshold to the nagios performance string
                    nagiosPerformance = nagiosPerformance + ";" + criticalValue.ToString();

                    //check if the global step has exceeded the critical threshold
                    if (Global.duration >= criticalValue)
                    {
                        //change global exit code
                        globalExitcode.InnerText = "2";

                        //set the standard output exit code
                        standardOutputExitCode = 2;

                        //add this step to the critical steps
                        try
                        {
                            CriticalStep.Add(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                            WarningStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                        }
                        catch
                        {
                            CriticalStep.Add("global step;" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                            WarningStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                        }
                    }
                }
                catch
                {
                    //if no warning threshold is set then add only a semicolon to the nagios performance string
                    nagiosPerformance = nagiosPerformance + ";";
                }

                try
                {
                    //set global timeout value into the output file
                    long timeout = long.Parse(Global.xmlNode.SelectSingleNode("performance").Attributes["timeout.value"].Value);
                    globalPerformance.SetAttribute("timeout", timeout.ToString());

                    //check if the global step has exceeded the timeout value
                    if (Global.duration >= timeout)
                    {
                        //change global exit code
                        globalExitcode.InnerText = "3";

                        //set the standard output exit code
                        standardOutputExitCode = 3;

                        try
                        {
                            //check if user has set different exit code for the timeout
                            globalExitcode.InnerText = Global.xmlNode.SelectSingleNode("performance").Attributes["timeout.exitcode"].Value;
                            standardOutputExitCode = Int32.Parse(globalExitcode.InnerText);

                            globalTimeoutOccurred = true;
                            globalTimeoutExitCode = standardOutputExitCode;
                        }
                        catch
                        {
                        }

                        //add this step to the unknown steps
                        try
                        {
                            TimeoutStep.Add(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                            WarningStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                            CriticalStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                        }
                        catch
                        {
                            TimeoutStep.Add("global step;" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                            WarningStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                            CriticalStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                        }

                    }
                }
                catch { }

                //we don't have a min or max value for the performance data.
                //So we I to add two semicolon to avoid any kind of error on the graph
                nagiosPerformance = nagiosPerformance + ";;";

                //put together global node and global child nodes
                global.AppendChild(globalDate);
                global.AppendChild(globalPerformance);
                global.AppendChild(globalExitcode);
                xRoot.AppendChild(global);
            }

            //create a node that will contain all the steps
            XmlElement steps = outputFile.CreateElement("steps");

            //loop through all steps timings collection
            foreach (StepTiming stepTiming in StepTimingsCollection)
            {
                //variable to enable the output
                bool enableOutput = false;

                //variable to enable the data source group
                string groupName = "";
                string groupName2 = "";
                string groupName3 = "";
                bool groupEnable = false;

                try
                {
                    //check if we have to write the output of current step into the output file
                    if (stepTiming.stepNode.SelectSingleNode("performance").Attributes["output"].Value.ToLower() == "yes")
                        enableOutput = true;
                }
                catch{}

                try
                {
                    //check if we have to group the datasource
                    groupName = stepTiming.stepNode.SelectSingleNode("performance").Attributes["group"].Value.ToLower();

                    //check if we have to write the output of current step into the output file
                    if (groupName != "")
                    {
                        groupName2 = ", group is " + groupName;
                        groupName3 = " (group is " + groupName + ")";

                        groupEnable = true;
                    }
                }
                catch { }

                if (enableOutput == true) //&& groupEnable == false)
                {
                    //declare the step node (and its child node) that will be written to the output file
                    XmlElement step = outputFile.CreateElement("step");
                    XmlElement performance = outputFile.CreateElement("performance");
                    XmlElement exitcode = outputFile.CreateElement("exitcode");
                    long duration = stepTiming.stepDuration;

                    performance.SetAttribute("start", stepTiming.startTime.ToString("HH:mm:ss"));
                    performance.SetAttribute("end", stepTiming.endTime.ToString("HH:mm:ss"));
                    performance.SetAttribute("duration", duration.ToString());

                    //set the exit code of the step
                    exitcode.InnerText = "0";

                    //set the step number
                    step.SetAttribute("number", stepTiming.stepNumber.ToString());

                    string stepName = "";

                    try
                    {
                        //set the step name
                        stepName = stepTiming.stepNode.Attributes["name"].Value;
                        step.SetAttribute("name", stepName);
                    }
                    catch
                    {
                        stepName = "Step " + stepTiming.stepNumber.ToString();
                    }

                    if (groupEnable == false)
                    {
                        //add the duration of current step to the nagios performance string
                        nagiosPerformance = nagiosPerformance + " " + stepName + "=" + duration.ToString() + "ms";
                    }
                    else
                    {
                        //get the duration of the group
                        string durationOfGroupString = "";
                        int durationOfGroup = 0;

                        try
                        {
                            durationOfGroupString = Regex.Split(nagiosPerformance, groupName + "=")[1];
                            durationOfGroupString = Regex.Split(durationOfGroupString, "ms")[0];

                            durationOfGroup = Int32.Parse(durationOfGroupString);

                            nagiosPerformance = nagiosPerformance.Replace(groupName + "=" + durationOfGroup, groupName + "=" + (duration + durationOfGroup).ToString());// + " " + groupName + "=" + (duration + durationOfGroup).ToString() + "ms";

                        }
                        catch //group data source is not present, so create it
                        {
                            //add the duration of current step to the nagios performance string
                            nagiosPerformance = nagiosPerformance + " " + groupName + "=" + duration.ToString() + "ms";
                        }

                    }

                    try
                    {
                        //set the description for the current step
                        step.SetAttribute("description", stepTiming.stepNode.Attributes["description"].Value);
                    }
                    catch { }

                    //add current step to the OkStep Array
                    try
                    {
                        OkStep.Add(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                    }
                    catch
                    {
                        OkStep.Add("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                    }

                    try
                    {
                        //set warning value into the output file for the current step
                        long warningLevel = long.Parse(stepTiming.stepNode.SelectSingleNode("performance").Attributes["warning"].Value);
                        performance.SetAttribute("warning", warningLevel.ToString());

                        if (groupEnable == false)
                        {
                            //add warning threshold to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";" + warningLevel.ToString();
                        }
                        else
                        {
                            if (Regex.IsMatch(nagiosPerformance, groupName + "=.*;;;;") == false)
                            {
                                nagiosPerformance = nagiosPerformance + ";";
                            }
                        }

                        //check if the current step has exceeded the warning threshold
                        if (duration >= warningLevel)
                        {
                            //change the exit code of current step
                            exitcode.InnerText = "1";

                            //add this step to the warning steps
                            try
                            {
                                WarningStep.Add(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);

                                OkStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                            }
                            catch
                            {
                                WarningStep.Add("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);

                                OkStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                            }

                            if (standardOutputExitCode <= 1)
                            {
                                //set the standard output exit code
                                standardOutputExitCode = 1;
                            }

                        }
                    }
                    catch
                    {
                        //if no warning threshold is set then add only a semicolon to the nagios performance string
                        nagiosPerformance = nagiosPerformance + ";";
                    }

                    try
                    {
                        //set global critical value into the output file fo the current step
                        long errorLevel = long.Parse(stepTiming.stepNode.SelectSingleNode("performance").Attributes["critical"].Value);
                        performance.SetAttribute("critical", errorLevel.ToString());

                        if (groupEnable == false)
                        {
                            //add critical threshold to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";" + errorLevel.ToString();
                        }
                        else
                        {
                            if (Regex.IsMatch(nagiosPerformance, groupName + "=.*;;;;") == false)
                            {
                                nagiosPerformance = nagiosPerformance + ";";
                            }
                        }

                        //check if the current step has exceeded the critical threshold
                        if (duration >= errorLevel)
                        {
                            //change the exit code of current step
                            exitcode.InnerText = "2";

                            //add this step to the critical steps
                            try
                            {
                                CriticalStep.Add(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);

                                OkStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                                WarningStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                            }
                            catch
                            {
                                CriticalStep.Add("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);

                                OkStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                                WarningStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                            }

                            if (standardOutputExitCode <= 2)
                            {
                                //set the standard output exit code
                                standardOutputExitCode = 2;
                            }
                        }
                    }
                    catch
                    {
                        //if no warning threshold is set then add only a semicolon to the nagios performance string
                        nagiosPerformance = nagiosPerformance + ";";
                    }

                    try
                    {
                        //set the timeout value into the output file for the current step
                        long timeout = long.Parse(stepTiming.stepNode.SelectSingleNode("performance").Attributes["timeout.value"].Value);
                        performance.SetAttribute("timeout", timeout.ToString());

                        //check if the global step has exceeded the timeout value
                        if (duration >= timeout)
                        {
                            if (groupEnable == false)
                            {
                                if (ConfigUtils.OutputTimeoutHandler == 1)
                                {
                                    try
                                    {
                                        //set the step name
                                        stepName = stepTiming.stepNode.Attributes["name"].Value;

                                        nagiosPerformance = nagiosPerformance.Replace(
                                            stepName + "=" + duration.ToString() + "ms",
                                            stepName + "=0ms");
                                    }
                                    catch
                                    {
                                        nagiosPerformance = nagiosPerformance.Replace(
                                            "Step " + stepTiming.stepNumber.ToString() + "=" + duration.ToString() + "ms",
                                            "Step " + stepTiming.stepNumber.ToString() + "=0ms");
                                    }
                                }
                                else if (ConfigUtils.OutputTimeoutHandler == 2)
                                {
                                    try
                                    {
                                        //set the step name
                                        stepName = stepTiming.stepNode.Attributes["name"].Value;

                                        nagiosPerformance = nagiosPerformance.Replace(
                                            stepName + "=" + duration.ToString() + "ms",
                                            stepName + "=ms");
                                    }
                                    catch
                                    {
                                        nagiosPerformance = nagiosPerformance.Replace(
                                            "Step " + stepTiming.stepNumber.ToString() + "=" + duration.ToString() + "ms",
                                            "Step " + stepTiming.stepNumber.ToString() + "=ms");
                                    }
                                }
                            }

                            //add this step to the timeout steps
                            try
                            {
                                TimeoutStep.Add(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);

                                OkStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                                CriticalStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                                WarningStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                            }
                            catch
                            {
                                TimeoutStep.Add("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);

                                OkStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                                CriticalStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                                WarningStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                            }

                            //performance.SetAttribute("duration", duration.ToString());

                            //change global exit code
                            exitcode.InnerText = "3";

                            //set the standard output exit code
                            standardOutputExitCode = 3;

                            try
                            {
                                //check if user has set different exit code for the timeout
                                exitcode.InnerText = stepTiming.stepNode.SelectSingleNode("performance").Attributes["timeout.exitcode"].Value;
                                standardOutputExitCode = Int32.Parse(exitcode.InnerText);
                            }
                            catch
                            {
                            }
                        }
                    }
                    catch { }

                    //we don't have a min or max value for the performance data.
                    //So we I to add two semicolon to avoid any kind of error on the graph
                    if(groupEnable == false)nagiosPerformance = nagiosPerformance + ";;";

                    //put together step node and step child nodes
                    step.AppendChild(performance);
                    step.AppendChild(exitcode);
                    steps.AppendChild(step);
                }

            }

            int cnt = 0;
            foreach(XmlNode notExecutedStep in ConfigUtils.AlexaSteps)
            {
                UnknownStepStruct unknownStepStruct = new UnknownStepStruct();

                if (cnt < executedStepCounter)
                {
                    cnt++;
                    continue;
                }
                else
                {
                    bool enableOutput = false;

                    try
                    {
                        //check if we have to write the output of current step into the output file
                        if (notExecutedStep.SelectSingleNode("performance").Attributes["output"].Value.ToLower() == "yes")
                            enableOutput = true;
                    }
                    catch { }

                    if (enableOutput)
                    {
                        //standardOutputExitCode = 3;

                        if(globalTimeoutOccurred == true) standardOutputExitCode = globalTimeoutExitCode;

                        //declare the step node (and its child node) that will be written to the output file
                        XmlElement step = outputFile.CreateElement("step");
                        XmlElement performance = outputFile.CreateElement("performance");
                        XmlElement exitcode = outputFile.CreateElement("exitcode");

                        performance.SetAttribute("start", "n.a.");
                        performance.SetAttribute("end", "n.a.");
                        performance.SetAttribute("duration", "n.a.");

                        //set the exit code of the step
                        exitcode.InnerText = "3";

                        //set the step number
                        step.SetAttribute("number", (cnt + 1).ToString());

                        try
                        {
                            //set the step name
                            string stepName = notExecutedStep.Attributes["name"].Value;
                            step.SetAttribute("name", stepName);

                            unknownStepStruct.stepName = stepName + " (Step " + (cnt + 1).ToString() + ")";

                            //add the duration of current step to the nagios performance string
                            if (ConfigUtils.OutputTimeoutHandler == 2)
                            {
                                nagiosPerformance = nagiosPerformance + " " + stepName + "=ms";
                            }
                            else
                            {
                                nagiosPerformance = nagiosPerformance + " " + stepName + "=0ms";
                            }
                        }
                        catch
                        {
                            //add the duration of current step to the nagios performance string
                            if (ConfigUtils.OutputTimeoutHandler == 2)
                            {
                                nagiosPerformance = nagiosPerformance + " Step " + (cnt + 1).ToString() + "=ms";
                            }
                            else
                            {
                                nagiosPerformance = nagiosPerformance + " Step " + (cnt + 1).ToString() + "=0ms";
                            }

                            unknownStepStruct.stepName = "Step " + (cnt + 1).ToString();
                        }

                        try
                        {
                            //set warning value into the output file for the current step
                            long warningLevel = long.Parse(notExecutedStep.SelectSingleNode("performance").Attributes["warning"].Value);
                            performance.SetAttribute("warning", warningLevel.ToString());

                            //add warning threshold to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";" + warningLevel.ToString();
                        }
                        catch
                        {
                            //if no warning threshold is set then add only a semicolon to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";";
                        }

                        try
                        {
                            //set global critical value into the output file fo the current step
                            long errorLevel = long.Parse(notExecutedStep.SelectSingleNode("performance").Attributes["critical"].Value);
                            performance.SetAttribute("critical", errorLevel.ToString());

                            //add critical threshold to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";" + errorLevel.ToString();
                        }
                        catch
                        {
                            //if no warning threshold is set then add only a semicolon to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";";
                        }

                        try
                        {
                            //set the timeout value into the output file for the current step
                            long timeout = long.Parse(notExecutedStep.SelectSingleNode("performance").Attributes["timeout.value"].Value);
                            performance.SetAttribute("timeout", timeout.ToString());
                        }
                        catch { }

                        //we don't have a min or max value for the performance data.
                        //So we I to add two semicolon to avoid any kind of error on the graph
                        nagiosPerformance = nagiosPerformance + ";;";

                        //add current unknownStepStruct element to the unknownStepList
                        unknownStepList.Add(unknownStepStruct);

                        //put together step node and step child nodes
                        step.AppendChild(performance);
                        step.AppendChild(exitcode);
                        steps.AppendChild(step);
                        cnt++;
                    }
                }
            }

            //append all steps to the root node
            xRoot.AppendChild(steps);

            string CriticalString = "critical state step(s):";

            foreach (String critStep in CriticalStep)
            {
                CriticalString = CriticalString + " " + critStep.Split(';')[0] + ",";
            }

            CriticalString = CriticalString.Remove(CriticalString.Length - 1);

            string WarningString = "warning state step(s):";

            foreach (String warnStep in WarningStep)
            {
                WarningString = WarningString + " " + warnStep.Split(';')[0] + ",";
            }

            WarningString = WarningString.Remove(WarningString.Length - 1);

            string TimeoutString = "timeout state step(s):";

            foreach (String timeoutStep in TimeoutStep)
            {
                TimeoutString = TimeoutString + " " + timeoutStep.Split(';')[0] + ",";
            }

            TimeoutString = TimeoutString.Remove(TimeoutString.Length - 1);

            string unknownStepsString = "unknown state step(s):";

            foreach (UnknownStepStruct unknownStepElement in unknownStepList)
            {
                unknownStepsString = unknownStepsString + " " + unknownStepElement.stepName + ",";
            }

            unknownStepsString = unknownStepsString.Remove(unknownStepsString.Length - 1);

            if (standardOutputExitCode != 0)
            {
                outString = "";
            }

            if (exception == true)
            {
                outString = "An internal exception has occurred. Some steps may not have been executed. Please read the Al'exa.log file, ";

                standardOutputExitCode = 3;
            }

            if (TimeoutString != "timeout state step(s)")
            {
                outString = outString + TimeoutString + ", ";
            }

            if (CriticalString != "critical state step(s)")
            {
                outString = outString + CriticalString + ", ";
            }

            if (WarningString != "warning state step(s)")
            {
                outString = outString + WarningString + ", ";
            }

            if (unknownStepsString != "unknown state step(s)")
            {
                outString = outString + unknownStepsString + ", ";
            }

            if(standardOutputExitCode != 0) outString = outString.Remove(outString.Length - 2);

            //print to the console the message
            outString = outString + "|" + nagiosPerformance;

            if (standardOutputExitCode == 0)
            {
                outString = "OK: " + outString;
            }
            else if (standardOutputExitCode == 1)
            {
                if(serviceName != "")
                    outString = "WARNING: '" + serviceName + "' service has some problems: " + outString;
                else
                    outString = "WARNING: " + outString;
            }
            else if (standardOutputExitCode == 2)
            {
                if (serviceName != "")
                    outString = "CRITICAL: '" + serviceName + "' service has some problems: " + outString;
                else
                    outString = "CRITICAL: " + outString;
            }
            else if (standardOutputExitCode == 3)
            {
                if (serviceName != "")
                    outString = "UNKNOWN: '" + serviceName + "' service has some problems: " + outString;
                else
                    outString = "UNKNOWN: " + outString;
            }

            Console.WriteLine(outString);

            string detailString = "";
            foreach (String critStep in CriticalStep)
            {
                Console.WriteLine("CRITICAL: " + critStep.Split(';')[0] + ", duration is " + critStep.Split(';')[1] + " ms");
                detailString = detailString + "CRITICAL: " + critStep.Split(';')[0] + ", duration is " + critStep.Split(';')[1] + " ms\r\n";
            }

            foreach (String warningStep in WarningStep)
            {
                Console.WriteLine("WARNING: " + warningStep.Split(';')[0] + ", duration is " + warningStep.Split(';')[1] + " ms");
                detailString = detailString + "WARNING: " + warningStep.Split(';')[0] + ", duration is " + warningStep.Split(';')[1] + " ms\r\n";
            }

            foreach (String timeoutStep in TimeoutStep)
            {
                Console.WriteLine("TIMEOUT: " + timeoutStep.Split(';')[0] + ", duration is " + timeoutStep.Split(';')[1] + " ms");
                detailString = detailString + "TIMEOUT: " + timeoutStep.Split(';')[0] + ", duration is " + timeoutStep.Split(';')[1] + " ms\r\n";
            }

            foreach (UnknownStepStruct unknownStepElement in unknownStepList)
            {
                Console.WriteLine("UNKNOWN: " + unknownStepElement.stepName);
                detailString = detailString + "UNKNOWN: " + unknownStepElement.stepName + "\r\n";
            }

            foreach (String okStep in OkStep)
            {
                Console.WriteLine("OK: " + okStep.Split(';')[0] + ", duration is " + okStep.Split(';')[1] + " ms");
                detailString = detailString + "OK: " + okStep.Split(';')[0] + ", duration is " + okStep.Split(';')[1] + " ms\r\n";
            }

            //create a node that contains the data formatted for nagios
            XmlElement nagiosService = outputFile.CreateElement("nagios");
            XmlElement nagiosMessage = outputFile.CreateElement("message");
            XmlElement nagiosExitCode = outputFile.CreateElement("exitcode");

            //set the values of the nagios nodes
            nagiosMessage.InnerText = outString + /*"|" + nagiosPerformance +*/ "\r\n" + detailString;
            nagiosExitCode.InnerText = standardOutputExitCode.ToString();

            //append nagios child nodes to nagios root node
            nagiosService.AppendChild(nagiosMessage);
            nagiosService.AppendChild(nagiosExitCode);

            //append nagios root node to the xml root node
            xRoot.AppendChild(nagiosService);

            //save the output if user has set this option
            if (ConfigUtils.OutputOnFile == true)
            {
                DirectoryInfo dir = new DirectoryInfo(ConfigUtils.OutputFolder);

                //if the output directory doesn't exist then create it
                if (!Directory.Exists(dir.FullName)) dir.Create();

                //save the xml
                outputFile.Save(Path.Combine(ConfigUtils.OutputFolder, "output.xml"));
            }

            //send the e-mail
            SystemUtils.SendEmail();

            //run external scripts
            SystemUtils.RunExternalScript();

            //if the username (and other attributes) for the share is set...
            if (ConfigUtils.LogFolderUserName != "" && ConfigUtils.LogFolderPassword != "" && ConfigUtils.LogFolder.IndexOf(@"\\") != -1)
            {
                //...Disconnect from remote share
                SystemUtils.NetworkShare.Disconnect();
            }

            //exit with current exit code
            Environment.Exit(standardOutputExitCode);
        }
Beispiel #2
0
        /// <summary>
        /// Print the output and exit from the program
        /// </summary>
        public static void Finish(Boolean exception)
        {
            int executedStepCounter = StepTimingsCollection.Count();

            bool enableGlobalOutput = false;

            bool globalTimeoutOccurred = false;
            int  globalTimeoutExitCode = 3;

            //contains the message to send into the standard output
            string outString = "all steps are ok";

            string serviceName = "";

            //contains the nagios performance string
            string nagiosPerformance = "";

            //contains the exit code of Al'exa
            int standardOutputExitCode = 0; //default exit code is 0, all ok

            //they will contain step with an error state
            List <String> OkStep       = new List <String>();
            List <String> CriticalStep = new List <String>();
            List <String> WarningStep  = new List <String>();
            List <String> TimeoutStep  = new List <String>();

            //list for all steps that have not been executed
            List <UnknownStepStruct> unknownStepList = new List <UnknownStepStruct>();

            //declare the output file
            XmlDocument outputFile = new XmlDocument();

            //set the xml encoding
            XmlDeclaration xDecl = outputFile.CreateXmlDeclaration("1.0", System.Text.Encoding.UTF8.WebName, null);

            outputFile.AppendChild(xDecl);

            //add root node
            XmlElement xRoot = outputFile.CreateElement("", "output", "");

            outputFile.AppendChild(xRoot);

            try
            {
                //check if we have to write the global output into the output file
                if (Global.xmlNode.SelectSingleNode("performance").Attributes["output"].Value.ToLower() == "yes")
                {
                    enableGlobalOutput = true;
                }
            }
            catch {}

            if (enableGlobalOutput)
            {
                //declare the global node (and its child node) that will be written to the output file
                XmlElement global            = outputFile.CreateElement("global");
                XmlElement globalPerformance = outputFile.CreateElement("performance");
                //globalPerformance.SetAttribute("start", DateTimeToUnixTimestamp(Global.startTime).ToString());d_MM_yyyy_HH.mm.ss
                globalPerformance.SetAttribute("start", Global.startTime.ToString("HH:mm:ss"));
                //globalPerformance.SetAttribute("end", DateTimeToUnixTimestamp(Global.endTime).ToString());
                globalPerformance.SetAttribute("end", Global.endTime.ToString("HH:mm:ss"));
                globalPerformance.SetAttribute("duration", Global.duration.ToString());
                XmlElement globalDate = outputFile.CreateElement("date");
                globalDate.InnerText = Global.startTime.ToString("dd/MM/yyyy");
                //set the exit code of the global node
                XmlElement globalExitcode = outputFile.CreateElement("exitcode");
                globalExitcode.InnerText = "0";

                try
                {
                    //set the name of global node
                    string globalName = Global.xmlNode.SelectSingleNode("name").InnerText;
                    global.SetAttribute("name", globalName);

                    serviceName = Global.xmlNode.SelectSingleNode("name").InnerText;
                    outString   = "'" + serviceName + "' service is ok, all steps are ok";

                    //add the duration of global step to the nagios performance string
                    nagiosPerformance = nagiosPerformance + globalName + "=" + Global.duration.ToString() + "ms";
                }
                catch
                {
                    //add the duration of global step to the nagios performance string
                    nagiosPerformance = nagiosPerformance + "Global=" + Global.duration.ToString() + "ms";
                }

                try
                {
                    //set the description of global node
                    string description = Global.xmlNode.SelectSingleNode("description").InnerText;
                    global.SetAttribute("description", description);
                }
                catch { }

                //add current step to the OkStep Array
                try
                {
                    OkStep.Add(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                }
                catch
                {
                    OkStep.Add("global step;" + globalPerformance.Attributes["duration"].Value);
                }

                try
                {
                    //set global warning value into the output file
                    long warningValue = long.Parse(Global.xmlNode.SelectSingleNode("performance").Attributes["warning"].Value);
                    globalPerformance.SetAttribute("warning", warningValue.ToString());

                    //add warning threshold to the nagios performance string
                    nagiosPerformance = nagiosPerformance + ";" + warningValue.ToString();

                    //check if the global step has exceeded the warning threshold
                    if (Global.duration >= warningValue)
                    {
                        //change global exit code
                        globalExitcode.InnerText = "1";

                        //change the standard output exit code
                        standardOutputExitCode = 1;

                        //add this step to the warning steps
                        try
                        {
                            WarningStep.Add(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                        }
                        catch
                        {
                            WarningStep.Add("global step;" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                        }
                    }
                }
                catch
                {
                    //if no warning threshold is set then add only a semicolon to the nagios performance string
                    nagiosPerformance = nagiosPerformance + ";";
                }

                try
                {
                    //set global critical value into the output file
                    long criticalValue = long.Parse(Global.xmlNode.SelectSingleNode("performance").Attributes["critical"].Value);
                    globalPerformance.SetAttribute("critical", criticalValue.ToString());

                    //add critical threshold to the nagios performance string
                    nagiosPerformance = nagiosPerformance + ";" + criticalValue.ToString();

                    //check if the global step has exceeded the critical threshold
                    if (Global.duration >= criticalValue)
                    {
                        //change global exit code
                        globalExitcode.InnerText = "2";

                        //set the standard output exit code
                        standardOutputExitCode = 2;

                        //add this step to the critical steps
                        try
                        {
                            CriticalStep.Add(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                            WarningStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                        }
                        catch
                        {
                            CriticalStep.Add("global step;" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                            WarningStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                        }
                    }
                }
                catch
                {
                    //if no warning threshold is set then add only a semicolon to the nagios performance string
                    nagiosPerformance = nagiosPerformance + ";";
                }

                try
                {
                    //set global timeout value into the output file
                    long timeout = long.Parse(Global.xmlNode.SelectSingleNode("performance").Attributes["timeout.value"].Value);
                    globalPerformance.SetAttribute("timeout", timeout.ToString());

                    //check if the global step has exceeded the timeout value
                    if (Global.duration >= timeout)
                    {
                        //change global exit code
                        globalExitcode.InnerText = "3";

                        //set the standard output exit code
                        standardOutputExitCode = 3;

                        try
                        {
                            //check if user has set different exit code for the timeout
                            globalExitcode.InnerText = Global.xmlNode.SelectSingleNode("performance").Attributes["timeout.exitcode"].Value;
                            standardOutputExitCode   = Int32.Parse(globalExitcode.InnerText);

                            globalTimeoutOccurred = true;
                            globalTimeoutExitCode = standardOutputExitCode;
                        }
                        catch
                        {
                        }

                        //add this step to the unknown steps
                        try
                        {
                            TimeoutStep.Add(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                            WarningStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                            CriticalStep.Remove(global.Attributes["name"].Value + " (global step);" + globalPerformance.Attributes["duration"].Value);
                        }
                        catch
                        {
                            TimeoutStep.Add("global step;" + globalPerformance.Attributes["duration"].Value);

                            OkStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                            WarningStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                            CriticalStep.Remove("global step;" + globalPerformance.Attributes["duration"].Value);
                        }
                    }
                }
                catch { }

                //we don't have a min or max value for the performance data.
                //So we I to add two semicolon to avoid any kind of error on the graph
                nagiosPerformance = nagiosPerformance + ";;";

                //put together global node and global child nodes
                global.AppendChild(globalDate);
                global.AppendChild(globalPerformance);
                global.AppendChild(globalExitcode);
                xRoot.AppendChild(global);
            }

            //create a node that will contain all the steps
            XmlElement steps = outputFile.CreateElement("steps");

            //loop through all steps timings collection
            foreach (StepTiming stepTiming in StepTimingsCollection)
            {
                //variable to enable the output
                bool enableOutput = false;

                //variable to enable the data source group
                string groupName   = "";
                string groupName2  = "";
                string groupName3  = "";
                bool   groupEnable = false;

                try
                {
                    //check if we have to write the output of current step into the output file
                    if (stepTiming.stepNode.SelectSingleNode("performance").Attributes["output"].Value.ToLower() == "yes")
                    {
                        enableOutput = true;
                    }
                }
                catch {}


                try
                {
                    //check if we have to group the datasource
                    groupName = stepTiming.stepNode.SelectSingleNode("performance").Attributes["group"].Value.ToLower();

                    //check if we have to write the output of current step into the output file
                    if (groupName != "")
                    {
                        groupName2 = ", group is " + groupName;
                        groupName3 = " (group is " + groupName + ")";

                        groupEnable = true;
                    }
                }
                catch { }



                if (enableOutput == true) //&& groupEnable == false)
                {
                    //declare the step node (and its child node) that will be written to the output file
                    XmlElement step        = outputFile.CreateElement("step");
                    XmlElement performance = outputFile.CreateElement("performance");
                    XmlElement exitcode    = outputFile.CreateElement("exitcode");
                    long       duration    = stepTiming.stepDuration;

                    performance.SetAttribute("start", stepTiming.startTime.ToString("HH:mm:ss"));
                    performance.SetAttribute("end", stepTiming.endTime.ToString("HH:mm:ss"));
                    performance.SetAttribute("duration", duration.ToString());

                    //set the exit code of the step
                    exitcode.InnerText = "0";

                    //set the step number
                    step.SetAttribute("number", stepTiming.stepNumber.ToString());


                    string stepName = "";

                    try
                    {
                        //set the step name
                        stepName = stepTiming.stepNode.Attributes["name"].Value;
                        step.SetAttribute("name", stepName);
                    }
                    catch
                    {
                        stepName = "Step " + stepTiming.stepNumber.ToString();
                    }


                    if (groupEnable == false)
                    {
                        //add the duration of current step to the nagios performance string
                        nagiosPerformance = nagiosPerformance + " " + stepName + "=" + duration.ToString() + "ms";
                    }
                    else
                    {
                        //get the duration of the group
                        string durationOfGroupString = "";
                        int    durationOfGroup       = 0;

                        try
                        {
                            durationOfGroupString = Regex.Split(nagiosPerformance, groupName + "=")[1];
                            durationOfGroupString = Regex.Split(durationOfGroupString, "ms")[0];

                            durationOfGroup = Int32.Parse(durationOfGroupString);

                            nagiosPerformance = nagiosPerformance.Replace(groupName + "=" + durationOfGroup, groupName + "=" + (duration + durationOfGroup).ToString()); // + " " + groupName + "=" + (duration + durationOfGroup).ToString() + "ms";
                        }
                        catch                                                                                                                                            //group data source is not present, so create it
                        {
                            //add the duration of current step to the nagios performance string
                            nagiosPerformance = nagiosPerformance + " " + groupName + "=" + duration.ToString() + "ms";
                        }
                    }



                    try
                    {
                        //set the description for the current step
                        step.SetAttribute("description", stepTiming.stepNode.Attributes["description"].Value);
                    }
                    catch { }

                    //add current step to the OkStep Array
                    try
                    {
                        OkStep.Add(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                    }
                    catch
                    {
                        OkStep.Add("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                    }

                    try
                    {
                        //set warning value into the output file for the current step
                        long warningLevel = long.Parse(stepTiming.stepNode.SelectSingleNode("performance").Attributes["warning"].Value);
                        performance.SetAttribute("warning", warningLevel.ToString());

                        if (groupEnable == false)
                        {
                            //add warning threshold to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";" + warningLevel.ToString();
                        }
                        else
                        {
                            if (Regex.IsMatch(nagiosPerformance, groupName + "=.*;;;;") == false)
                            {
                                nagiosPerformance = nagiosPerformance + ";";
                            }
                        }

                        //check if the current step has exceeded the warning threshold
                        if (duration >= warningLevel)
                        {
                            //change the exit code of current step
                            exitcode.InnerText = "1";

                            //add this step to the warning steps
                            try
                            {
                                WarningStep.Add(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);

                                OkStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                            }
                            catch
                            {
                                WarningStep.Add("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);

                                OkStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                            }

                            if (standardOutputExitCode <= 1)
                            {
                                //set the standard output exit code
                                standardOutputExitCode = 1;
                            }
                        }
                    }
                    catch
                    {
                        //if no warning threshold is set then add only a semicolon to the nagios performance string
                        nagiosPerformance = nagiosPerformance + ";";
                    }

                    try
                    {
                        //set global critical value into the output file fo the current step
                        long errorLevel = long.Parse(stepTiming.stepNode.SelectSingleNode("performance").Attributes["critical"].Value);
                        performance.SetAttribute("critical", errorLevel.ToString());

                        if (groupEnable == false)
                        {
                            //add critical threshold to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";" + errorLevel.ToString();
                        }
                        else
                        {
                            if (Regex.IsMatch(nagiosPerformance, groupName + "=.*;;;;") == false)
                            {
                                nagiosPerformance = nagiosPerformance + ";";
                            }
                        }


                        //check if the current step has exceeded the critical threshold
                        if (duration >= errorLevel)
                        {
                            //change the exit code of current step
                            exitcode.InnerText = "2";

                            //add this step to the critical steps
                            try
                            {
                                CriticalStep.Add(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);

                                OkStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                                WarningStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                            }
                            catch
                            {
                                CriticalStep.Add("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);

                                OkStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                                WarningStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                            }

                            if (standardOutputExitCode <= 2)
                            {
                                //set the standard output exit code
                                standardOutputExitCode = 2;
                            }
                        }
                    }
                    catch
                    {
                        //if no warning threshold is set then add only a semicolon to the nagios performance string
                        nagiosPerformance = nagiosPerformance + ";";
                    }


                    try
                    {
                        //set the timeout value into the output file for the current step
                        long timeout = long.Parse(stepTiming.stepNode.SelectSingleNode("performance").Attributes["timeout.value"].Value);
                        performance.SetAttribute("timeout", timeout.ToString());

                        //check if the global step has exceeded the timeout value
                        if (duration >= timeout)
                        {
                            if (groupEnable == false)
                            {
                                if (ConfigUtils.OutputTimeoutHandler == 1)
                                {
                                    try
                                    {
                                        //set the step name
                                        stepName = stepTiming.stepNode.Attributes["name"].Value;

                                        nagiosPerformance = nagiosPerformance.Replace(
                                            stepName + "=" + duration.ToString() + "ms",
                                            stepName + "=0ms");
                                    }
                                    catch
                                    {
                                        nagiosPerformance = nagiosPerformance.Replace(
                                            "Step " + stepTiming.stepNumber.ToString() + "=" + duration.ToString() + "ms",
                                            "Step " + stepTiming.stepNumber.ToString() + "=0ms");
                                    }
                                }
                                else if (ConfigUtils.OutputTimeoutHandler == 2)
                                {
                                    try
                                    {
                                        //set the step name
                                        stepName = stepTiming.stepNode.Attributes["name"].Value;

                                        nagiosPerformance = nagiosPerformance.Replace(
                                            stepName + "=" + duration.ToString() + "ms",
                                            stepName + "=ms");
                                    }
                                    catch
                                    {
                                        nagiosPerformance = nagiosPerformance.Replace(
                                            "Step " + stepTiming.stepNumber.ToString() + "=" + duration.ToString() + "ms",
                                            "Step " + stepTiming.stepNumber.ToString() + "=ms");
                                    }
                                }
                            }



                            //add this step to the timeout steps
                            try
                            {
                                TimeoutStep.Add(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);

                                OkStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                                CriticalStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                                WarningStep.Remove(step.Attributes["name"].Value + " (step " + step.Attributes["number"].Value + groupName2 + ");" + performance.Attributes["duration"].Value);
                            }
                            catch
                            {
                                TimeoutStep.Add("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);

                                OkStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                                CriticalStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                                WarningStep.Remove("Step " + step.Attributes["number"].Value + groupName3 + ";" + performance.Attributes["duration"].Value);
                            }

                            //performance.SetAttribute("duration", duration.ToString());

                            //change global exit code
                            exitcode.InnerText = "3";

                            //set the standard output exit code
                            standardOutputExitCode = 3;

                            try
                            {
                                //check if user has set different exit code for the timeout
                                exitcode.InnerText     = stepTiming.stepNode.SelectSingleNode("performance").Attributes["timeout.exitcode"].Value;
                                standardOutputExitCode = Int32.Parse(exitcode.InnerText);
                            }
                            catch
                            {
                            }
                        }
                    }
                    catch { }

                    //we don't have a min or max value for the performance data.
                    //So we I to add two semicolon to avoid any kind of error on the graph
                    if (groupEnable == false)
                    {
                        nagiosPerformance = nagiosPerformance + ";;";
                    }

                    //put together step node and step child nodes
                    step.AppendChild(performance);
                    step.AppendChild(exitcode);
                    steps.AppendChild(step);
                }
            }

            int cnt = 0;

            foreach (XmlNode notExecutedStep in ConfigUtils.AlexaSteps)
            {
                UnknownStepStruct unknownStepStruct = new UnknownStepStruct();

                if (cnt < executedStepCounter)
                {
                    cnt++;
                    continue;
                }
                else
                {
                    bool enableOutput = false;

                    try
                    {
                        //check if we have to write the output of current step into the output file
                        if (notExecutedStep.SelectSingleNode("performance").Attributes["output"].Value.ToLower() == "yes")
                        {
                            enableOutput = true;
                        }
                    }
                    catch { }

                    if (enableOutput)
                    {
                        //standardOutputExitCode = 3;

                        if (globalTimeoutOccurred == true)
                        {
                            standardOutputExitCode = globalTimeoutExitCode;
                        }

                        //declare the step node (and its child node) that will be written to the output file
                        XmlElement step        = outputFile.CreateElement("step");
                        XmlElement performance = outputFile.CreateElement("performance");
                        XmlElement exitcode    = outputFile.CreateElement("exitcode");

                        performance.SetAttribute("start", "n.a.");
                        performance.SetAttribute("end", "n.a.");
                        performance.SetAttribute("duration", "n.a.");

                        //set the exit code of the step
                        exitcode.InnerText = "3";

                        //set the step number
                        step.SetAttribute("number", (cnt + 1).ToString());


                        try
                        {
                            //set the step name
                            string stepName = notExecutedStep.Attributes["name"].Value;
                            step.SetAttribute("name", stepName);

                            unknownStepStruct.stepName = stepName + " (Step " + (cnt + 1).ToString() + ")";

                            //add the duration of current step to the nagios performance string
                            if (ConfigUtils.OutputTimeoutHandler == 2)
                            {
                                nagiosPerformance = nagiosPerformance + " " + stepName + "=ms";
                            }
                            else
                            {
                                nagiosPerformance = nagiosPerformance + " " + stepName + "=0ms";
                            }
                        }
                        catch
                        {
                            //add the duration of current step to the nagios performance string
                            if (ConfigUtils.OutputTimeoutHandler == 2)
                            {
                                nagiosPerformance = nagiosPerformance + " Step " + (cnt + 1).ToString() + "=ms";
                            }
                            else
                            {
                                nagiosPerformance = nagiosPerformance + " Step " + (cnt + 1).ToString() + "=0ms";
                            }

                            unknownStepStruct.stepName = "Step " + (cnt + 1).ToString();
                        }

                        try
                        {
                            //set warning value into the output file for the current step
                            long warningLevel = long.Parse(notExecutedStep.SelectSingleNode("performance").Attributes["warning"].Value);
                            performance.SetAttribute("warning", warningLevel.ToString());

                            //add warning threshold to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";" + warningLevel.ToString();
                        }
                        catch
                        {
                            //if no warning threshold is set then add only a semicolon to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";";
                        }

                        try
                        {
                            //set global critical value into the output file fo the current step
                            long errorLevel = long.Parse(notExecutedStep.SelectSingleNode("performance").Attributes["critical"].Value);
                            performance.SetAttribute("critical", errorLevel.ToString());

                            //add critical threshold to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";" + errorLevel.ToString();
                        }
                        catch
                        {
                            //if no warning threshold is set then add only a semicolon to the nagios performance string
                            nagiosPerformance = nagiosPerformance + ";";
                        }


                        try
                        {
                            //set the timeout value into the output file for the current step
                            long timeout = long.Parse(notExecutedStep.SelectSingleNode("performance").Attributes["timeout.value"].Value);
                            performance.SetAttribute("timeout", timeout.ToString());
                        }
                        catch { }

                        //we don't have a min or max value for the performance data.
                        //So we I to add two semicolon to avoid any kind of error on the graph
                        nagiosPerformance = nagiosPerformance + ";;";

                        //add current unknownStepStruct element to the unknownStepList
                        unknownStepList.Add(unknownStepStruct);

                        //put together step node and step child nodes
                        step.AppendChild(performance);
                        step.AppendChild(exitcode);
                        steps.AppendChild(step);
                        cnt++;
                    }
                }
            }

            //append all steps to the root node
            xRoot.AppendChild(steps);

            string CriticalString = "critical state step(s):";

            foreach (String critStep in CriticalStep)
            {
                CriticalString = CriticalString + " " + critStep.Split(';')[0] + ",";
            }

            CriticalString = CriticalString.Remove(CriticalString.Length - 1);

            string WarningString = "warning state step(s):";

            foreach (String warnStep in WarningStep)
            {
                WarningString = WarningString + " " + warnStep.Split(';')[0] + ",";
            }

            WarningString = WarningString.Remove(WarningString.Length - 1);

            string TimeoutString = "timeout state step(s):";

            foreach (String timeoutStep in TimeoutStep)
            {
                TimeoutString = TimeoutString + " " + timeoutStep.Split(';')[0] + ",";
            }

            TimeoutString = TimeoutString.Remove(TimeoutString.Length - 1);

            string unknownStepsString = "unknown state step(s):";

            foreach (UnknownStepStruct unknownStepElement in unknownStepList)
            {
                unknownStepsString = unknownStepsString + " " + unknownStepElement.stepName + ",";
            }

            unknownStepsString = unknownStepsString.Remove(unknownStepsString.Length - 1);


            if (standardOutputExitCode != 0)
            {
                outString = "";
            }

            if (exception == true)
            {
                outString = "An internal exception has occurred. Some steps may not have been executed. Please read the Al'exa.log file, ";

                standardOutputExitCode = 3;
            }


            if (TimeoutString != "timeout state step(s)")
            {
                outString = outString + TimeoutString + ", ";
            }

            if (CriticalString != "critical state step(s)")
            {
                outString = outString + CriticalString + ", ";
            }

            if (WarningString != "warning state step(s)")
            {
                outString = outString + WarningString + ", ";
            }

            if (unknownStepsString != "unknown state step(s)")
            {
                outString = outString + unknownStepsString + ", ";
            }

            if (standardOutputExitCode != 0)
            {
                outString = outString.Remove(outString.Length - 2);
            }

            //print to the console the message
            outString = outString + "|" + nagiosPerformance;

            if (standardOutputExitCode == 0)
            {
                outString = "OK: " + outString;
            }
            else if (standardOutputExitCode == 1)
            {
                if (serviceName != "")
                {
                    outString = "WARNING: '" + serviceName + "' service has some problems: " + outString;
                }
                else
                {
                    outString = "WARNING: " + outString;
                }
            }
            else if (standardOutputExitCode == 2)
            {
                if (serviceName != "")
                {
                    outString = "CRITICAL: '" + serviceName + "' service has some problems: " + outString;
                }
                else
                {
                    outString = "CRITICAL: " + outString;
                }
            }
            else if (standardOutputExitCode == 3)
            {
                if (serviceName != "")
                {
                    outString = "UNKNOWN: '" + serviceName + "' service has some problems: " + outString;
                }
                else
                {
                    outString = "UNKNOWN: " + outString;
                }
            }

            Console.WriteLine(outString);


            string detailString = "";

            foreach (String critStep in CriticalStep)
            {
                Console.WriteLine("CRITICAL: " + critStep.Split(';')[0] + ", duration is " + critStep.Split(';')[1] + " ms");
                detailString = detailString + "CRITICAL: " + critStep.Split(';')[0] + ", duration is " + critStep.Split(';')[1] + " ms\r\n";
            }

            foreach (String warningStep in WarningStep)
            {
                Console.WriteLine("WARNING: " + warningStep.Split(';')[0] + ", duration is " + warningStep.Split(';')[1] + " ms");
                detailString = detailString + "WARNING: " + warningStep.Split(';')[0] + ", duration is " + warningStep.Split(';')[1] + " ms\r\n";
            }

            foreach (String timeoutStep in TimeoutStep)
            {
                Console.WriteLine("TIMEOUT: " + timeoutStep.Split(';')[0] + ", duration is " + timeoutStep.Split(';')[1] + " ms");
                detailString = detailString + "TIMEOUT: " + timeoutStep.Split(';')[0] + ", duration is " + timeoutStep.Split(';')[1] + " ms\r\n";
            }

            foreach (UnknownStepStruct unknownStepElement in unknownStepList)
            {
                Console.WriteLine("UNKNOWN: " + unknownStepElement.stepName);
                detailString = detailString + "UNKNOWN: " + unknownStepElement.stepName + "\r\n";
            }

            foreach (String okStep in OkStep)
            {
                Console.WriteLine("OK: " + okStep.Split(';')[0] + ", duration is " + okStep.Split(';')[1] + " ms");
                detailString = detailString + "OK: " + okStep.Split(';')[0] + ", duration is " + okStep.Split(';')[1] + " ms\r\n";
            }

            //create a node that contains the data formatted for nagios
            XmlElement nagiosService  = outputFile.CreateElement("nagios");
            XmlElement nagiosMessage  = outputFile.CreateElement("message");
            XmlElement nagiosExitCode = outputFile.CreateElement("exitcode");

            //set the values of the nagios nodes
            nagiosMessage.InnerText  = outString + /*"|" + nagiosPerformance +*/ "\r\n" + detailString;
            nagiosExitCode.InnerText = standardOutputExitCode.ToString();

            //append nagios child nodes to nagios root node
            nagiosService.AppendChild(nagiosMessage);
            nagiosService.AppendChild(nagiosExitCode);

            //append nagios root node to the xml root node
            xRoot.AppendChild(nagiosService);

            //save the output if user has set this option
            if (ConfigUtils.OutputOnFile == true)
            {
                DirectoryInfo dir = new DirectoryInfo(ConfigUtils.OutputFolder);

                //if the output directory doesn't exist then create it
                if (!Directory.Exists(dir.FullName))
                {
                    dir.Create();
                }

                //save the xml
                outputFile.Save(Path.Combine(ConfigUtils.OutputFolder, "output.xml"));
            }

            //send the e-mail
            SystemUtils.SendEmail();

            //run external scripts
            SystemUtils.RunExternalScript();

            //if the username (and other attributes) for the share is set...
            if (ConfigUtils.LogFolderUserName != "" && ConfigUtils.LogFolderPassword != "" && ConfigUtils.LogFolder.IndexOf(@"\\") != -1)
            {
                //...Disconnect from remote share
                SystemUtils.NetworkShare.Disconnect();
            }


            //exit with current exit code
            Environment.Exit(standardOutputExitCode);
        }