Simple way to perform error logging?

后端 未结 9 1486
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-30 03:52

I\'ve created a small C# winforms application, as an added feature I was considering adding some form of error logging into it. Anyone have any suggestions for good ways to go a

相关标签:
9条回答
  • 2021-01-30 04:26

    Create a class called Log.cs I am using Linq To SQl to save to the database

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Text;
    public static partial class Log
    {
        /// <summary>
        /// Saves the exception details to ErrorLogging db with Low Priority
        /// </summary>
        /// <param name="ex">The exception.</param>
        public static void Save(this Exception ex)
        {
            Save(ex, ImpactLevel.Low, "");
        }
    
        /// <summary>
        /// Saves the exception details to ErrorLogging db with specified ImpactLevel
        /// </summary>
        /// <param name="ex">The exception.</param>
        /// <param name="impactLevel">The Impact level.</param>
        public static void Save(this Exception ex, ImpactLevel impactLevel)
        {
            Save(ex, impactLevel,"");
        }
        /// <summary>
        /// Saves the exception details to ErrorLogging db with specified ImpactLevel and user message
        /// </summary>
        /// <param name="ex">The exception</param>
        /// <param name="impactLevel">The impact level.</param>
        /// <param name="errorDescription">The error Description.</param>
        public static void Save(this Exception ex, ImpactLevel impactLevel, string errorDescription)
        {
            using (var db = new ErrorLoggingDataContext())
            {
                Log log = new Log();
    
                if (errorDescription != null && errorDescription != "")
                {
                    log.ErrorShortDescription = errorDescription;
                }
                log.ExceptionType = ex.GetType().FullName;
                var stackTrace = new StackTrace(ex, true);
                var allFrames = stackTrace.GetFrames().ToList();
                foreach (var frame in allFrames)
                {
                    log.FileName = frame.GetFileName();
                    log.LineNumber = frame.GetFileLineNumber();
                    var method = frame.GetMethod();
                    log.MethodName = method.Name;
                    log.ClassName = frame.GetMethod().DeclaringType.ToString();
                }
    
                log.ImpactLevel = impactLevel.ToString();
                try
                {
                    log.ApplicationName = Assembly.GetCallingAssembly().GetName().Name;
                }
                catch
                {
                    log.ApplicationName = "";
                }
    
                log.ErrorMessage = ex.Message;
                log.StackTrace = ex.StackTrace;
                if (ex.InnerException != null)
                {
                    log.InnerException = ex.InnerException.ToString();
                    log.InnerExceptionMessage = ex.InnerException.Message;
                }
                log.IpAddress = ""; //get the ip address
    
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    log.IsProduction = false;
                }
    
                try
                {
                    db.Logs.InsertOnSubmit(log);
                    db.SubmitChanges();
                }
                catch (Exception eex)
                {
    
                }
            }
        }
    }
    

    Create the following table

    USE [database Name]
    GO
    
    /****** Object:  Table [dbo].[Log]    Script Date: 9/27/2016 11:52:32 AM ******/
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    SET ANSI_PADDING ON
    GO
    
    CREATE TABLE [dbo].[Log](
        [LogId] [INT] IDENTITY(1,1) NOT NULL,
        [ErrorDate] [DATETIME] NOT NULL CONSTRAINT [DF_Log_Date]  DEFAULT (GETDATE()),
        [ErrorShortDescription] [VARCHAR](1000) NULL,
        [ExceptionType] [VARCHAR](255) NULL,
        [FileName] [VARCHAR](1000) NULL,
        [LineNumber] [INT] NULL,
        [MethodName] [VARCHAR](255) NULL,
        [ClassName] [VARCHAR](150) NULL,
        [ImpactLevel] [VARCHAR](50) NOT NULL,
        [ApplicationName] [VARCHAR](255) NULL,
        [ErrorMessage] [VARCHAR](4000) NULL,
        [StackTrace] [VARCHAR](MAX) NULL,
        [InnerException] [VARCHAR](2000) NULL,
        [InnerExceptionMessage] [VARCHAR](2000) NULL,
        [IpAddress] [VARCHAR](150) NULL,
        [IsProduction] [BIT] NOT NULL CONSTRAINT [DF_Log_IsProduction]  DEFAULT ((1)),
        [LastModified] [DATETIME] NOT NULL CONSTRAINT [DF_Log_LastModified]  DEFAULT (GETDATE()),
     CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED 
    (
        [LogId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
    GO
    
    SET ANSI_PADDING OFF
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'This table holds all the exceptions. 
    ErrorData = when error happened
    ,[ErrorShortDescription] == short desc about the error entered by the developers
          ,[FileName] = file where error happened full path
          ,[LineNumber] = line number where code failed
          ,[MethodName] = method name where exception happened
          ,[ClassName] = class where exception happened
          ,[ImpactLevel] = high, medium, low
          ,[ApplicationName] = name of the application where error came from
          ,[ErrorMessage] = exception error messge
          ,[StackTrace] = C# stack trace
          ,[InnerException] = inner exception of strack trace
          ,[InnerExceptionMessage] = inner message
          ,[IpAddress]
          ,[IsProduction]' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Log'
    GO
    

    Impact Level is basically Enum

     public enum ImpactLevel
        {
            High = 0,
            Medium = 1,
            Low = 2,
        }
    

    You can use it as following

    try
    {
    
    
    }
    catch(Exception ex)
    {
        //this will save the exception details and mark exception as low priority
        ex.Save();
    }
    
    
    try
    {
    
    
    }
    catch(Exception ex)
    {
        //this will save the exception details with  priority you define: High, Medium,Low
        ex.Save(ImpactLevel.Medium);
    }
    
    try
    {
    
    
    }
    catch(Exception ex)
    {
        //this will save the exception details with  priority you define: High, Medium,Low
        ex.Save(ImpactLevel.Medium, "You can enter an details you want here ");
    }
    
    0 讨论(0)
  • 2021-01-30 04:27

    You just write out your exception errors to a text file. Write to Text File. One suggestion is to put the file you create in a userdata or appdata directory though, so you do not have to struggle with permissions.

    Since this is only needed for a few months and will be discarded there is no reason to go overboard with DB. A simple text file should suffice.

    0 讨论(0)
  • 2021-01-30 04:31

    Heres example for log4net:

    1. Create a new console project called Log4NetTest
    2. Add log4net [1.2.13] nuget package into project
    3. Write following program:

      using System.Threading.Tasks;
      using log4net;
      using System.Text;
      using System.CollectionsGeneric;
      using System;
      namespace Log4NetTest
      {
          class Program
          {
      
              private static readonly ILog _logger = LogManager.GetLogger("testApp.LoggingExample");
      
              static void Main(string[] args)
              {
                  // Configure from App.config. This is marked as obsolete so you can also add config into separate config file
                  // and use log4net.Config.XmlConfigurator method to configure from xml file.            
                  log4net.Config.DOMConfigurator.Configure(); 
      
                  _logger.Debug("Shows only at debug");
                  _logger.Warn("Shows only at warn");
                  _logger.Error("Shows only at error");
      
                  Console.ReadKey();
              }
          }
      }
      
    4. Change your app.config to following:

      <!-- language: xml -->
      <?xml version="1.0" encoding="utf-8" ?> 
      <configuration> 
          <configSections> 
              <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> 
          </configSections> 
              <startup> 
                      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
              </startup> 
          <log4net debug="false"> 
              <appender name="LogFileAppender" type="log4net.Appender.FileAppender,log4net" > 
                  <param name="File" value="myLog.log" /> 
                  <param name="AppendToFile" value="true" /> 
                  <layout type="log4net.Layout.PatternLayout,log4net"> 
                      <param name="ConversionPattern" value="%date [%thread] %-5level %logger %ndc - %message%newline" /> 
                  </layout>      
              </appender> 
              <root> 
                  <priority value="ALL" /> 
                  <appender-ref ref="LogFileAppender" /> 
              </root> 
              <category name="testApp.LoggingExample"> 
                  <priority value="ALL" /> 
              </category> 
          </log4net> 
      </configuration>
      

    5.Run application and you should find following file from bin\Debug folder:

    2013-12-13 13:27:27,252 [8] DEBUG testApp.LoggingExample (null) - Shows only at debug
    2013-12-13 13:27:27,280 [8] WARN  testApp.LoggingExample (null) - Shows only at warn
    2013-12-13 13:27:27,282 [8] ERROR testApp.LoggingExample (null) - Shows only at error
    
    0 讨论(0)
  • 2021-01-30 04:37

    Instead of using log4net which is an external library I have created my own simple class, highly customizable and easy to use (edit YOURNAMESPACEHERE with the namespace that you need).

    CONSOLE APP

    using System;
    using System.IO;
    
    namespace YOURNAMESPACEHERE
    {
        enum LogEvent
        {
            Info = 0,
            Success = 1,
            Warning = 2,
            Error = 3
        }
    
        internal static class Log
        {
            private static readonly string LogSession = DateTime.Now.ToLocalTime().ToString("ddMMyyyy_HHmmss");
            private static readonly string LogPath = AppDomain.CurrentDomain.BaseDirectory + "logs";
    
            internal static void Write(LogEvent Level, string Message, bool ShowConsole = true, bool WritelogFile = true)
            {
                string Event = string.Empty;
                ConsoleColor ColorEvent = Console.ForegroundColor;
    
                switch (Level)
                {
                    case LogEvent.Info:
                        Event = "INFO";
                        ColorEvent = ConsoleColor.White;
                        break;
                    case LogEvent.Success:
                        Event = "SUCCESS";
                        ColorEvent = ConsoleColor.Green;
                        break;
                    case LogEvent.Warning:
                        Event = "WARNING";
                        ColorEvent = ConsoleColor.Yellow;
                        break;
                    case LogEvent.Error:
                        Event = "ERROR";
                        ColorEvent = ConsoleColor.Red;
                        break;
                }
    
                if (ShowConsole)
                {
                    Console.ForegroundColor = ColorEvent;
                    Console.WriteLine(" [{0}] => {1}", DateTime.Now.ToString("HH:mm:ss"), Message);
                    Console.ResetColor();
                }
    
                if (WritelogFile)
                {
                    if (!Directory.Exists(LogPath))
                        Directory.CreateDirectory(LogPath);
    
                    File.AppendAllText(LogPath + @"\" + LogSession + ".log", string.Format("[{0}] => {1}: {2}\n", DateTime.Now.ToString("HH:mm:ss"), Event, Message));
                }
            }
        }
    }
    

    NO CONSOLE APP (ONLY LOG)

    using System;
    using System.IO;
    
    namespace YOURNAMESPACEHERE
    {
        enum LogEvent
        {
            Info = 0,
            Success = 1,
            Warning = 2,
            Error = 3
        }
    
    internal static class Log
    {
        private static readonly string LogSession = DateTime.Now.ToLocalTime().ToString("ddMMyyyy_HHmmss");
        private static readonly string LogPath = AppDomain.CurrentDomain.BaseDirectory + "logs";
    
        internal static void Write(LogEvent Level, string Message)
        {
            string Event = string.Empty;
    
            switch (Level)
            {
                case LogEvent.Info:
                    Event = "INFO";
                    break;
                case LogEvent.Success:
                    Event = "SUCCESS";
                    break;
                case LogEvent.Warning:
                    Event = "WARNING";
                    break;
                case LogEvent.Error:
                    Event = "ERROR";
                    break;
            }
    
            if (!Directory.Exists(LogPath))
                Directory.CreateDirectory(LogPath);
    
            File.AppendAllText(LogPath + @"\" + LogSession + ".log", string.Format("[{0}] => {1}: {2}\n", DateTime.Now.ToString("HH:mm:ss"), Event, Message));
        }
    }
    

    Usage:

    CONSOLE APP

    Log.Write(LogEvent.Info, "Test message"); // It will print an info in your console, also will save a copy of this print in a .log file.
    Log.Write(LogEvent.Warning, "Test message", false); // It will save the print as warning only in your .log file.
    Log.Write(LogEvent.Error, "Test message", true, false); // It will print an error only in your console.
    

    NO CONSOLE APP (ONLY LOG)

    Log.Write(LogEvent.Info, "Test message"); // It will print an info in your .log file.
    
    0 讨论(0)
  • 2021-01-30 04:39

    You could use SimpleLog.

    It's a simple, but robust and powerful one-class logging solution, easy to understand, easy to integrate and easy to use. No need to spend days for setting up and customize log4Net, with that class, you're done in minutes.

    Though it currently logs to a file, it should be easily customizable to log to a database.

    http://www.codeproject.com/Tips/585796/Simple-Log

    0 讨论(0)
  • 2021-01-30 04:46

    An optimal solution, in my opinion, would be to use NLog: http://nlog-project.org/

    Just install the config package from NuGet: http://www.nuget.org/packages/NLog.Config/ and you will end up with the library and a pre-configured file logger...

    Then in your code you just need:

    // A logger member field:
    
    private readonly Logger logger = LogManager.GetCurrentClassLogger(); // creates a logger using the class name
    
    // use it:
    logger.Info(...);
    logger.Error(...);
    
    // and also:
    logger.ErrorException("text", ex); // which will log the stack trace.
    

    In the config file you get, you need to uncomment the sections that you need:

    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    
        <!-- 
            See http://nlog-project.org/wiki/Configuration_file 
            for information on customizing logging rules and outputs.
        -->
        <targets>
            <!-- add your targets here -->
    
            <!-- UNCOMMENT THIS!
            <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
                    layout="${longdate} ${uppercase:${level}} ${message}" />
            -->
        </targets>
    
        <rules>
            <!-- add your logging rules here -->
    
            <!-- UNCOMMENT THIS!
            <logger name="*" minlevel="Trace" writeTo="f" />
            -->
        </rules>
    </nlog>
    

    Edit the properties of the nlog.config file to

    Copy to Output Directory: Copy always
    
    0 讨论(0)
提交回复
热议问题