Как разбить строку 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