Как разбить строку stacktrace на пространство имен, класс, файл метода и номер строки?

Трассировки стека С# имеют следующий вид:

   at Foo.Core.Test.FinalMethod(Doh doh) in C:\Projects\src\Core.Tests\Test.cs:line 21
   at Foo.Core.Test.AnotherMethod(Bar bar)
   at Foo.Core.Test.AMethod() in C:\Projects\src\Core.Tests\Test.cs:line 6
   at Foo.Core.Test.<>c__DisplayClass7.<SomeAnonDelegate>b__6(Object _) in C:\Projects\src\Core.Tests\Test.cs:line 35

Как я могу получить пространство имен, класс, метод, файл и номер строки из каждой строки?

  • Существуют ли какие-либо существующие классы для этого?
  • Если это не лучший способ?
  • Regex? Как я с жадностью сопоставляю пространство имен, но оставим класс и метод?
  • Пользовательский парсер?

Поблагодарили бы за некоторые идеи и ввод.

Ответ 1

Если вы получаете это от StackTrace, вы можете выполнить цикл StackFrames через GetFrame и позвоните GetMethod, GetFileName и GetFileLineNumber. Пространство имен и класс могут быть извлечены из метода.

ИЗМЕНИТЬ
В ответ на первый комментарий (к сожалению, мы получаем следы от Exception.StackTrace), вы можете вызвать конструктор StackTrace (Exception).

ИЗМЕНИТЬ
Я должен был привязаться к этому конструктору вместо этого - StackTrace (исключение, bool).

Ответ 2

Я прочитал ответ Остина Салонена, и это очевидно лучше, но я уже начал с регулярного выражения. поэтому я все равно напишу.

Regex r = new Regex(@"at (?<namespace>.*)\.(?<class>.*)\.(?<method>.*(.*)) in (?<file>.*):line (?<line>\d*)");
var result = r.Match(@"at Foo.Core.Test.FinalMethod(Doh doh) in C:\Projects\src\Core.Tests\Test.cs:line 21");
if (result.Success)
{
    string _namespace = result.Groups["namespace"].Value.ToString();
    string _class = result.Groups["class"].Value.ToString();
    string _method = result.Groups["method"].Value.ToString();
    string _file = result.Groups["file"].Value.ToString();
    string _line = result.Groups["line"].Value.ToString();
    Console.WriteLine("namespace: " + _namespace);
    Console.WriteLine("class: " + _class);
    Console.WriteLine("method: " + _method);
    Console.WriteLine("file: " + _file);
    Console.WriteLine("line: " + _line);
}

Ответ 3

StackTraceParser может анализировать вывод текста трассировки стека (например, обычно возвращается Environment.StackTrace или Exception.StackTrace) обратно в последовательность кадров трассировки стека, включая следующие компоненты:

Type
Method
Parameter types and names
File and line information, if present

Он доступен как исходный пакет NuGet, который напрямую встраивается в проект С#.

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

public static IEnumerable<TFrame> Parse<TToken, TMethod, TParameters, TParameter, TSourceLocation, TFrame>(
    string text,
    Func<int, int, string, TToken> tokenSelector,
    Func<TToken, TToken, TMethod> methodSelector,
    Func<TToken, TToken, TParameter> parameterSelector,
    Func<TToken, IEnumerable<TParameter>, TParameters> parametersSelector,
    Func<TToken, TToken, TSourceLocation> sourceLocationSelector,
    Func<TToken, TMethod, TParameters, TSourceLocation, TFrame> selector)

См. примеры в https://github.com/atifaziz/StackTraceParser и https://bitbucket.org/project-elmah/main/src/2a6b0b5916a6b4913ca5af4c22c4e4fc69f1260d/src/Elmah.AspNet/ErrorDetailPage.cs?at=default&fileviewer=file-view-default