Example #1
0
        /// <summary>Determines whether the exception should be logged.</summary>
        /// <param name="context">The exception logger context.</param>
        /// <returns>
        /// <see langword="true"/> if the exception should be logged; otherwise, <see langword="false"/>.
        /// </returns>
        /// <remarks>
        /// The default decision is only to log an exception instance the first time it is seen by this logger.
        /// </remarks>
        public virtual bool ShouldLog(ExceptionLoggerContext context)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            ExceptionContext exceptionContext = context.ExceptionContext;
            ExceptionDispatchInfo exceptionInfo = exceptionContext.ExceptionInfo;

            if (exceptionInfo == null)
            {
                throw Error.Argument("context", Resources.TypePropertyMustNotBeNull, typeof(ExceptionContext).Name, "ExceptionInfo");
            }

            Exception exception = exceptionInfo.SourceException;
            IDictionary data = exception.Data;

            if (data == null || data.IsReadOnly)
            {
                // If the exception doesn't have a mutable Data collection, we can't prevent duplicate logging. In this
                // case, just log every time.
                return true;
            }

            ICollection<object> loggedBy;

            if (data.Contains(LoggedByKey))
            {
                object untypedLoggedBy = data[LoggedByKey];

                loggedBy = untypedLoggedBy as ICollection<object>;

                if (loggedBy == null)
                {
                    // If exception.Data["MS_LoggedBy"] exists but is not of the right type, we can't prevent duplicate
                    // logging. In this case, just log every time.
                    return true;
                }

                if (loggedBy.Contains(this))
                {
                    // If this logger has already logged this exception, don't log again.
                    return false;
                }
            }
            else
            {
                loggedBy = new List<object>();
                data.Add(LoggedByKey, loggedBy);
            }

            // Either loggedBy did not exist before (we just added it) or it already existed of the right type and did
            // not already contain this logger. Log now, but mark not to log this exception again for this logger.
            Contract.Assert(loggedBy != null);
            loggedBy.Add(this);
            return true;
        }
        /// <summary>Calls an exception logger.</summary>
        /// <param name="logger">The unhandled exception logger.</param>
        /// <param name="context">The exception context.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <returns>A task representing the asynchronous exception logging operation.</returns>
        public static Task LogAsync(this IExceptionLogger logger, ExceptionContext context, CancellationToken cancellationToken)
        {
            if (logger == null)
            {
                throw Error.ArgumentNull("logger");
            }

            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            ExceptionLoggerContext loggerContext = new ExceptionLoggerContext(context);
            return logger.LogAsync(loggerContext, cancellationToken);
        }
        public Task LogAsync(ExceptionLoggerContext context, CancellationToken cancellationToken)
        {
            List<Task> tasks = new List<Task>();

            Contract.Assert(this.loggers != null);

            foreach (IExceptionLogger logger in this.loggers)
            {
                if (logger == null)
                {
                    throw Error.InvalidOperation(Resources.TypeInstanceMustNotBeNull, typeof(IExceptionLogger).Name);
                }

                Task task = logger.LogAsync(context, cancellationToken);
                tasks.Add(task);
            }

            return Task.WhenAll(tasks);
        }
Example #4
0
        /// <inheritdoc />
        Task IExceptionLogger.LogAsync(ExceptionLoggerContext context, CancellationToken cancellationToken)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            ExceptionContext exceptionContext = context.ExceptionContext;

            if (exceptionContext.ExceptionInfo == null)
            {
                throw Error.Argument("context", Resources.TypePropertyMustNotBeNull, typeof(ExceptionContext).Name, "ExceptionInfo");
            }

            if (!this.ShouldLog(context))
            {
                return TaskHelpers.Completed();
            }

            return this.LogAsync(context, cancellationToken);
        }
Example #5
0
 /// <summary>When overridden in a derived class, logs the exception synchronously.</summary>
 /// <param name="context">The exception logger context.</param>
 public virtual void Log(ExceptionLoggerContext context)
 {
 }
Example #6
0
 /// <summary>When overridden in a derived class, logs the exception asynchronously.</summary>
 /// <param name="context">The exception logger context.</param>
 /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
 /// <returns>A task representing the asynchronous exception logging operation.</returns>
 public virtual Task LogAsync(ExceptionLoggerContext context, CancellationToken cancellationToken)
 {
     this.Log(context);
     return TaskHelpers.Completed();
 }