/// <summary>
        /// Writes a notification for the specified <see cref="AggregatedAlert"/>.
        /// </summary>
        /// <param name="aggregatedAlert">An <see cref="AggregatedAlert"/> that should be written to the notification.</param>
        public void WriteAggregatedAlert(AggregatedAlert aggregatedAlert)
        {
            if (_tabLevel <= 1)
            {
                throw new InvalidOperationException("A status range must be entered before aggregated alerts can be written!");
            }

            StatusAuditAlert  auditAlert = aggregatedAlert.CommonAlert ?? StatusAuditAlert.None;
            StatusRatingRange range      = StatusRating.FindRange(auditAlert.Rating);
            string            rangeName  = StatusRating.GetRangeName(range);
            string            rangeColor = StatusRating.GetRangeForegroundColor(auditAlert.Rating);
            string            rgbColor   = StatusRating.GetRatingRgbForegroundColor(aggregatedAlert.RatingSum / aggregatedAlert.Sources.Count);

            List <StatusPropertyRange> propertyRanges = aggregatedAlert.PropertyRanges;

            OpenHeader(_details, _terse, _tabLevel, (StatusRatingRange)(-1), rgbColor);

            _terse.Append(aggregatedAlert.Target + ": " + aggregatedAlert.TerseSources + "->");

#if RAWRATINGS
            _details.Append("[RATING=" + auditAlert.Rating.ToString(DebugRatingFloatFormat) + "] ");
#endif
            _details.Append(aggregatedAlert.Target + ": " + aggregatedAlert.DetailsSources + " reporting: ");

            // multi-line alert details or properties to list?
            if ((aggregatedAlert.CommonAlert?.Details != null && (aggregatedAlert.CommonAlert.Details.Contains("<br/>", StringComparison.Ordinal) || aggregatedAlert.CommonAlert.Details.Contains("</div>", StringComparison.Ordinal))) || (propertyRanges != null && propertyRanges.Count > 0))
            {
                CloseHeader(_details, _terse, _tabLevel);

                EnterTabLevel();
                OpenHeader(_details, _terse, _tabLevel, (StatusRatingRange)(-1), rgbColor);

                _terse.Append(RenderTerse(auditAlert.Terse).Replace("\n", "\n" + new string(' ', _tabLevel), StringComparison.Ordinal));
                _details.AppendLine(RenderDetails(auditAlert.Details));

                CloseHeader(_details, _terse, _tabLevel);

                // are there properties?
                if (propertyRanges != null && propertyRanges.Count > 0)
                {
                    _details.Append(" because");
                    foreach (StatusPropertyRange propertyRange in aggregatedAlert.PropertyRanges)
                    {
                        OpenHeader(_details, _terse, _tabLevel, (StatusRatingRange)(-1), rgbColor);
                        _terse.Append(propertyRange.ToString());
                        _details.AppendLine(propertyRange.ToString());
                        CloseHeader(_details, _terse, _tabLevel);
                    }
                }
                LeaveTabLevel();
            }
            else
            {
                _terse.Append(RenderTerse(auditAlert.Terse));
                _details.Append(' ');
                _details.Append(RenderDetails(auditAlert.Details));
                CloseHeader(_details, _terse, _tabLevel);
            }
        }
示例#2
0
        /// <summary>
        /// Gets a string representation of this object.
        /// </summary>
        /// <returns>A string representation of this object.</returns>
        public override string ToString()
        {
            StringBuilder output = new StringBuilder();

            output.Append('@');
            output.Append(_auditStartTime.ToShortTimeString().Replace(" ", "", StringComparison.Ordinal));
            if (_alert != null)
            {
                output.Append(':');
                output.Append(StatusRating.GetRangeName(_alert.Rating));
                if (!string.IsNullOrEmpty(_alert.Terse))
                {
                    output.Append('(');
                    output.Append(_alert.Terse);
                    output.Append(')');
                }
            }
            return(output.ToString());
        }
        /// <summary>
        /// Enters a status range section for the range indicated by the rating.
        /// Should be matched by a subsequent call to <see cref="LeaveStatusRange"/>.
        /// </summary>
        /// <param name="rating">The status rating.</param>
        public void EnterStatusRange(float rating)
        {
            StatusRatingRange range      = StatusRating.FindRange(rating);
            string            rangeName  = StatusRating.GetRangeName(range);
            string            rangeColor = StatusRating.GetRangeForegroundColor(range);

            if (_tabLevel > 1)
            {
                throw new InvalidOperationException("All targets and status ranges must be closed before entering a new status range!");
            }

            _details.Append("<div class=\"");
#pragma warning disable CA1308 // this is to convert the range name from the C# style casing (Pascal) to the HTML style casing (kebab)
            _details.Append(rangeName.ToLowerInvariant());
#pragma warning restore CA1308
            _details.Append("-range\">");

            OpenHeader(_details, _terse, _tabLevel, range, rangeColor);
            _currentSectionRatingRange = range;

            _terse.Append(rangeName.ToUpperInvariant());
            _details.Append(StatusRating.GetRangeSymbol(range));
            _details.Append(' ');
            _details.Append(rangeName);

            if (_notificationTime != null)
            {
                _terse.Append(" @");
                _terse.Append(_notificationTime.Value.ToShortTimeString());
                _details.Append(" at ");
                _details.Append(_notificationTime.Value.ToLongTimeString());
                _notificationTime = null;
            }

            CloseHeader(_details, _terse, _tabLevel);

            EnterTabLevel();
        }