简体   繁体   English

记录任何类型的异常的所有异常信息

[英]Log all exception information for any kind of exception

I'm developing with C#, ASP.NET MVC Web Api, Entity Framework and .NET Framework 4.0. 我正在使用C#,ASP.NET MVC Web Api,实体框架和.NET Framework 4.0进行开发。

I have this code to log an exception: 我有这个代码来记录异常:

public void LogCompleteException(
    string controllerName,
    string actionName,
    Exception exception)
{
    string exceptionMessage = string.Empty;

    Exception e = exception;
    if (e.InnerException == null)
        e = null;
    else
        while (e.InnerException != null) e = e.InnerException;

    if (e == null)
        exceptionMessage = exception.Message;
    else
        exceptionMessage = string.Format("{0}\n\rInnerException: {1}", exception.Message, e.Message);

    _logger.ErrorFormat(
        LogTextFormatString,
        ExceptionText,
        controllerName,
        actionName,
        exceptionMessage);
}

But on my log file I have found this: 但是在我的日志文件中我发现了这个:

Validation failed for one or more entities. 一个或多个实体的验证失败。 See 'EntityValidationErrors' property for more details. 有关详细信息,请参阅“EntityValidationErrors”属性。

When I wrote 'See 'EntityValidationErrors' property for more details.', I'm only showing an example where I haven't log an important property. 当我编写'See'EntityValidationErrors'属性以获取更多详细信息。', 我只是展示了一个我没有记录重要属性的示例

There are a lot of kind of exceptions; 有很多例外; but with my method I'm not logging all the relevant information because there could be properties like 'EntityValidationErrors' that I don't log. 但是使用我的方法,我没有记录所有相关信息,因为可能存在我没有记录的'EntityValidationErrors'等属性。

When I pass the exception to log it I don't know what properties it has, and I don't know how to log each property it has. 当我传递异常来记录它时,我不知道它有什么属性,我不知道如何记录它拥有的每个属性。

Do you know a method to log an exception completely? 你知道一种完全记录异常的方法吗? My code doesn't long exceptions with an EntityValidationErrors property or any other important property. 我的代码与EntityValidationErrors属性或任何其他重要属性的长期异常并不长。

I'm doing the logging with log4net. 我正在使用log4net进行日志记录。

Since the inner exception is an exception itself, perhaps you can just recurse and reuse the method you already have: 由于内部异常本身就是一个异常,也许您只需递归并重用已有的方法:

if (e.InnerException != null)
{
    LogCompleteException(controllerName, actionName, e.InnerException);
}

If this does work, however, you will still be missing the EntityValidationErrors. 但是,如果这确实有效,您仍将缺少EntityValidationErrors。

Another method, which I used recently is to just explicitly trap and log the exception where it occurs: 我最近使用的另一种方法是显式地捕获并记录发生的异常:

try
{
    db.Add(something);
    db.SaveChanges();
}
catch (DbEntityValidationException ex)
{
    StringBuilder sb = new StringBuilder();

    // collect some extra info about the exception before logging
    foreach (var eve in ex.EntityValidationErrors)
    {
        sb.AppendLine(String.Format("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", eve.Entry.Entity.GetType().Name, eve.Entry.State));
        foreach (var ve in eve.ValidationErrors)
        {
            sb.AppendLine(String.Format("Property: \"{0}\", Error: \"{1}\"", ve.PropertyName, ve.ErrorMessage));
        }
    }

    logger.Error("There was an error while trying to parse and save something!\n" + sb.ToString(), ex);
}

If you want the Exception.Data dictionary entries, you can add those as well: 如果你想要Exception.Data字典条目,你也可以添加它们:

foreach (DictionaryEntry entry in ex.Data)
{
    // you will want to use a StringBuilder instead of concatenating strings if you do this
    exceptionMessage = exceptionMessage + string.Format("Exception.Data[{0}]: {1}", entry.Key, entry.Value);
}

As for properties for Custom exception classes just as the EntityValidationErrors, I would just trap and parse those where they occur. 至于Custom异常类的属性就像EntityValidationErrors一样,我只是陷阱并解析它们出现的位置。 Otherwise you would have to override ToString() on every exception type or use some reflection hackery to enumerate all the properties which would significantly clutter the logs with properties you dont care about. 否则,您必须在每个异常类型上覆盖ToString()或使用一些反射hackery枚举所有属性,这些属性会使您不关心的属性显着混乱。

you could use elmah and the log4net appender . 你可以使用elmahlog4net appender Elmah logs catches all exceptions and can log them to a log4net instance. Elmah日志捕获所有异常,并可以将它们记录到log4net实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM