Exemple #1
0
        /// <summary>
        /// Processes the specified log message synchronously and passes the log message to the next processing stages,
        /// if appropriate. This method must not throw exceptions.
        /// </summary>
        /// <param name="message">Message to process.</param>
        public void ProcessMessage(LocalLogMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            lock (Sync)
            {
                if (!mInitialized)
                {
                    throw new InvalidOperationException("The pipeline stage is not initialized. Ensure it is attached to the logging subsystem.");
                }

                try
                {
                    if (OnProcessMessageBase(message))
                    {
                        // pass log message to the next pipeline stages
                        for (int i = 0; i < mNextStages.Length; i++)
                        {
                            mNextStages[i].ProcessMessage(message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // swallow exception to avoid crashing the application, if the exception is not handled properly
                    Debug.Fail("The pipeline stage threw an exception processing a message.", ex.ToString());
                }
            }
        }
 /// <summary>
 /// The callback that is expected to be invoked when a log message is to process.
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 public bool ProcessSyncCallback(LocalLogMessage message)
 {
     ProcessSyncCallbackWasCalled       = true;
     MessagePassedToProcessSyncCallback = message;
     MessagePassedToProcessSyncCallback.AddRef();
     return(ProcessSyncCallbackReturnValue);
 }
Exemple #3
0
 protected override bool ProcessSync(LocalLogMessage message, out bool queueForAsyncProcessing)
 {
     ProcessSyncWasCalled = true;
     MessagePassedToProcessSync?.Release();
     MessagePassedToProcessSync = message;
     MessagePassedToProcessSync.AddRef();
     return(base.ProcessSync(message, out queueForAsyncProcessing));
 }
Exemple #4
0
            public bool ProcessSyncCallback(LocalLogMessage message, out bool queueForAsyncProcessing)
            {
                queueForAsyncProcessing = ProcessSyncCallbackQueueForAsyncProcessing;

                ProcessSyncCallbackWasCalled = true;
                MessagePassedToProcessSyncCallback?.Release();
                MessagePassedToProcessSyncCallback = message;
                MessagePassedToProcessSyncCallback.AddRef();

                return(ProcessSyncCallbackReturnValue);
            }
Exemple #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LocalLogMessage"/> class copying the specified one.
 /// </summary>
 /// <param name="other">Message to copy.</param>
 public LocalLogMessage(LocalLogMessage other)
 {
     Context    = new Dictionary <string, object>(other.Context);
     mTimestamp = other.Timestamp;
     mHighPrecisionTimestamp = other.HighPrecisionTimestamp;
     mLogWriter       = other.LogWriter;
     mLogLevel        = other.LogLevel;
     mTags            = other.Tags;
     mApplicationName = other.ApplicationName;
     mProcessName     = other.ProcessName;
     mProcessId       = other.ProcessId;
     mText            = other.Text;
 }
Exemple #6
0
        /// <summary>
        /// Gets a log message from the pool, creates a new one, if the pool is empty. The returned message is not initialized.
        /// Call <see cref="LocalLogMessage.InitWith"/> to initialize it.
        /// </summary>
        /// <returns>The requested log message.</returns>
        public LocalLogMessage GetUninitializedMessage()
        {
            if (mMessages.TryTake(out var message))
            {
                message.AddRef();
            }
            else
            {
                message = new LocalLogMessage(this);
            }

            Debug.Assert(message.RefCount == 1);
            return(message);
        }
Exemple #7
0
        /// <summary>
        /// Is called on behalf of <see cref="ProcessingPipelineStage.ProcessMessage"/> (for internal use only).
        /// This method must not throw exceptions.
        /// </summary>
        /// <param name="message">Message to process.</param>
        /// <returns>
        /// true to pass the message to the following stages;
        /// false to stop processing the message.
        /// </returns>
        internal override bool OnProcessMessageBase(LocalLogMessage message)
        {
            try
            {
                return(ProcessSync(message));
            }
            catch (Exception ex)
            {
                // swallow exception to avoid crashing the application, if the exception is not handled properly
                Debug.Fail("The pipeline stage threw an exception processing the message.", ex.ToString());

                // let the following stages process the message
                // (hopefully this is the right decision in this case)
                return(true);
            }
        }
        /// <summary>
        /// Is called on behalf of <see cref="ProcessingPipelineStage.ProcessMessage"/> (for internal use only).
        /// This method must not throw exceptions.
        /// </summary>
        /// <param name="message">Message to process.</param>
        /// <returns>
        /// true to pass the message to the following stages;
        /// false to stop processing the message.
        /// </returns>
        internal override bool OnProcessMessageBase(LocalLogMessage message)
        {
            try
            {
                // synchronous processing
                bool proceed = ProcessSync(message, out bool queueMessageForAsynchronousProcessing);

                // asynchronous processing
                if (queueMessageForAsynchronousProcessing)
                {
                    if (mDiscardMessagesIfQueueFull)
                    {
                        message.AddRef();
                        bool pushed = mAsyncProcessingMessageStack.TryPush(message);
                        if (pushed)
                        {
                            mTriggerAsyncProcessingEvent.Set();
                        }
                        else
                        {
                            message.Release();
                        }
                    }
                    else
                    {
                        message.AddRef();
                        while (!mAsyncProcessingMessageStack.TryPush(message))
                        {
                            Thread.Sleep(10);
                        }
                        mTriggerAsyncProcessingEvent.Set();
                    }
                }

                return(proceed);
            }
            catch (Exception ex)
            {
                // swallow exception to avoid crashing the application, if the exception is not handled properly
                Debug.Fail("The pipeline stage threw an exception processing the message.", ex.ToString());

                // let the following stages process the message
                // (hopefully this is the right decision in this case)
                return(true);
            }
        }
Exemple #9
0
 /// <summary>
 /// When overridden in a derived class, processes the specified log message synchronously.
 /// This method is called by the thread writing the message and from within the pipeline stage lock (<see cref="ProcessingPipelineStage.Sync"/>).
 /// This method must not throw exceptions.
 /// </summary>
 /// <param name="message">Message to process.</param>
 /// <returns>
 /// true to pass the message to the following pipeline stages;
 /// otherwise false.
 /// </returns>
 /// <remarks>
 /// Call <see cref="LocalLogMessage.AddRef"/> on a message that should be stored any longer to prevent it from
 /// returning to the log message pool too early. Call <see cref="LocalLogMessage.Release"/> as soon as you don't
 /// need the message any more.
 /// </remarks>
 protected virtual bool ProcessSync(LocalLogMessage message)
 {
     return(true);
 }
 /// <summary>
 /// When overridden in a derived class, processes the specified log message synchronously.
 /// This method is called by the thread writing the message and from within the pipeline stage lock.
 /// This method must not throw exceptions.
 /// </summary>
 /// <param name="message">Message to process.</param>
 /// <param name="queueForAsyncProcessing">
 /// Receives a value indicating whether the message should be enqueued for asynchronous processing.
 /// </param>
 /// <returns>
 /// true to pass the message to the following pipeline stages;
 /// otherwise false.
 /// </returns>
 /// <remarks>
 /// Call <see cref="LocalLogMessage.AddRef"/> on a message that should be stored any longer to prevent it from
 /// returning to the log message pool too early. Call <see cref="LocalLogMessage.Release"/> as soon as you don't
 /// need the message any more.
 /// </remarks>
 protected virtual bool ProcessSync(LocalLogMessage message, out bool queueForAsyncProcessing)
 {
     queueForAsyncProcessing = true;
     return(true);
 }
Exemple #11
0
 /// <summary>
 /// Is called on behalf of <see cref="ProcessMessage"/> (for internal use only).
 /// This method must not throw exceptions.
 /// </summary>
 /// <param name="message">Message to process.</param>
 /// <returns>
 /// true to pass the message to the following stages;
 /// false to stop processing the message.
 /// </returns>
 internal abstract bool OnProcessMessageBase(LocalLogMessage message);
Exemple #12
0
 /// <summary>
 /// Returns a log message to the pool, so it can be re-used.
 /// This message is called by the messages, if their reference counter gets 0.
 /// </summary>
 /// <param name="message">Message to return to the pool.</param>
 public void ReturnMessage(LocalLogMessage message)
 {
     Debug.Assert(message.RefCount == 0);
     message.Reset();
     mMessages.Add(message);
 }