1949 lines · 82.2 KB · C#
RawDownload
//******************************************************************************************************
//  ErrorLogger.cs - Gbtc
//
//  Copyright © 2012, Grid Protection Alliance.  All Rights Reserved.
//
//  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
//  the NOTICE file distributed with this work for additional information regarding copyright ownership.
//  The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
//  not use this file except in compliance with the License. You may obtain a copy of the License at:
//
//      http://www.opensource.org/licenses/eclipse-1.0.php
//
//  Unless agreed to in writing, the subject software distributed under the License is distributed on an
//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
//  License for the specific language governing permissions and limitations.
//
//  Code Modification History:
//  ----------------------------------------------------------------------------------------------------
//  04/03/2007 - Pinal C. Patel
//       Original version of source code generated.
//  11/30/2007 - Pinal C. Patel
//       Modified the "design time" check in EndInit() method to use LicenseManager.UsageMode property
//       instead of DesignMode property as the former is more accurate than the latter.
//  09/17/2008 - Pinal C. Patel
//       Converted code to C#.
//  10/16/2008 - Pinal C. Patel
//       Edited code comments.
//  06/18/2009 - Pinal C. Patel
//       Modified Log() to quit if Enabled is false.
//  07/27/2009 - Pinal C. Patel
//       Made logging user information along with exception information optional via LogUserInfo property.
//  08/06/2009 - Pinal C. Patel
//       Enabled upon initialization rather than instantiation.
//  08/07/2009 - Pinal C. Patel
//       Added LoggingException event to notify about exceptions encountered when logging exceptions.
//  09/14/2009 - Stephen C. Wills
//       Added new header and license agreement.
//  02/11/2010 - Pinal C. Patel
//       Added OS version to the system information being logged.
//  03/27/2012 - prasanthgs
//       Exceptions logged through ErrorLogger are saved to backend db too.
//  12/14/2012 - Starlynn Danyelle Gilliam
//       Modified Header.
//
//******************************************************************************************************

#region [ Contributor License Agreements ]

//*******************************************************************************************************
//
//   Code based on the following project:
//        User Friendly ASP.NET Exception Handling
//        http://www.codeproject.com/KB/aspnet/ASPNETExceptionHandling.aspx
//
//   Copyright Jeff Atwood
//  
//   The Code Project Open License (CPOL):
//        http://www.codeproject.com/info/cpol10.aspx
//
//*******************************************************************************************************

#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Web;
using System.Windows.Forms;
using GSF.Configuration;
using GSF.Data;
using GSF.IO;
using GSF.Identity;
using GSF.Net.Smtp;
using GSF.Reflection;
using GSF.Windows.Forms;

namespace GSF.ErrorManagement
{
    /// <summary>
    /// Represents a logger that can be used for logging handled as well as unhandled exceptions across multiple 
    /// application types (Windows Application, Console Application, Windows Service, Web Application, Web Service).
    /// </summary>
    /// <remarks>
    /// Adapted from exception handling code by Jeff Atwood of CodingHorror.com. Demo projects for handling unhandled
    /// exception in both windows and web environment by Jeff Atwood are available at The Code Project web site.
    /// See: http://www.codeproject.com/script/articles/list_articles.asp?userid=450027
    /// </remarks>
    /// <example>
    /// This example shows how to use the <see cref="ErrorLogger"/> component to log handled and unhandled exceptions:
    /// <code>
    /// using System;
    /// using System.IO;
    /// using GSF.ErrorManagement;
    ///
    /// class Program
    /// {
    ///     static ErrorLogger s_logger;
    ///
    ///     static Program()
    ///     {
    ///         s_logger = new ErrorLogger();
    ///         s_logger.LogToUI = true;                    // Show exception info on the UI.
    ///         s_logger.LogToFile = true;                  // Log exception info to a file.
    ///         s_logger.LogToEmail = true;                 // Send exception info in an e-mail.
    ///         s_logger.LogToEventLog = true;              // Log exception info to the event log.
    ///         s_logger.LogToScreenshot = true;            // Take a screenshot of desktop on exception.
    ///         s_logger.ContactEmail = "dev@email.com";    // Provide an e-mail address.
    ///         s_logger.HandleUnhandledException = true;   // Configure to handle unhandled exceptions.
    ///         s_logger.PersistSettings = true;            // Save settings to the config file.
    ///         s_logger.Initialize();                      // Initialize ErrorLogger component for use.
    ///     }
    ///
    ///     static void Main(string[] args)
    ///     {
    ///         try
    ///         {
    ///             // This may cause a handled FileNotFoundException if the file doesn't exist.
    ///             string data = File.ReadAllText(@"c:\NonExistentFile.txt");
    ///         }
    ///         catch (Exception ex)
    ///         {
    ///             // When logging handled exceptions we want to disable loggers (UI logger and E-mail logger) that
    ///             // may require interaction either directly or indirectly as it can be annoying. All the loggers
    ///             // are enabled automatically after the handled exception has been logged.
    ///             s_logger.SuppressInteractiveLogging();
    ///             s_logger.Log(ex);
    ///         }
    ///
    ///         int numerator = 1;
    ///         int denominator = 0;
    ///         int result = numerator / denominator;   // This will cause an unhandled DivideByZeroException.
    ///
    ///         Console.ReadLine();
    ///     }
    /// }
    /// </code>
    /// </example>
    /// <seealso cref="ErrorModule"/>
    [ToolboxBitmap(typeof(ErrorLogger))]
    public class ErrorLogger : Component, ISupportLifecycle, ISupportInitialize, IProvideStatus, IPersistSettings
    {
        #region [ Members ]

        // Constants

        /// <summary>
        /// Specifies the default value for the <see cref="DefaultExceptionLogSize"/> property.
        /// </summary>
        private const int DefaultExceptionLogSize = 2000;

        /// <summary>
        /// Specifies the default value for the <see cref="LogToUI"/> property.
        /// </summary>
        public const bool DefaultLogToUI = false;

        /// <summary>
        /// Specifies the default value for the <see cref="LogToFile"/> property.
        /// </summary>
        public const bool DefaultLogToFile = true;

        /// <summary>
        /// Specifies the default value for the <see cref="LogToEmail"/> property.
        /// </summary>
        public const bool DefaultLogToEmail = false;

        /// <summary>
        /// Specifies the default value for the <see cref="LogToEventLog"/> property.
        /// </summary>
        public const bool DefaultLogToEventLog = true;

        /// <summary>
        /// Specifies the default value for the <see cref="LogToDatabase"/> property.
        /// </summary>
        public const bool DefaultLogToDatabase = false;

        /// <summary>
        /// Specifies the default value for the <see cref="LogToScreenshot"/> property.
        /// </summary>
        public const bool DefaultLogToScreenshot = false;

        /// <summary>
        /// Specifies the default value for the <see cref="LogUserInfo"/> property.
        /// </summary>
        public const bool DefaultLogUserInfo = false;

        /// <summary>
        /// Specifies the default value for the <see cref="SmtpServer"/> property.
        /// </summary>
        public const string DefaultSmtpServer = Mail.DefaultSmtpServer;

        /// <summary>
        /// Specifies the default value for the <see cref="ContactName"/> property.
        /// </summary>
        public const string DefaultContactName = "";

        /// <summary>
        /// Specifies the default value for the <see cref="ContactEmail"/> property.
        /// </summary>
        public const string DefaultContactEmail = "";

        /// <summary>
        /// Specifies the default value for the <see cref="ContactPhone"/> property.
        /// </summary>
        public const string DefaultContactPhone = "";

        /// <summary>
        /// Specifies the default value for the <see cref="PersistSettings"/> property.
        /// </summary>
        public const bool DefaultPersistSettings = false;

        /// <summary>
        /// Specifies the default value for the <see cref="SettingsCategory"/> property.
        /// </summary>
        public const string DefaultSettingsCategory = "ErrorLogger";

        /// <summary>
        /// Specifies the default value for the <see cref="HandleUnhandledException"/> property.
        /// </summary>
        public const bool DefaultHandleUnhandledException = true;

        /// <summary>
        /// Specifies the default value for the <see cref="ExitOnUnhandledException"/> property.
        /// </summary>
        public const bool DefaultExitOnUnhandledException = false;

        // Events

        /// <summary>
        /// Occurs when an <see cref="Exception"/> is encountered while logging an <see cref="Exception"/>.
        /// </summary>
        /// <remarks>
        /// <see cref="EventArgs{T}.Argument"/> is the <see cref="Exception"/> that was encountered while logging an <see cref="Exception"/>.
        /// </remarks>
        public event EventHandler<EventArgs<Exception>> LoggingException;

        // Fields
        private bool m_logToUI;
        private bool m_logToFile;
        private bool m_logToEmail;
        private bool m_logToEventLog;
        private bool m_logToDatabase;
        private bool m_logToScreenshot;
        private bool m_logUserInfo;
        private string m_smtpServer;
        private string m_contactName;
        private string m_contactEmail;
        private string m_contactPhone;
        private bool m_persistSettings;
        private string m_settingsCategory;
        private bool m_enabled;
        private bool m_handleUnhandledException;
        private bool m_exitOnUnhandledException;
        private readonly LogFile m_errorLog;
        private Exception m_lastException;
        private ApplicationType m_appType;
        private Func<string> m_errorTextMethod;
        private Func<string> m_scopeTextMethod;
        private Func<string> m_actionTextMethod;
        private Func<string> m_moreInfoTextMethod;
        private readonly List<Action<Exception>> m_loggers;
        private bool m_logToFileOK;
        private bool m_logToEmailOK;
        private bool m_logToEventLogOK;
        private bool m_logToDatabaseOK;
        private bool m_logToScreenshotOK;
        private bool m_disposed;
        private bool m_initialized;
        private bool m_suppressInteractiveLogging;

        #endregion

        #region [ Constructors ]

        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorLogger"/> class.
        /// </summary>
        public ErrorLogger()
        {
            m_logToUI = DefaultLogToUI;
            m_logToFile = DefaultLogToFile;
            m_logToEmail = DefaultLogToEmail;
            m_logToEventLog = DefaultLogToEventLog;
            m_logToDatabase = DefaultLogToDatabase;
            m_logToScreenshot = DefaultLogToScreenshot;
            m_logUserInfo = DefaultLogUserInfo;
            m_smtpServer = DefaultSmtpServer;
            m_contactName = DefaultContactName;
            m_contactEmail = DefaultContactEmail;
            m_contactPhone = DefaultContactPhone;
            m_persistSettings = DefaultPersistSettings;
            m_settingsCategory = DefaultSettingsCategory;
            m_handleUnhandledException = DefaultHandleUnhandledException;
            m_exitOnUnhandledException = DefaultExitOnUnhandledException;
            // Initialize delegate methods.
            m_errorTextMethod = GetErrorText;
            m_scopeTextMethod = GetScopeText;
            m_actionTextMethod = GetActionText;
            m_moreInfoTextMethod = GetMoreInfoText;
            // Initialize the error log file.
            m_errorLog = new LogFile();
            m_errorLog.FileName = "ErrorLog.txt";
            // Initialize all logger methods.
            m_loggers = new List<Action<Exception>>();
            m_loggers.Add(ExceptionToScreenshot);
            m_loggers.Add(ExceptionToDatabase);
            m_loggers.Add(ExceptionToEventLog);
            m_loggers.Add(ExceptionToEmail);
            m_loggers.Add(ExceptionToFile);
            m_loggers.Add(ExceptionToUI);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorLogger"/> class.
        /// </summary>
        /// <param name="container"><see cref="IContainer"/> object that contains the <see cref="ErrorLogger"/>.</param>
        public ErrorLogger(IContainer container)
            : this()
        {
            if ((object)container != null)
                container.Add(this);
        }

        #endregion

        #region [ Properties ]

        /// <summary>
        /// Gets or sets a boolean value that indicates whether <see cref="Exception"/> information is to be 
        /// displayed on the application UI.
        /// </summary>
        /// <remarks>
        /// This setting is ignored in Windows Service and Web Service application types.
        /// </remarks>
        [Category("Logging"),
        DefaultValue(DefaultLogToUI),
        Description("Indicates whether Exception information is to be displayed on the application UI.")]
        public bool LogToUI
        {
            get
            {
                return m_logToUI;
            }
            set
            {
                m_logToUI = value;
            }
        }

        /// <summary>
        /// Gets or sets a boolean value that indicates whether <see cref="Exception"/> information is to be 
        /// written to the <see cref="ErrorLog"/>.
        /// </summary>
        [Category("Logging"),
        DefaultValue(DefaultLogToFile),
        Description("Indicates whether Exception information is to be written to the ErrorLog.")]
        public bool LogToFile
        {
            get
            {
                return m_logToFile;
            }
            set
            {
                m_logToFile = value;
            }
        }

        /// <summary>
        /// Gets or sets a boolean value that indicates whether <see cref="Exception"/> information is to be sent 
        /// in an e-mail to the <see cref="ContactEmail"/> address.
        /// </summary>
        [Category("Logging"),
        DefaultValue(DefaultLogToEmail),
        Description("Indicates whether Exception information is to be sent in an e-mail to the ContactEmail address.")]
        public bool LogToEmail
        {
            get
            {
                return m_logToEmail;
            }
            set
            {
                m_logToEmail = value;
            }
        }

        /// <summary>
        /// Gets or sets a boolean value that indicates whether <see cref="Exception"/> information is to be 
        /// written to the <see cref="EventLog"/>.
        /// </summary>
        [Category("Logging"),
        DefaultValue(DefaultLogToEventLog),
        Description("Indicates whether Exception information is to be written to the EventLog.")]
        public bool LogToEventLog
        {
            get
            {
                return m_logToEventLog;
            }
            set
            {
                m_logToEventLog = value;
            }
        }

        /// <summary>
        /// Gets or sets a boolean value that indicates whether <see cref="Exception"/> information is to be 
        /// written to the database.
        /// </summary>
        [Category("Logging"),
        DefaultValue(DefaultLogToDatabase),
        Description("Indicates whether Exception information is to be written to the database.")]
        public bool LogToDatabase
        {
            get
            {
                return m_logToDatabase;
            }
            set
            {
                m_logToDatabase = value;
            }
        }

        /// <summary>
        /// Gets or sets a boolean value that indicates whether a screenshot of the user's desktop is to be taken
        /// when an <see cref="Exception"/> is logged.
        /// </summary>
        /// <remarks>
        /// This setting is ignored in Web Application and Web Service application types.
        /// </remarks>
        [Category("Logging"),
        DefaultValue(DefaultLogToScreenshot),
        Description("Indicates whether a screenshot of the user's desktop is to be taken when an Exception is logged.")]
        public bool LogToScreenshot
        {
            get
            {
                return m_logToScreenshot;
            }
            set
            {
                m_logToScreenshot = value;
            }
        }

        /// <summary>
        /// Gets or sets a boolean value that indicates whether information about local user (for windows applications) 
        /// or remote user (for web applications) is to be logged when logging an <see cref="Exception"/>.
        /// </summary>
        [Category("Logging"),
        DefaultValue(DefaultLogUserInfo),
        Description("Indicates whether information about a local user (for windows application) or remote user (for web application) is to be logged when logging an Exception.")]
        public bool LogUserInfo
        {
            get
            {
                return m_logUserInfo;
            }
            set
            {
                m_logUserInfo = value;
            }
        }

        /// <summary>
        /// Gets or sets the SMTP server to be used for sending e-mail messages containing <see cref="Exception"/> 
        /// information to the <see cref="ContactEmail"/> address.
        /// </summary>
        [Category("Settings"),
        DefaultValue(DefaultSmtpServer),
        Description("The SMTP server to be used for sending e-mail messages containing Exception information to the ContactEmail address.")]
        public string SmtpServer
        {
            get
            {
                return m_smtpServer;
            }
            set
            {
                m_smtpServer = value;
            }
        }

        /// <summary>
        /// Gets or sets the name of the person who can be contacted by the end-user in case of an <see cref="Exception"/>.
        /// </summary>
        [Category("Settings"),
        DefaultValue(DefaultContactName),
        Description("Name of the person who can be contacted by the end-user in case of an Exception.")]
        public string ContactName

Lines 1–500 of 1949.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t