/// <summary>
        ///     Forwards the log event to one of the sub-targets.
        ///     The sub-target is randomly chosen.
        /// </summary>
        /// <param name="logEvent">The log event.</param>
        protected override void Write(AsyncLogEventInfo logEvent)
        {
            if (Targets.Count == 0)
            {
                logEvent.Continuation(null);
                return;
            }

            int selectedTarget;

            lock (random)
            {
                selectedTarget = random.Next(Targets.Count);
            }

            Targets[selectedTarget].WriteAsyncLogEvent(logEvent);
        }
        /// <summary>
        ///     Forwards the write to one of the targets from
        ///     the <see cref="NLog.Targets" /> collection.
        /// </summary>
        /// <param name="logEvent">The log event.</param>
        /// <remarks>
        ///     The writes are routed in a round-robin fashion.
        ///     The first log event goes to the first target, the second
        ///     one goes to the second target and so on looping to the
        ///     first target when there are no more targets available.
        ///     In general request N goes to Targets[N % Targets.Count].
        /// </remarks>
        protected override void Write(AsyncLogEventInfo logEvent)
        {
            if (Targets.Count == 0)
            {
                logEvent.Continuation(null);
                return;
            }

            int selectedTarget;

            lock (lockObject)
            {
                selectedTarget = currentTarget;
                currentTarget = (currentTarget + 1)%Targets.Count;
            }

            Targets[selectedTarget].WriteAsyncLogEvent(logEvent);
        }
        /// <summary>
        ///     Forwards the log event to the sub-targets until one of them succeeds.
        /// </summary>
        /// <param name="logEvent">The log event.</param>
        /// <remarks>
        ///     The method remembers the last-known-successful target
        ///     and starts the iteration from it.
        ///     If <see cref="ReturnToFirstOnSuccess" /> is set, the method
        ///     resets the target to the first target
        ///     stored in <see cref="NLog.Targets" />.
        /// </remarks>
        protected override void Write(AsyncLogEventInfo logEvent)
        {
            AsyncContinuation continuation = null;
            var tryCounter = 0;
            int targetToInvoke;

            continuation = ex =>
                               {
                                   if (ex == null)
                                   {
                                       // success
                                       lock (lockObject)
                                       {
                                           if (currentTarget != 0)
                                           {
                                               if (ReturnToFirstOnSuccess)
                                               {
                                                   InternalLogger.Debug("Fallback: target '{0}' succeeded. Returning to the first one.", Targets[currentTarget]);
                                                   currentTarget = 0;
                                               }
                                           }
                                       }

                                       logEvent.Continuation(null);
                                       return;
                                   }

                                   // failure
                                   lock (lockObject)
                                   {
                                       InternalLogger.Warn("Fallback: target '{0}' failed. Proceeding to the next one. Error was: {1}", Targets[currentTarget], ex);

                                       // error while writing, go to the next one
                                       currentTarget = (currentTarget + 1)%Targets.Count;

                                       tryCounter++;
                                       targetToInvoke = currentTarget;
                                       if (tryCounter >= Targets.Count)
                                       {
                                           targetToInvoke = -1;
                                       }
                                   }

                                   if (targetToInvoke >= 0)
                                   {
                                       Targets[targetToInvoke].WriteAsyncLogEvent(logEvent.LogEvent.WithContinuation(continuation));
                                   }
                                   else
                                   {
                                       logEvent.Continuation(ex);
                                   }
                               };

            lock (lockObject)
            {
                targetToInvoke = currentTarget;
            }

            Targets[targetToInvoke].WriteAsyncLogEvent(logEvent.LogEvent.WithContinuation(continuation));
        }
Esempio n. 4
0
        /// <summary>
        ///     Sends the
        ///     rendered logging event over the network optionally concatenating it with a newline character.
        /// </summary>
        /// <param name="logEvent">The logging event.</param>
        protected override void Write(AsyncLogEventInfo logEvent)
        {
            var address = Address.Render(logEvent.LogEvent);
            var bytes = GetBytesToWrite(logEvent.LogEvent);

            if (KeepConnection)
            {
                var sender = GetCachedNetworkSender(address);

                ChunkedSend(
                    sender,
                    bytes,
                    ex =>
                        {
                            if (ex != null)
                            {
                                InternalLogger.Error("Error when sending {0}", ex);
                                ReleaseCachedConnection(sender);
                            }

                            logEvent.Continuation(ex);
                        });
            }
            else
            {
                var sender = SenderFactory.Create(address);
                sender.Initialize();

                lock (openNetworkSenders)
                {
                    openNetworkSenders.Add(sender);
                    ChunkedSend(
                        sender,
                        bytes,
                        ex =>
                            {
                                lock (openNetworkSenders)
                                {
                                    openNetworkSenders.Remove(sender);
                                }

                                if (ex != null)
                                {
                                    InternalLogger.Error("Error when sending {0}", ex);
                                }

                                sender.Close(ex2 => { });
                                logEvent.Continuation(ex);
                            });
                }
            }
        }
        /// <summary>
        ///     Writes the specified log event to the wrapped target, retrying and pausing in case of an error.
        /// </summary>
        /// <param name="logEvent">The log event.</param>
        protected override void Write(AsyncLogEventInfo logEvent)
        {
            AsyncContinuation continuation = null;
            var counter = 0;

            continuation = ex =>
                               {
                                   if (ex == null)
                                   {
                                       logEvent.Continuation(null);
                                       return;
                                   }

                                   var retryNumber = Interlocked.Increment(ref counter);
                                   InternalLogger.Warn("Error while writing to '{0}': {1}. Try {2}/{3}", WrappedTarget, ex, retryNumber, RetryCount);

                                   // exceeded retry count
                                   if (retryNumber >= RetryCount)
                                   {
                                       InternalLogger.Warn("Too many retries. Aborting.");
                                       logEvent.Continuation(ex);
                                       return;
                                   }

                                   // sleep and try again
                                   Thread.Sleep(RetryDelayMilliseconds);
                                   WrappedTarget.WriteAsyncLogEvent(logEvent.LogEvent.WithContinuation(continuation));
                               };

            WrappedTarget.WriteAsyncLogEvent(logEvent.LogEvent.WithContinuation(continuation));
        }
Esempio n. 6
0
        /// <summary>
        ///     Writes log event to the log target. Must be overridden in inheriting
        ///     classes.
        /// </summary>
        /// <param name="logEvent">Log event to be written out.</param>
        protected virtual void Write(AsyncLogEventInfo logEvent)
        {
            try
            {
                Write(logEvent.LogEvent);
                logEvent.Continuation(null);
            }
            catch (Exception exception)
            {
                if (exception.MustBeRethrown())
                {
                    throw;
                }

                logEvent.Continuation(exception);
            }
        }
Esempio n. 7
0
        /// <summary>
        ///     Writes the log to the target.
        /// </summary>
        /// <param name="logEvent">Log event to write.</param>
        public void WriteAsyncLogEvent(AsyncLogEventInfo logEvent)
        {
            lock (SyncRoot)
            {
                if (!IsInitialized)
                {
                    logEvent.Continuation(null);
                    return;
                }

                if (initializeException != null)
                {
                    logEvent.Continuation(CreateInitException());
                    return;
                }

                var wrappedContinuation = AsyncHelpers.PreventMultipleCalls(logEvent.Continuation);

                try
                {
                    Write(logEvent.LogEvent.WithContinuation(wrappedContinuation));
                }
                catch (Exception exception)
                {
                    if (exception.MustBeRethrown())
                    {
                        throw;
                    }

                    wrappedContinuation(exception);
                }
            }
        }