Ejemplo n.º 1
0
        private void SendAlertSignalEmail(InternalSignal signal, NamedValueSet props)
        {
            try
            {
                var smtpHost = props.GetValue <string>(AlertRule.MailHost);
                IEnumerable <string> recipients = ResolveMultipleEmailAddresses(props.GetArray <string>(AlertRule.MailTo));
                string sender      = ResolveSingleEmailAddress(props.GetValue <string>(AlertRule.MailFrom));
                var    email       = new MailMessage();
                string instanceMsg = GetInstanceMsg(signal.ReminderCount);
                signal.ReminderCount += 1;
                email.Subject         =
                    $"QDS Alert {EnvHelper.EnvName(IntClient.Target.ClientInfo.ConfigEnv)}. {signal.RuleName}: {signal.Status}";

                if (signal.Status == AlertStatus.Alerted)
                {
                    email.Subject += $"({instanceMsg})";
                }
                var body = new StringBuilder(signal.SignalMessage);
                if (props.GetValue <bool>("rule.DebugEnabled", false))
                {
                    body.AppendLine();
                    body.AppendLine();
                    body.AppendLine("[debug-begin]");
                    props.LogValues(text => body.AppendLine("  " + text));
                    body.AppendLine("[debug-end]");
                }
                email.Body = body.ToString();
                SendEmail(smtpHost, email, sender, recipients);
            }
            catch (Exception excp)
            {
                ReportUncaughtError("EmailAlertSignal", signal.RuleName, excp, props);
            }
        }
Ejemplo n.º 2
0
 protected override void OnCloseCallback()
 {
     try
     {
         // server shutting down
         // - publish all rule status as Undefined
         DateTimeOffset now = DateTimeOffset.Now;
         foreach (InternalRule rule in _ruleStore.Values)
         {
             try
             {
                 var signal = new InternalSignal
                 {
                     RuleName      = rule.RuleName,
                     AlertServer   = IntClient.Target.ClientInfo.HostName,
                     Status        = AlertStatus.Undefined,
                     LastMonitored = now,
                     SignalMessage = "AlertServer shutdown"
                 };
                 PublishAlertSignal(signal);
             }
             catch (Exception ex)
             {
                 ReportUncaughtError("OnCloseCallback", rule.RuleName, ex, null);
             }
         } // foreach rule
     }
     catch (Exception ex)
     {
         ReportUncaughtError("OnCloseCallback", null, ex, null);
     }
 }
Ejemplo n.º 3
0
        private void PublishAlertSignal(InternalSignal signal)
        {
            AlertSignal item = signal.AsAlertSignal();

            IntClient.Target.SaveObject(item, item.ItemName, item.ItemProps, TimeSpan.MaxValue);
        }
Ejemplo n.º 4
0
        private void ProcessAllRules()
        {
            // note: no locks required - as we are inside main Dispatcher
            try
            {
                // publish latest rule status
                DateTimeOffset asAtTime = DateTimeOffset.Now;
                foreach (InternalRule rule in _ruleStore.Values)
                {
                    var props = new NamedValueSet();
                    try
                    {
                        if ((rule.LastMonitored + rule.MonitorPeriod) < asAtTime)
                        {
                            // update LastMonitored first to prevent infinite looping
                            // when there are repeated expression evaluation exceptions
                            rule.LastMonitored = asAtTime;
                            // build property set
                            string   smtpServer = rule.Properties.GetString(AlertRule.MailHost, null) ?? _defaultSmtpServer;
                            string   mailFrom   = rule.Properties.GetString(AlertRule.MailFrom, null) ?? _defaultMailFrom;
                            string[] recipients = rule.Properties.GetArray <string>(AlertRule.MailTo) ?? _defaultMailTo;
                            props.Set(AlertRule.MailHost, smtpServer);
                            props.Set(AlertRule.MailFrom, mailFrom);
                            props.Set(AlertRule.MailTo, recipients);
                            props.Set("host.AsAtTime", asAtTime);
                            props.Set("host.HostName", IntClient.Target.ClientInfo.HostName);
                            props.Set("rule.DebugEnabled", rule.Properties.GetValue <bool>("DebugEnabled", false));
                            props.Set("rule.RuleName", rule.RuleName);
                            props.Set("rule.Disabled", rule.Disabled);
                            props.Set("rule.DataSubsExpr", rule.DataSubsExpr.DisplayString());
                            props.Set("rule.Constraint", rule.Constraint.DisplayString());
                            props.Set("rule.Condition", rule.Condition.DisplayString());
                            props.Set("rule.MonitorPeriod", rule.MonitorPeriod);
                            props.Add(rule.Properties);
                            if (rule.CurrentReceivedItem != null)
                            {
                                props.Add(rule.CurrentReceivedItem.AppProps);
                                props.Set("item.IsNotNull", true);
                            }
                            else
                            {
                                // no item received
                                props.Set("item.IsNotNull", false);
                            }
                            AlertStatus newStatus;
                            string      statusMessage;
                            var         signal = new InternalSignal
                            {
                                RuleName    = rule.RuleName,
                                AlertServer = IntClient.Target.ClientInfo.HostName
                            };
                            if (rule.Disabled)
                            {
                                newStatus     = AlertStatus.Disabled;
                                statusMessage = "the rule is disabled";
                            }
                            else
                            {
                                // extend constraint
                                ICoreItem item       = rule.CurrentReceivedItem;
                                object    constraint = (item == null)
                                    ? rule.Constraint.Evaluate(props, null, DateTimeOffset.MinValue, DateTimeOffset.MinValue, asAtTime)
                                    : rule.Constraint.Evaluate(props, item.Name, item.Created, item.Expires, asAtTime);
                                if (Expr.CastTo(constraint, false))
                                {
                                    object condition = item == null
                                        ? rule.Condition.Evaluate(props, null, DateTimeOffset.MinValue, DateTimeOffset.MinValue, asAtTime)
                                        : rule.Condition.Evaluate(props, item.Name, item.Created, item.Expires, asAtTime);

                                    if (Expr.CastTo(condition, false))
                                    {
                                        newStatus     = AlertStatus.Alerted;
                                        statusMessage = rule.SignalFormat;
                                    }
                                    else
                                    {
                                        newStatus     = AlertStatus.AllClear;
                                        statusMessage = "the condition is no longer active";
                                    }
                                }
                                else
                                {
                                    newStatus     = AlertStatus.Inactive;
                                    statusMessage = "the constraint is no longer satisfied";
                                }
                            }
                            props.Set("rule.Status", newStatus.ToString());
                            signal.Status        = newStatus;
                            signal.LastMonitored = asAtTime;
                            signal.ReminderCount = 0;
                            if (rule.LastSignal != null)
                            {
                                signal.ReminderCount = rule.LastSignal.ReminderCount;
                            }
                            if (newStatus == AlertStatus.Alerted)
                            {
                                signal.SignalMessage = props.ReplaceTokens(statusMessage);
                            }
                            else
                            {
                                signal.SignalMessage =
                                    $"The previous alert message sent from this server ({signal.AlertServer}) " +
                                    $"for this rule ({signal.RuleName}) has been withdrawn because {statusMessage}.";
                            }
                            // set instance (repeat) count
                            if (newStatus != rule.LastStatus)
                            {
                                signal.ReminderCount = 0;
                            }
                            if ((newStatus != rule.LastStatus) || ((rule.LastPublished + rule.PublishPeriod) < asAtTime))
                            {
                                rule.LastPublished = asAtTime;
                                // publish signal
                                PublishAlertSignal(signal);
                                // email signal if status is or was alerted
                                if ((newStatus == AlertStatus.Alerted) || (rule.LastStatus == AlertStatus.Alerted))
                                {
                                    Logger.LogInfo(
                                        "Rule '{0}' {1}: {2}", signal.RuleName, signal.Status, signal.SignalMessage);
                                    SendAlertSignalEmail(signal, props);
                                }
                            }
                            // done
                            rule.LastStatus = newStatus;
                            rule.LastSignal = signal;
                        }
                    }
                    catch (Exception ex)
                    {
                        ReportUncaughtError("MainCallback", rule.RuleName, ex, props);
                    }
                } // foreach rule
            }
            catch (Exception ex)
            {
                ReportUncaughtError("MainCallback", null, ex, null);
            }
        }