Исключение регистрации в С#

регистрация исключений с помощью приведенного ниже кода позволяет сохранить содержимое исключения в текстовом файле. Здесь я получаю только описание ошибки.

но это не говорит мне, где произошло исключение, на какой линии. Может кто-нибудь сказать мне, как я могу добиться этого, чтобы я мог получить даже номер строки, где произошло исключение?

#region WriteLogError
/// <summary>
/// Write an error Log in File
/// </summary>
/// <param name="errorMessage"></param>
public void WriteLogError(string errorMessage)
{
  try
  {
    string path = "~/Error/" + DateTime.Today.ToString("dd-mm-yy") + ".txt";
    if (!File.Exists(System.Web.HttpContext.Current.Server.MapPath(path)))
    {
      File.Create(System.Web.HttpContext.Current.Server.MapPath(path))
     .Close();
    }
    using (StreamWriter w = File.AppendText(System.Web.HttpContext.Current.Server.MapPath(path)))
    {
      w.WriteLine("\r\nLog Entry : ");
      w.WriteLine("{0}", DateTime.Now.ToString(CultureInfo.InvariantCulture));
      string err = "Error in: " + System.Web.HttpContext.Current.Request.Url.ToString() 
                 + ". Error Message:" + errorMessage;
      w.WriteLine(err);
      w.WriteLine("__________________________");
      w.Flush();
      w.Close();
    }
  }
  catch (Exception ex)
  {
    WriteLogError(ex.Message);
  }

}

#endregion

Ответ 1

Я считаю, что самый простой способ регистрировать исключения в С# - это вызвать метод ToString():

try
{

}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}

Это обычно дает вам всю необходимую информацию, такую как сообщение об ошибке и трассировку стека, а также любую дополнительную информацию, относящуюся к конкретному исключению. (однако учтите, что трассировка стека покажет вам исходные файлы и номера строк, если ваше приложение скомпилировано с отладочной информацией)

Тем не менее, стоит отметить, что просмотр трассировки полного стека может быть довольно утомительным для пользователя, и поэтому, где это возможно, вы должны стараться обрабатывать исключения и выводить более понятное сообщение об ошибке.

Еще одно замечание - вы должны заменить свой метод WriteLogError на полнофункциональную структуру ведения журналов (например, Serilog) вместо того, чтобы пытаться написать свой собственный.

Ваш метод регистрации не является потокобезопасным (ваш файл журнала, вероятно, в конечном итоге будет содержать сообщения журнала, смешанные друг с другом), а также определенно не должен вызывать сам себя, если вы поймаете исключение - это будет означать, что любые исключения, возникающие во время ошибок регистрации, вероятно, будут вызвать сложную диагностику исключений Qaru.

Я мог бы предложить, как исправить эти вещи, однако вам будет гораздо лучше обслужиться, просто используя надлежащую структуру ведения журналов.

Ответ 2

Просто зарегистрируйтесь ToString(). Он не только даст вам трассировку стека, но также включает внутренние исключения.

Ответ 3

Кроме того, когда вы, например, развертываете сборку своего кода в производственной среде, не забудьте включить файлы .pdb в пакет выпуска. Вам нужен этот файл, чтобы получить номер строки для этого кода (см. Сколько информации содержатся в файлах pdb? (С#/.NET))

Ответ 4

Ваше решение довольно хорошее. Я прошел через ту же фазу
и в конце концов нужно было регистрировать все больше и больше (это будет...):

  • расположение источника журналирования
  • стек вызовов до исключения (может быть в другом месте)
  • все внутренние исключения одинаково
  • идентификатор процесса/идентификатор потока
  • время (или запрос тиков)
  • для веб - URL, заголовки http, ip клиента, куки, содержимое веб-сессии
  • некоторые другие значения критических переменных
  • загруженные сборки в памяти
  • ...

Желательно, чтобы я щелкнул ссылку на файл, где произошла ошибка,
или щелкнул ссылку в стеке вызовов, и Visual Studio открылась в соответствующем месте.
(Конечно, все, что вам нужно сделать, это файлы *.PDB, где пути из кода IL
на ваш выпущенный источник в С# хранятся.)

Итак, я наконец начал использовать это решение:
Он существует как пакет Nuget - Desharp.
Это для обоих типов приложений - веб и рабочего стола.
Смотрите документацию Desharp Github. У него много параметров конфигурации.

try {
    var myStrangeObj = new { /*... something really mysterious ...*/ };
    throw new Exception("Something really baaaaad with my strange object :-)");
} catch (Exception ex) {

    // store any rendered object in debug.html or debug.log file
    Desharp.Debug.Log(myStrangeObj, Desharp.Level.DEBUG);

    // store exception with all inner exceptions and everything else
    // you need to know later in exceptions.html or exceptions.log file
    Desharp.Debug.Log(ex);
}

У этого есть форматы журнала HTML, каждое исключение в одной строке,
а со страницы HTML, которую вы можете открыть в браузере, вы можете нажать
на ссылку на файл и перейти к Visual Studio - это действительно затягивает!
Необходимо только установить этот редактор открытий Desharp.

Смотрите некоторые демонстрации здесь:

Попробуйте проверить любой из этих репозиториев и зарегистрировать что-нибудь, как описано выше.
затем вы можете увидеть результаты в журнале ~/Logs. В основном все настраивается.

Ответ 5

Я отвечаю только на вопрос, другие уже упоминали о коде. Если вы хотите, чтобы номер строки был включен в ваш журнал, вам нужно включить сгенерированные файлы отладки (pdb) в ваше развертывание на сервере. Если это только ваш регион разработки/тестирования, это хорошо, но я не рекомендую использовать в производстве.

Ответ 6

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

Запись в выходной файл, конечно, может быть выполнена с помощью ToString() вместо чтения только сообщения об ошибке, как указано в других ответах.

Исключительный класс

https://docs.microsoft.com/en-us/dotnet/api/system.exception?redirectedfrom=MSDN&view=netframework-4.7.2

Информация о сериализации, акте преобразования объекта в файл на диске и наоборот.

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/serialization/