Example #1
0
        /// <summary>
        /// Writes a system-level error message with exception.
        /// </summary>
        /// <remarks>
        /// This logging method is used for the most important high-level events the user should be aware of.
        /// These events are logged into the Windows Event log instead of the trace debug log files, and would be
        /// used for logging exceptions, backup completed/sync status, configuration issues, etc.
        /// </remarks>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        /// <param name="stackContext"></param>
        /// <param name="eventID"></param>
        /// <param name="writeToTraceLog"></param>
        /// <param name="engineID"></param>
        public void WriteSystemEvent(string message, Exception exception, string stackContext, int eventID, bool writeToTraceLog, int engineID = 0)
        {
            if (EventLogInitialized == false)
            {
                throw new InvalidOperationException("Log has not been initialized.");
            }
            if (string.IsNullOrWhiteSpace(message))
            {
                throw new ArgumentException("Argument cannot be null or empty/whitespace: " + nameof(message));
            }
            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }

            var loggableMessage = GenerateExceptionLoggingMessage(message, exception, stackContext);

            EventLog.WriteEntry(LogSource, loggableMessage, EventLogEntryType.Error, eventID);

            if (writeToTraceLog && TraceInitialized)
            {
                // also append this message to the tracelog.
                TraceMessageQueue.Enqueue(loggableMessage);
            }
        }
Example #2
0
        /// <summary>
        /// Writes an error message to the trace log file on disk.
        /// </summary>
        /// <remarks>
        /// This logging method is the preferred method for trace-level debug messaging.
        /// An example would be things like individual file transfer messages, state changes, etc.
        /// </remarks>
        /// <param name="message"></param>
        /// <param name="engineID"></param>
        public void WriteTraceError(string message, int engineID = 0)
        {
            if (TraceInitialized == false)
            {
                throw new InvalidOperationException("Trace has not been initialized.");
            }
            if (string.IsNullOrWhiteSpace(message))
            {
                throw new ArgumentException("Argument cannot be null or empty/whitespace: " + nameof(message));
            }

            TraceMessageQueue.Enqueue(PrependMessageWithDateAndSeverity(message, EventLogEntryType.Error, engineID));
        }
Example #3
0
        /// <summary>
        /// Writes an error message (and exception) to the trace log file on disk.
        /// </summary>
        /// <remarks>
        /// This logging method is the preferred method for trace-level debug messaging.
        /// An example would be things like individual file transfer messages, state changes, etc.
        /// </remarks>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        /// <param name="stackContext"></param>
        /// <param name="engineID"></param>
        public void WriteTraceError(string message, Exception exception, string stackContext, int engineID = 0)
        {
            if (TraceInitialized == false)
            {
                throw new InvalidOperationException("Trace has not been initialized.");
            }
            if (string.IsNullOrWhiteSpace(message))
            {
                throw new ArgumentException("Argument cannot be null or empty/whitespace: " + nameof(message));
            }
            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }

            TraceMessageQueue.Enqueue(GenerateExceptionLoggingMessage(message, exception, stackContext));
        }
Example #4
0
        /// <summary>
        /// Writes a system-level event message.
        /// </summary>
        /// <remarks>
        /// This logging method is used for the most important high-level events the user should be aware of.
        /// These events are logged into the Windows Event log instead of the trace debug log files, and would be
        /// used for logging exceptions, backup completed/sync status, configuration issues, etc.
        /// </remarks>
        /// <param name="message"></param>
        /// <param name="severity"></param>
        /// <param name="eventID"></param>
        /// <param name="writeToTraceLog"></param>
        /// <param name="engineID"></param>
        public void WriteSystemEvent(string message, EventLogEntryType severity, int eventID, bool writeToTraceLog, int engineID = 0)
        {
            if (EventLogInitialized == false)
            {
                throw new InvalidOperationException("Log has not been initialized.");
            }
            if (string.IsNullOrWhiteSpace(message))
            {
                throw new ArgumentException("Argument cannot be null or empty/whitespace: " + nameof(message));
            }

            var loggableMessage = PrependMessageWithDateAndSeverity(message, severity, engineID);

            EventLog.WriteEntry(LogSource, loggableMessage, severity, eventID);

            if (writeToTraceLog && TraceInitialized)
            {
                // also append this message to the tracelog.
                TraceMessageQueue.Enqueue(loggableMessage);
            }
        }
Example #5
0
        /// <summary>
        /// A long-running loop/thread to write trace messages to disk.
        /// </summary>
        /// <remarks>
        /// A dedicated message writer thread with retry solves two problems:
        ///  1) We can queue messages for writing- which allows the logging consumers to return immediately and not wait for logging to flush to disk.
        ///  2) Writing to a file on disk may encounter write/lock issues.
        ///     They usually crop up from things like antivirus scans. If a single log message fails to write,
        ///     then this shouldn't crash the application. This function is a loop to write with retries and delays.
        /// </remarks>
        public async Task TraceMessageWriterAsync()
        {
            while (true)
            {
                string messageToWrite = null;

                if (TraceMessageQueue.Count > 0)
                {
                    TraceMessageQueue.TryDequeue(out messageToWrite);
                }

                if (messageToWrite == null)
                {
                    await WaitAsync(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
                }
                else
                {
                    bool      successfulWrite = false;
                    Exception lastError       = null;
                    int       attempts        = 0;

                    while (true)
                    {
                        attempts++;

                        try
                        {
                            File.AppendAllText(GetCurrentTraceLogFilePath(), messageToWrite + Environment.NewLine);
                            successfulWrite = true;
                            break;
                        }
                        catch (Exception ex)
                        {
                            if (attempts >= MaxWriteAttempts)
                            {
                                lastError = ex;
                                break;
                            }
                            else
                            {
                                if (CancelSource.IsCancellationRequested)
                                {
                                    break;
                                }
                                else
                                {
                                    await WaitAsync(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
                                }
                            }
                        }
                    }

                    if (successfulWrite == false)
                    {
                        WriteSystemEvent("Failed to write a message to the tracelog.", lastError, null, EventIDs.FailedToWriteToTraceLog, false);
                    }
                }

                if (CancelSource.IsCancellationRequested)
                {
                    break;
                }
            }
        }