Подтвердить что ты не робот

Простой способ выполнить регистрацию ошибок?

Я создал небольшое приложение winforms для С#, которое добавило мне возможность добавить в него какую-то форму регистрации ошибок. У кого-нибудь есть какие-то предложения по хорошим путям? Это функция, которую я никогда не рассматривал в дополнение к предыдущим проектам, поэтому я открыт для предложений от разработчиков, у которых больше опыта.

Я рассматривал что-то вроде строк для записи исключений в указанный текстовый файл или, возможно, в таблицу базы данных. Это приложение, которое будет использоваться в течение нескольких месяцев, а затем отбрасывается, когда заканчивается более крупный продукт.

4b9b3361

Ответ 1

Я бы не слишком много копал в внешних библиотеках, так как ваши потребности в протоколировании просты.

.NET Framework уже поставляется с этой функцией в пространстве имен System.Diagnostics, вы можете записать все необходимые вам журналы, просто вызывая методы под Trace класс:

Trace.TraceInformation("Your Information");
Trace.TraceError("Your Error");
Trace.TraceWarning("Your Warning");

И затем настройте все прослушиватели трассировки, соответствующие вашим потребностям, в файле app.config:

<configuration>
  // other config
  <system.diagnostics>
    <trace autoflush="true" indentsize="4">
      <listeners>
        <add name="consoleListener" type="System.Diagnostics.ConsoleTraceListener"/>
        <add name="textWriterListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="YourLogFile.txt"/>
        <add name="eventLogListener" type="System.Diagnostics.EventLogTraceListener" initializeData="YourEventLogSource" />
        <remove name="Default"/>
      </listeners>
    </trace>
  </system.diagnostics>
  // other config
</configuration>

или, если хотите, вы также можете настроить своих слушателей в своем приложении, не зависимо от конфигурационного файла:

Trace.Listeners.Add(new TextWriterTraceListener("MyTextFile.log"));

Не забудьте установить для свойства Trace.AutoFlush значение true, чтобы текстовый журнал работал правильно.

Ответ 2

Оптимальным решением, на мой взгляд, было бы использование NLog: http://nlog-project.org/

Просто установите конфигурационный пакет из NuGet: http://www.nuget.org/packages/NLog.Config/, и вы получите библиотеку и предварительно сконфигурированный регистратор файлов..

Тогда в вашем коде вам просто нужно:

// 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.

В полученном файле конфигурации вам необходимо раскомментировать разделы, которые вам нужны:

<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>

Ответ 3

Вы можете использовать SimpleLog.

Это простое, но надежное и мощное одноклассовое решение для ведения журналов, которое легко понять, легко интегрируется и прост в использовании. Не нужно тратить дни на настройку и настройку log4Net, с этим классом вы делаете это за считанные минуты.

Хотя он в настоящее время регистрируется в файле, его легко настроить для входа в базу данных.

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

Ответ 4

Хорошо log4net работает как кирпич. Это может быть немного сложно настроить, но это того стоит. Он также позволяет настраивать блокировку файлов этих файлов журналов и т.д.

http://www.codeproject.com/Articles/140911/log4net-Tutorial

Ответ 5

Вот пример для log4net:

  • Создайте новый проект консоли Log4NetTest
  • Добавить log4net [1.2.13] пакет nuget в проект
  • Напишите следующую программу:

    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();
            }
        }
    }
    
  • Измените свой app.config на следующий:

    <!-- 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, и вы должны найти следующий файл из папки bin\Debug:

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

Ответ 6

Вы просто записываете ошибки исключения в текстовый файл. Запись в текстовый файл. Одно из предложений состоит в том, чтобы поместить файл, который вы создаете, в каталог userdata или appdata, хотя вам не нужно бороться с разрешениями.

Так как это требуется всего несколько месяцев и будет отброшено, нет никаких оснований переходить за борт с БД. Простой текстовый файл должен быть достаточным.

Ответ 7

Создайте класс Log.cs Я использую Linq To SQl для сохранения в базе данных

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)
            {

            }
        }
    }
}

Создайте следующую таблицу

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

Уровень воздействия в основном Enum

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

Вы можете использовать его как следующий

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 ");
}