protected void LogReceived(AsyncLogEventInfo log)
        {
            LogEventViewModel vm = new LogEventViewModel(log.LogEvent);

            Dispatcher.BeginInvoke(new Action(() =>
            {
                if (MaxRowCount > 0 && LogEntries.Count >= MaxRowCount)
                {
                    LogEntries.RemoveAt(0);
                }
                LogEntries.Add(vm);
                if (AutoScrollToLast)
                {
                    ScrollToLast();
                }
                ItemAdded(this, (NLogEvent)log.LogEvent);
            }));
        }
Exemple #2
0
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     WriteCount++;
     ThreadPool.QueueUserWorkItem(
         s =>
     {
         if (ThrowExceptions)
         {
             logEvent.Continuation(new InvalidOperationException("Some problem!"));
             logEvent.Continuation(new InvalidOperationException("Some problem!"));
         }
         else
         {
             logEvent.Continuation(null);
             logEvent.Continuation(null);
         }
     });
 }
Exemple #3
0
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     if ((DateTime.Now - _lastLogEvent).TotalMinutes >= MinLogInterval)
     {
         _lastLogEvent = DateTime.Now;
         WrappedTarget.WriteAsyncLogEvent(logEvent);
     }
     else
     {
         logEvent.Continuation(null);
         // EXPERIMENTAL: check if the level of the log event is higher than "WARN" (3) and
         // log a debug message about keeping back the email message:
         if (logEvent.LogEvent.Level.Ordinal > 3)
         {
             Log.Debug("RateLimitWrapper: not sending email, frequency too high!");
         }
     }
 }
Exemple #4
0
        /// <summary>
        /// Forwards the write to one of the targets from
        /// the <see cref="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 write to one of the targets from
        /// the <see cref="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 (this.Targets.Count == 0)
            {
                logEvent.Continuation(null);
                return;
            }

            int selectedTarget;

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

            this.Targets[selectedTarget].WriteAsyncLogEvent(logEvent);
        }
        private NLogEvents TranslateLogEvents(IList <AsyncLogEventInfo> logEvents)
        {
            if (logEvents.Count == 0 && !LogManager.ThrowExceptions)
            {
                InternalLogger.Error("LogReceiverServiceTarget(Name={0}): LogEvents array is empty, sending empty event...", Name);
                return(new NLogEvents());
            }

            string clientID = string.Empty;

            if (ClientId != null)
            {
                clientID = ClientId.Render(logEvents[0].LogEvent);
            }

            var networkLogEvents = new NLogEvents
            {
                ClientName  = clientID,
                LayoutNames = new StringCollection(),
                Strings     = new StringCollection(),
                BaseTimeUtc = logEvents[0].LogEvent.TimeStamp.ToUniversalTime().Ticks
            };

            var stringTable = new Dictionary <string, int>();

            for (int i = 0; i < Parameters.Count; ++i)
            {
                networkLogEvents.LayoutNames.Add(Parameters[i].Name);
            }

            if (IncludeEventProperties)
            {
                AddEventProperties(logEvents, networkLogEvents);
            }

            networkLogEvents.Events = new NLogEvent[logEvents.Count];
            for (int i = 0; i < logEvents.Count; ++i)
            {
                AsyncLogEventInfo ev = logEvents[i];
                networkLogEvents.Events[i] = TranslateEvent(ev.LogEvent, networkLogEvents, stringTable);
            }

            return(networkLogEvents);
        }
Exemple #7
0
        protected override void Write(AsyncLogEventInfo logEvent)
        {
            GetConnection();
            InternalLogger.Trace("Fluentd (Name={0}): Sending to address: '{1}:{2}'", Name, this.Host, this.Port);
            var record     = new Dictionary <string, string>();
            var logMessage = GetFormattedMessage(logEvent.LogEvent);

            record.Add("message", logMessage);
            try
            {
                this.emitter.Pack(logEvent.LogEvent.TimeStamp, this.Tag, record);
            }
            catch (Exception ex)
            {
                InternalLogger.Warn("Fluentd Emit - " + ex.ToString());

                throw;  // Notify NLog of failure
            }
        }
Exemple #8
0
        /// <summary>
        /// Writes async log event to the log target.
        /// </summary>
        /// <param name="logEvent">Async Log event to be written out.</param>
        protected virtual void Write(AsyncLogEventInfo logEvent)
        {
            try
            {
                MergeEventProperties(logEvent.LogEvent);

                Write(logEvent.LogEvent);
                logEvent.Continuation(null);
            }
            catch (Exception exception)
            {
                if (exception.MustBeRethrown())
                {
                    throw;
                }

                logEvent.Continuation(exception);
            }
        }
        private void Enqueue(AsyncLogEventInfo asyncLogEventInfo, int timeout)
        {
            void LogEnqueueResult(string message)
            {
                if (!InternalLogger.IsDebugEnabled)
                {
                    return;
                }
                InternalLogger.Debug("[Syslog] {0} '{1}'", message, asyncLogEventInfo.ToFormattedMessage());
            }

            if (queue.TryAdd(asyncLogEventInfo, timeout, token))
            {
                LogEnqueueResult("Enqueued");
                return;
            }
            LogEnqueueResult("Failed enqueuing");
            asyncLogEventInfo.Continuation(new InvalidOperationException($"Enqueue failed"));
        }
Exemple #10
0
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     Assert.True(this.FlushCount <= this.WriteCount);
     Interlocked.Increment(ref this.WriteCount);
     ThreadPool.QueueUserWorkItem(
         s =>
     {
         if (this.ThrowExceptions)
         {
             logEvent.Continuation(new InvalidOperationException("Some problem!"));
             logEvent.Continuation(new InvalidOperationException("Some problem!"));
         }
         else
         {
             logEvent.Continuation(null);
             logEvent.Continuation(null);
         }
     });
 }
Exemple #11
0
        /// <summary>
        /// Writes an array of logging events to the log target. By default it iterates on all
        /// events and passes them to "Write" method. Inheriting classes can use this method to
        /// optimize batch writes.
        /// </summary>
        /// <param name="logEvents">Logging events to be written out.</param>
        protected override void Write(IList <AsyncLogEventInfo> logEvents)
        {
            InternalLogger.Trace("SplitGroup(Name={0}): Writing {1} events", Name, logEvents.Count);

            if (logEvents.Count == 1)
            {
                Write(logEvents[0]);    // Skip array allocation for each destination target
            }
            else if (Targets.Count == 0 || logEvents.Count == 0)
            {
                for (int i = 0; i < logEvents.Count; ++i)
                {
                    logEvents[i].Continuation(null);
                }
            }
            else
            {
                if (Targets.Count > 1)
                {
                    for (int i = 0; i < logEvents.Count; ++i)
                    {
                        AsyncLogEventInfo ev = logEvents[i];
                        logEvents[i] = ev.LogEvent.WithContinuation(CreateCountedContinuation(ev.Continuation, Targets.Count));
                    }
                }

                for (int i = 0; i < Targets.Count; ++i)
                {
                    InternalLogger.Trace("SplitGroup(Name={0}): Sending {1} events to {2}", Name, logEvents.Count, Targets[i]);

                    var targetLogEvents = logEvents;
                    if (i < Targets.Count - 1)
                    {
                        // OptimizeBufferReuse = true, will change the input-array (so we make clones here)
                        AsyncLogEventInfo[] cloneLogEvents = new AsyncLogEventInfo[logEvents.Count];
                        logEvents.CopyTo(cloneLogEvents, 0);
                        targetLogEvents = cloneLogEvents;
                    }

                    Targets[i].WriteAsyncLogEvents(targetLogEvents);
                }
            }
        }
        private void Send(AsyncLogEventInfo info)
        {
            var message  = RenderLogEvent(Layout, info.LogEvent);
            var baseurl  = RenderLogEvent(BaseUrl, info.LogEvent);
            var botToken = RenderLogEvent(BotToken, info.LogEvent);
            var chatId   = RenderLogEvent(ChatId, info.LogEvent);

            var uriBuilder = new UriBuilder(baseurl + botToken);

            uriBuilder.Path += "/sendMessage";
            var url     = uriBuilder.Uri.ToString();
            var builder = TelegramMessageBuilder
                          .Build(url, message)
                          .ToChat(chatId)
                          .OnError(e => info.Continuation(e))
            ;

            builder.Send();
        }
Exemple #13
0
        /// <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;
            int counter = 0;

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

                int 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 (Check every 100 ms if target have been closed)
                for (int i = 0; i < RetryDelayMilliseconds;)
                {
                    int retryDelay = Math.Min(100, RetryDelayMilliseconds - i);
                    Thread.Sleep(retryDelay);
                    i += retryDelay;
                    if (!IsInitialized)
                    {
                        InternalLogger.Warn("Target closed. Aborting.");
                        logEvent.Continuation(ex);
                        return;
                    }
                }

                WrappedTarget.WriteAsyncLogEvent(logEvent.LogEvent.WithContinuation(continuation));
            };

            WrappedTarget.WriteAsyncLogEvent(logEvent.LogEvent.WithContinuation(continuation));
        }
Exemple #14
0
        /// <summary>
        /// Writes async log event to the log target.
        /// </summary>
        /// /// <param name="logEvent">Logging event to be written out.</param>
        protected override void Write(AsyncLogEventInfo logEvent)
        {
            LogEntry logEntry = null;

            try
            {
                logEntry = BuildLogEntry(logEvent.LogEvent);
            }
            catch (Exception ex)
            {
                InternalLogger.Error(ex, "GoogleStackdriver(Name={0}): Failed to create LogEntry, marked as failed", Name);
                logEvent.Continuation(ex);
            }

            if (logEntry != null)
            {
                WriteLogEntries(new[] { logEntry }, logEvent.Continuation);
            }
        }
        /// <summary>
        /// Writes log event to the wrapped target if the current <see cref="MessagesWrittenCount"/> is lower than <see cref="MessageLimit"/>.
        /// If the <see cref="MessageLimit"/> is already reached, no log event will be written to the wrapped target.
        /// <see cref="MessagesWrittenCount"/> resets when the current <see cref="Interval"/> is expired.
        /// </summary>
        /// <param name="logEvent">Log event to be written out.</param>
        protected override void Write(AsyncLogEventInfo logEvent)
        {
            if (IsIntervalExpired())
            {
                ResetInterval();
                InternalLogger.Debug("LimitingWrapper(Name={0}): New interval of '{1}' started.", Name, Interval);
            }

            if (MessagesWrittenCount < MessageLimit)
            {
                WrappedTarget.WriteAsyncLogEvent(logEvent);
                MessagesWrittenCount++;
            }
            else
            {
                logEvent.Continuation(null);
                InternalLogger.Trace("LimitingWrapper(Name={0}): Discarded event, because MessageLimit of '{1}' was reached.", Name, MessageLimit);
            }
        }
Exemple #16
0
        /// <summary>
        /// Forwards the specified log event to all sub-targets.
        /// </summary>
        /// <param name="logEvent">The log event.</param>
        protected override void Write(AsyncLogEventInfo logEvent)
        {
            if (Targets.Count == 0)
            {
                logEvent.Continuation(null);
            }
            else
            {
                if (Targets.Count > 1)
                {
                    logEvent = logEvent.LogEvent.WithContinuation(CreateCountedContinuation(logEvent.Continuation, Targets.Count));
                }

                for (int i = 0; i < Targets.Count; ++i)
                {
                    Targets[i].WriteAsyncLogEvent(logEvent);
                }
            }
        }
Exemple #17
0
        protected override void Write(AsyncLogEventInfo logEvent)
        {
            var continuation        = logEvent.Continuation;
            var basicProperties     = GetBasicProperties(logEvent);
            var uncompressedMessage = GetMessage(logEvent);
            var message             = CompressMessage(uncompressedMessage);
            var routingKey          = GetTopic(logEvent.LogEvent);

            if (_Model == null || !_Model.IsOpen)
            {
                StartConnection();
            }

            if (_Model == null || !_Model.IsOpen)
            {
                AddUnsent(routingKey, basicProperties, message);
                return;
            }

            try
            {
                CheckUnsent();
                Publish(message, basicProperties, routingKey);
                return;
            }
            catch (IOException e)
            {
                AddUnsent(routingKey, basicProperties, message);
                continuation(e);
                //InternalLogger.Error("Could not send to RabbitMQ instance! {0}", e.ToString());
            }
            catch (ObjectDisposedException e)
            {
                AddUnsent(routingKey, basicProperties, message);
                continuation(e);
                //InternalLogger.Error("Could not write data to the network stream! {0}", e.ToString());
            }

            ShutdownAmqp(_Connection,
                         new ShutdownEventArgs(ShutdownInitiator.Application, Constants.ChannelError, "Could not talk to RabbitMQ instance", null));
            // using this version of constructor, because RabbitMQ.Client from 3.5.x don't have ctor without cause parameter
        }
        protected override void Write(AsyncLogEventInfo info)
        {
            try
            {
                var uri  = new Uri(Url.Render(info.LogEvent));
                var json = BuildJsonEvent(info.LogEvent);

#if DEBUG
                Debug.WriteLine("Sending: " + json);
#endif

                _poster.Post(uri, json);

                info.Continuation(null);
            }
            catch (Exception ex)
            {
                info.Continuation(ex);
            }
        }
Exemple #19
0
        /// <summary>
        /// Invokes the web service method.
        /// </summary>
        /// <param name="parameters">Parameters to be passed.</param>
        /// <param name="logEvent">The logging event.</param>
        protected override void DoInvoke(object[] parameters, AsyncLogEventInfo logEvent)
        {
            var request = (HttpWebRequest)WebRequest.Create(BuildWebServiceUrl(parameters));

            if (this.Headers != null && this.Headers.Count > 0)
            {
                for (int i = 0; i < this.Headers.Count; i++)
                {
                    string headerValue = base.RenderLogEvent(this.Headers[i].Layout, logEvent.LogEvent);
                    if (headerValue == null)
                    {
                        continue;
                    }

                    request.Headers[this.Headers[i].Name] = headerValue;
                }
            }

            DoInvoke(parameters, request, logEvent.Continuation);
        }
Exemple #20
0
        private async Task WriteAsync(AsyncLogEventInfo info)
        {
            try
            {
                InternalLogger.Debug("Async post event: {0}.", info.LogEvent.SequenceID);

                var result = await Client.PostAsync(Url, new JsonContent(GetContent(info.LogEvent)));

                InternalLogger.Debug("Response of event {0} from '{1}': {2}", info.LogEvent.SequenceID, Url, result);

                result.EnsureSuccessStatusCode();

                info.Continuation(null);
            }
            catch (Exception ex)
            {
                InternalLogger.Error(ex, "Async write error of event: {0}.", info.LogEvent.SequenceID);
                info.Continuation(ex);
            }
        }
        protected override void Write(AsyncLogEventInfo info)
        {
            if (!_client.Configuration.IsValid)
            {
                return;
            }

            var builder = _client.CreateFromLogEvent(info.LogEvent);

            foreach (var field in Fields)
            {
                var renderedField = field.Layout.Render(info.LogEvent);
                if (!String.IsNullOrWhiteSpace(renderedField))
                {
                    builder.AddObject(renderedField, field.Name);
                }
            }

            builder.Submit();
        }
Exemple #22
0
        /// <summary>
        /// Writes the log to the target.
        /// </summary>
        /// <param name="logEvent">Log event to write.</param>
        public void WriteAsyncLogEvent(AsyncLogEventInfo logEvent)
        {
            lock (this.SyncRoot)
            {
                if (!this.IsInitialized)
                {
                    logEvent.Continuation(null);
                    return;
                }

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

                AsyncContinuation wrappedContinuation = AsyncHelpers.PreventMultipleCalls(this.LoggingConfiguration, logEvent.Continuation);;

                // Create async continuation to put log item back into the pool
                if (this.LoggingConfiguration.PoolingEnabled())
                {
                    var pool = this.LoggingConfiguration.PoolFactory.Get <CombinedAsyncContinuationPool, CombinedAsyncContinuation>();

                    wrappedContinuation = pool.Get(wrappedContinuation, logEvent.LogEvent.PutBackDelegate).Delegate;
                }

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

                    wrappedContinuation(exception);
                }
            }
        }
        /// <summary>
        /// Adds the specified log event to the buffer.
        /// </summary>
        /// <param name="eventInfo">Log event.</param>
        /// <returns>The number of items in the buffer.</returns>
        public int Append(AsyncLogEventInfo eventInfo)
        {
            lock (_lockObject)
            {
                // make room for additional item
                if (_count >= _buffer.Length)
                {
                    if (_growAsNeeded && _buffer.Length < _growLimit)
                    {
                        // create a new buffer, copy data from current
                        int newLength = _buffer.Length * 2;
                        if (newLength >= _growLimit)
                        {
                            newLength = _growLimit;
                        }

                        InternalLogger.Trace("Enlarging LogEventInfoBuffer from {0} to {1}", _buffer.Length, newLength);
                        var newBuffer = new AsyncLogEventInfo[newLength];
                        Array.Copy(_buffer, 0, newBuffer, 0, _buffer.Length);
                        _buffer = newBuffer;
                    }
                    else
                    {
                        // lose the oldest item
                        _getPointer = _getPointer + 1;
                    }
                }

                // put the item
                _putPointer = _putPointer % _buffer.Length;
                _buffer[_putPointer] = eventInfo;
                _putPointer = _putPointer + 1;
                _count++;
                if (_count >= _buffer.Length)
                {
                    _count = _buffer.Length;
                }

                return _count;
            }
        }
        /// <summary>
        /// Enqueues another item. If the queue is overflown the appropriate
        /// action is taken as specified by <see cref="AsyncRequestQueueBase.OnOverflow"/>.
        /// </summary>
        /// <param name="logEventInfo">The log event info.</param>
        /// <returns>Queue was empty before enqueue</returns>
        public override bool Enqueue(AsyncLogEventInfo logEventInfo)
        {
            long currentCount = Interlocked.Increment(ref _count);

            if (currentCount > RequestLimit)
            {
                InternalLogger.Debug("Async queue is full");
                switch (OnOverflow)
                {
                case AsyncTargetWrapperOverflowAction.Discard:
                {
                    do
                    {
                        if (_logEventInfoQueue.TryDequeue(out var lostItem))
                        {
                            InternalLogger.Debug("Discarding one element from queue");
                            currentCount = Interlocked.Decrement(ref _count);
                            OnLogEventDropped(lostItem.LogEvent);
                            break;
                        }
                        currentCount = Interlocked.Read(ref _count);
                    } while (currentCount > RequestLimit);
                }
                break;

                case AsyncTargetWrapperOverflowAction.Block:
                {
                    currentCount = WaitForBelowRequestLimit();
                }
                break;

                case AsyncTargetWrapperOverflowAction.Grow:
                {
                    OnLogEventQueueGrows(currentCount);
                }
                break;
                }
            }
            _logEventInfoQueue.Enqueue(logEventInfo);
            return(currentCount == 1);
        }
Exemple #25
0
        /// <summary>
        /// Writes an array of logging events to the log target. By default it iterates on all
        /// events and passes them to "Write" method. Inheriting classes can use this method to
        /// optimize batch writes.
        /// </summary>
        /// <param name="logEvents">Logging events to be written out.</param>
        protected override void Write(ArraySegment <AsyncLogEventInfo> logEvents)
        {
            // if web service call is being processed, buffer new events and return
            // lock is being held here
            if (this.inCall)
            {
                for (int x = 0; x < logEvents.Count; x++)
                {
                    var ev = logEvents.Array[x];
                    this.buffer.Append(ev);
                }

                return;
            }

            var networkLogEvents = this.TranslateLogEvents(logEvents);
            var arr = new AsyncLogEventInfo[logEvents.Count];

            Array.Copy(logEvents.Array, logEvents.Offset, arr, 0, logEvents.Count);
            this.Send(networkLogEvents, arr);
        }
        /// <summary>
        /// Writes an array of logging events to the log target. By default it iterates on all
        /// events and passes them to "Append" method. Inheriting classes can use this method to
        /// optimize batch writes.
        /// </summary>
        /// <param name="logEvents">Logging events to be written out.</param>
        protected override void Write(IList<AsyncLogEventInfo> logEvents)
        {
            // if web service call is being processed, buffer new events and return
            // lock is being held here
            if (inCall)
            {
                for (int i = 0; i < logEvents.Count; ++i)
                {
                    PrecalculateVolatileLayouts(logEvents[i].LogEvent);
                    buffer.Append(logEvents[i]);
                }
                return;
            }

            // OptimizeBufferReuse = true, will reuse the input-array on method-exit (so we make clone here)
            AsyncLogEventInfo[] logEventsArray = new AsyncLogEventInfo[logEvents.Count];
            logEvents.CopyTo(logEventsArray, 0);

            var networkLogEvents = TranslateLogEvents(logEventsArray);
            Send(networkLogEvents, logEventsArray, null);
        }
Exemple #27
0
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     try
     {
         // The check for the request is a dirty way to check if we're trying to log from App_Start
         if (HttpContext.Current != null && HttpContext.Current.Request != null)
         {
             EnqueueLogEvent(logEvent);
             return;
         }
     }
     catch (HttpException)
     {
         // We're in App_Start, so we'll just write the log directly
     }
     using (MiniProfiler.Current.Ignore())
     {
         Cohort.Database.Insert(ProjectLog(logEvent.LogEvent));
     }
     base.Write(logEvent);
 }
Exemple #28
0
        /// <summary>
        /// Writes the array of log events.
        /// </summary>
        /// <param name="logEvents">The log events.</param>
        public void WriteAsyncLogEvents(params AsyncLogEventInfo[] logEvents)
        {
            if (logEvents == null || logEvents.Length == 0)
            {
                return;
            }

            if (!this.IsInitialized)
            {
                lock (this.SyncRoot)
                {
                    foreach (var ev in logEvents)
                    {
                        ev.Continuation(null);
                    }
                }
                return;
            }

            if (this.initializeException != null)
            {
                lock (this.SyncRoot)
                {
                    foreach (var ev in logEvents)
                    {
                        ev.Continuation(this.CreateInitException());
                    }
                }
                return;
            }

            var wrappedEvents = new AsyncLogEventInfo[logEvents.Length];

            for (int i = 0; i < logEvents.Length; ++i)
            {
                wrappedEvents[i] = logEvents[i].LogEvent.WithContinuation(AsyncHelpers.PreventMultipleCalls(logEvents[i].Continuation));
            }

            this.WriteAsyncThreadSafe(wrappedEvents);
        }
Exemple #29
0
        /// <summary>
        /// Writes an array of logging events to the log target. By default it iterates on all
        /// events and passes them to "Append" method. Inheriting classes can use this method to
        /// optimize batch writes.
        /// </summary>
        /// <param name="logEvents">Logging events to be written out.</param>
        protected override void Write(IList <AsyncLogEventInfo> logEvents)
        {
            // if web service call is being processed, buffer new events and return
            // lock is being held here
            if (inCall)
            {
                for (int i = 0; i < logEvents.Count; ++i)
                {
                    PrecalculateVolatileLayouts(logEvents[i].LogEvent);
                    buffer.Append(logEvents[i]);
                }
                return;
            }

            // Make clone as the input IList will be reused on next call
            AsyncLogEventInfo[] logEventsArray = new AsyncLogEventInfo[logEvents.Count];
            logEvents.CopyTo(logEventsArray, 0);

            var networkLogEvents = TranslateLogEvents(logEvents);

            Send(networkLogEvents, logEvents, null);
        }
 /// <summary>
 /// Forwards the call to the <see cref="WrapperTargetBase.WrappedTarget"/>.Write()
 /// and calls <see cref="Target.Flush(AsyncContinuation)"/> on it if LogEvent satisfies
 /// the flush condition or condition is null.
 /// </summary>
 /// <param name="logEvent">Logging event to be written out.</param>
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     if (this.Condition == null || this.Condition.Evaluate(logEvent.LogEvent).Equals(true))
     {
         AsyncContinuation currentContinuation = logEvent.Continuation;
         AsyncContinuation wrappedContinuation = (ex) =>
         {
             if (ex == null)
             {
                 this.WrappedTarget.Flush((e) => { });
             }
             this.pendingManualFlushList.CompleteOperation(ex);
             currentContinuation(ex);
         };
         this.pendingManualFlushList.BeginOperation();
         this.WrappedTarget.WriteAsyncLogEvent(logEvent.LogEvent.WithContinuation(wrappedContinuation));
     }
     else
     {
         this.WrappedTarget.WriteAsyncLogEvent(logEvent);
     }
 }
 /// <summary>
 /// Checks the condition against the passed log event.
 /// If the condition is met, the log event is forwarded to
 /// the wrapped target.
 /// </summary>
 /// <param name="logEvent">Log event.</param>
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     object v = this.Condition.Evaluate(logEvent.LogEvent);
     if (boxedBooleanTrue.Equals(v))
     {
         this.WrappedTarget.WriteAsyncLogEvent(logEvent);
     }
     else
     {
         logEvent.Continuation(null);
     }
 }
 /// <summary>
 /// Forwards the call to the <see cref="WrapperTargetBase.WrappedTarget"/>.Write()
 /// and calls <see cref="Target.Flush(AsyncContinuation)"/> on it.
 /// </summary>
 /// <param name="logEvent">Logging event to be written out.</param>
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     this.WrappedTarget.WriteAsyncLogEvent(logEvent.LogEvent.WithContinuation(AsyncHelpers.PrecededBy(logEvent.Continuation, this.WrappedTarget.Flush)));
 }
Exemple #33
0
        /// <summary>
        /// Write to queue without locking <see cref="Target.SyncRoot"/> 
        /// </summary>
        /// <param name="logEvent"></param>
        protected override void WriteAsyncThreadSafe(AsyncLogEventInfo logEvent)
        {
            try
            {
                this.Write(logEvent);
            }
            catch (Exception exception)
            {
                if (exception.MustBeRethrown())
                {
                    throw;
                }

                logEvent.Continuation(exception);
            }
        }
Exemple #34
0
        /// <summary>
        /// Writes the specified array of logging events to a file specified in the FileName
        /// parameter.
        /// </summary>
        /// <param name="logEvents">An array of <see cref="LogEventInfo "/> objects.</param>
        /// <remarks>
        /// This function makes use of the fact that the events are batched by sorting
        /// the requests by filename. This optimizes the number of open/close calls
        /// and can help improve performance.
        /// </remarks>
        protected override void Write(AsyncLogEventInfo[] logEvents)
        {
            var buckets = logEvents.BucketSort(c => this.FileName.Render(c.LogEvent));
            using (var ms = new MemoryStream())
            {
                var pendingContinuations = new List<AsyncContinuation>();

                foreach (var bucket in buckets)
                {
                    string fileName = bucket.Key;

                    ms.SetLength(0);
                    ms.Position = 0;

                    LogEventInfo firstLogEvent = null;

                    foreach (AsyncLogEventInfo ev in bucket.Value)
                    {
                        if (firstLogEvent == null)
                        {
                            firstLogEvent = ev.LogEvent;
                        }

                        byte[] bytes = this.GetBytesToWrite(ev.LogEvent);
                        ms.Write(bytes, 0, bytes.Length);
                        pendingContinuations.Add(ev.Continuation);
                    }

                    this.FlushCurrentFileWrites(fileName, firstLogEvent, ms, pendingContinuations);
                }
            }
        }
 /// <summary>
 /// Renders the logging event message and adds it to the internal ArrayList of log messages.
 /// </summary>
 /// <param name="logEvent">The logging event.</param>
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     this.Write(new[] { logEvent });
 }
        /// <summary>
        /// Evaluates all filtering rules to find the first one that matches.
        /// The matching rule determines the filtering condition to be applied
        /// to all items in a buffer. If no condition matches, default filter
        /// is applied to the array of log events.
        /// </summary>
        /// <param name="logEvents">Array of log events to be post-filtered.</param>
        protected override void Write(AsyncLogEventInfo[] logEvents)
        {
            ConditionExpression resultFilter = null;

            InternalLogger.Trace("Running {0} on {1} events", this, logEvents.Length);

            // evaluate all the rules to get the filtering condition
            for (int i = 0; i < logEvents.Length; ++i)
            {
                foreach (FilteringRule rule in this.Rules)
                {
                    object v = rule.Exists.Evaluate(logEvents[i].LogEvent);

                    if (boxedTrue.Equals(v))
                    {
                        InternalLogger.Trace("Rule matched: {0}", rule.Exists);

                        resultFilter = rule.Filter;
                        break;
                    }
                }

                if (resultFilter != null)
                {
                    break;
                }
            }

            if (resultFilter == null)
            {
                resultFilter = this.DefaultFilter;
            }

            if (resultFilter == null)
            {
                this.WrappedTarget.WriteAsyncLogEvents(logEvents);
            }
            else
            {
                InternalLogger.Trace("Filter to apply: {0}", resultFilter);

                // apply the condition to the buffer
                var resultBuffer = new List<AsyncLogEventInfo>();

                for (int i = 0; i < logEvents.Length; ++i)
                {
                    object v = resultFilter.Evaluate(logEvents[i].LogEvent);
                    if (boxedTrue.Equals(v))
                    {
                        resultBuffer.Add(logEvents[i]);
                    }
                    else
                    {
                        // anything not passed down will be notified about successful completion
                        logEvents[i].Continuation(null);
                    }
                }

                InternalLogger.Trace("After filtering: {0} events.", resultBuffer.Count);
                if (resultBuffer.Count > 0)
                {
                    InternalLogger.Trace("Sending to {0}", this.WrappedTarget);
                    this.WrappedTarget.WriteAsyncLogEvents(resultBuffer.ToArray());
                }
            }
        }
        /// <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 (this.Targets.Count == 0)
            {
                logEvent.Continuation(null);
                return;
            }

            int selectedTarget;

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

            this.Targets[selectedTarget].WriteAsyncLogEvent(logEvent);
        }
 /// <summary>
 /// Renders an array logging events.
 /// </summary>
 /// <param name="logEvents">Array of logging events.</param>
 protected override void Write(AsyncLogEventInfo[] logEvents)
 {
     foreach (var bucket in logEvents.BucketSort(c => this.GetSmtpSettingsKey(c.LogEvent)))
     {
         var eventInfos = bucket.Value;
         this.ProcessSingleMailMessage(eventInfos);
     }
 }
 /// <summary>
 /// Forwards the specified log event to all sub-targets.
 /// </summary>
 /// <param name="logEvent">The log event.</param>
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     AsyncHelpers.ForEachItemSequentially(this.Targets, logEvent.Continuation, (t, cont) => t.WriteAsyncLogEvent(logEvent.LogEvent.WithContinuation(cont)));
 }
        /// <summary>
        /// Writes an array of logging events to the log target. By default it iterates on all
        /// events and passes them to "Write" method. Inheriting classes can use this method to
        /// optimize batch writes.
        /// </summary>
        /// <param name="logEvents">Logging events to be written out.</param>
        protected override void Write(AsyncLogEventInfo[] logEvents)
        {
            var buckets = SortHelpers.BucketSort(logEvents, c => this.BuildConnectionString(c.LogEvent));

            try
            {
                foreach (var kvp in buckets)
                {
                    foreach (AsyncLogEventInfo ev in kvp.Value)
                    {
                        try
                        {
                            this.WriteEventToDatabase(ev.LogEvent);
                            ev.Continuation(null);
                        }
                        catch (Exception exception)
                        {
                            if (exception.MustBeRethrown())
                            {
                                throw;
                            }

                            // in case of exception, close the connection and report it
                            InternalLogger.Error("Error when writing to database {0}", exception);
                            this.CloseConnection();
                            ev.Continuation(exception);
                        }
                    }
                }
            }
            finally
            {
                if (!this.KeepConnection)
                {
                    this.CloseConnection();
                }
            }
        }
        protected override void Write(AsyncLogEventInfo[] logEvents)
        {
            if (logEvents.Length == 0)
            {
                return;
            }

            var sb = new StringBuilder();
            var lastLogEvent = logEvents[logEvents.Length - 1];
            foreach (var ev in logEvents)
            {
                sb.Append(this.Layout.Render(ev.LogEvent));
                sb.Append("\n");
            }

            MessageBoxHelper.Show(sb.ToString(), this.Caption.Render(lastLogEvent.LogEvent));

            for (int i = 0; i < logEvents.Length; ++i)
            {
                logEvents[i].Continuation(null);
            }
        }
Exemple #42
0
 /// <summary>
 /// Adds the log event to asynchronous queue to be processed by
 /// the lazy writer thread.
 /// </summary>
 /// <param name="logEvent">The log event.</param>
 /// <remarks>
 /// The <see cref="Target.PrecalculateVolatileLayouts"/> is called
 /// to ensure that the log event can be processed in another thread.
 /// </remarks>
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     this.MergeEventProperties(logEvent.LogEvent);
     this.PrecalculateVolatileLayouts(logEvent.LogEvent);
     bool queueWasEmpty = this.RequestQueue.Enqueue(logEvent);
     if (queueWasEmpty && TimeToSleepBetweenBatches <= 0)
         StartInstantWriterTimer();
 }
Exemple #43
0
 /// <summary>
 /// Adds the log event to asynchronous queue to be processed by
 /// the lazy writer thread.
 /// </summary>
 /// <param name="logEvent">The log event.</param>
 /// <remarks>
 /// The <see cref="Target.PrecalculateVolatileLayouts"/> is called
 /// to ensure that the log event can be processed in another thread.
 /// </remarks>
 protected override void Write(AsyncLogEventInfo logEvent)
 {
     this.MergeEventProperties(logEvent.LogEvent);
     this.PrecalculateVolatileLayouts(logEvent.LogEvent);
     this.RequestQueue.Enqueue(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;
            int tryCounter = 0;
            int targetToInvoke;

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

                        logEvent.Continuation(null);
                        return;
                    }

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

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

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

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

            lock (this.lockObject)
            {
                targetToInvoke = this.currentTarget;
            }

            this.Targets[targetToInvoke].WriteAsyncLogEvent(logEvent.LogEvent.WithContinuation(continuation));
        }
        /// <summary>
        /// Writes an array of logging events to the log target. By default it iterates on all
        /// events and passes them to "Write" method. Inheriting classes can use this method to
        /// optimize batch writes.
        /// </summary>
        /// <param name="logEvents">Logging events to be written out.</param>
        protected override void Write(AsyncLogEventInfo[] logEvents)
        {
            InternalLogger.Trace("Writing {0} events", logEvents.Length);

            for (int i = 0; i < logEvents.Length; ++i)
            {
                logEvents[i].Continuation = CountedWrap(logEvents[i].Continuation, this.Targets.Count);
            }

            foreach (var t in this.Targets)
            {
                InternalLogger.Trace("Sending {0} events to {1}", logEvents.Length, t);
                t.WriteAsyncLogEvents(logEvents);
            }
        }