예제 #1
0
        internal static void Write([NotNull] Type loggerType, TargetWithFilterChain targets, LogEventInfo logEvent, LogFactory factory)
        {
            if (targets == null)
            {
                return;
            }

            StackTraceUsage stu = targets.GetStackTraceUsage();

            if (stu != StackTraceUsage.None && !logEvent.HasStackTrace)
            {
                StackTrace stackTrace;
#if !SILVERLIGHT
                stackTrace = new StackTrace(StackTraceSkipMethods, stu == StackTraceUsage.WithSource);
#else
                stackTrace = new StackTrace();
#endif

                int firstUserFrame = FindCallingMethodOnStackTrace(stackTrace, loggerType);

                logEvent.SetStackTrace(stackTrace, firstUserFrame);
            }

            ExceptionHandlerContinuation handler;
            int numberOfTargets = 0;

            for (var t = targets; t != null; t = t.NextInChain)
            {
                FilterResult result = GetFilterResult(t.FilterChain, logEvent);

                if ((result == FilterResult.Ignore) || (result == FilterResult.IgnoreFinal))
                {
                    if (InternalLogger.IsDebugEnabled)
                    {
                        InternalLogger.Debug(
                            "{0}.{1} Rejecting message because of a filter.",
                            logEvent.LoggerName,
                            logEvent.Level);
                    }

                    if (result == FilterResult.IgnoreFinal)
                    {
                        break;
                    }
                }
                else
                {
                    numberOfTargets += 1;
                }
            }

            if (factory.Configuration.PoolingEnabled())
            {
                handler = factory.Configuration.PoolFactory.Get <ExceptionHandlerPool, ExceptionHandlerContinuation>().Get(Thread.CurrentThread.ManagedThreadId, factory.ThrowExceptions);
            }
            else
            {
                handler = new ExceptionHandlerContinuation(Thread.CurrentThread.ManagedThreadId, factory.ThrowExceptions);
            }

            bool clone = numberOfTargets > 1;

            // Clone a message for each target, so that each target can put it back into the pool when its done with it.

            for (var t = targets; t != null; t = t.NextInChain)
            {
                if (!WriteToTargetWithFilterChain(t, logEvent, handler.Delegate, clone))
                {
                    break;
                }
            }


            // No targets at all wanted this log event, so put it back into the pool
            if (numberOfTargets == 0 || clone)
            {
                logEvent.PutBack();
            }
        }