internal static void Write([NotNull] Type loggerType, [NotNull] TargetWithFilterChain targetsForLevel, LogEventInfo logEvent, LogFactory logFactory) { logEvent.SetMessageFormatter(logFactory.ActiveMessageFormatter, targetsForLevel.NextInChain == null ? logFactory.SingleTargetMessageFormatter : null); #if CaptureCallSiteInfo StackTraceUsage stu = targetsForLevel.GetStackTraceUsage(); if (stu != StackTraceUsage.None) { bool attemptCallSiteOptimization = targetsForLevel.TryCallSiteClassNameOptimization(stu, logEvent); if (attemptCallSiteOptimization && targetsForLevel.TryLookupCallSiteClassName(logEvent, out string callSiteClassName)) { logEvent.CallSiteInformation.CallerClassName = callSiteClassName; } else if (attemptCallSiteOptimization || targetsForLevel.MustCaptureStackTrace(stu, logEvent)) { CaptureCallSiteInfo(logFactory, loggerType, logEvent, stu); if (attemptCallSiteOptimization) { targetsForLevel.TryRememberCallSiteClassName(logEvent); } } } #endif AsyncContinuation exceptionHandler = SingleCallContinuation.Completed; if (logFactory.ThrowExceptions) { int originalThreadId = AsyncHelpers.GetManagedThreadId(); exceptionHandler = ex => { if (ex != null && AsyncHelpers.GetManagedThreadId() == originalThreadId) { throw new NLogRuntimeException("Exception occurred in NLog", ex); } }; } IList <Filter> prevFilterChain = null; FilterResult prevFilterResult = FilterResult.Neutral; for (var t = targetsForLevel; t != null; t = t.NextInChain) { FilterResult result = ReferenceEquals(prevFilterChain, t.FilterChain) ? prevFilterResult : GetFilterResult(t.FilterChain, logEvent, t.DefaultResult); if (!WriteToTargetWithFilterChain(t.Target, result, logEvent, exceptionHandler)) { break; } prevFilterResult = result; // Cache the result, and reuse it for the next target, if it comes from the same logging-rule prevFilterChain = t.FilterChain; } }