How to split a stacktrace line into namespace, class, method file and line number?

后端 未结 3 1667
悲哀的现实
悲哀的现实 2020-12-10 05:07

C# stack traces take the following form:

   at Foo.Core.Test.FinalMethod(Doh doh) in C:\\Projects\\src\\Core.Tests\\Test.cs:line 21
   at Foo.Core.Test.Anoth         


        
相关标签:
3条回答
  • 2020-12-10 05:42

    If you're getting this from a StackTrace, then you can loop through the StackFrames via GetFrame and call GetMethod, GetFileName, and GetFileLineNumber. Namespace and class can be retrieved from the method.

    EDIT
    In response to the first comment (unfortunately we get the traces from Exception.StackTrace), you can call the StackTrace(Exception) constructor.

    EDIT
    I should've linked to this constructor instead -- StackTrace(Exception,bool).

    0 讨论(0)
  • 2020-12-10 05:42

    StackTraceParser can parse a stack trace text output (e.g. typically returned by Environment.StackTrace or Exception.StackTrace) back into a sequence of stack trace frames, including the following components:

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

    It is available as a NuGet source package that directly embeds into a C# project.

    However it requires a few functions to specify and it's usage is not immediately obvious.

    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)
    

    See examples in https://github.com/atifaziz/StackTraceParser and https://bitbucket.org/project-elmah/main/src/2a6b0b5916a6b4913ca5af4c22c4e4fc69f1260d/src/Elmah.AspNet/ErrorDetailPage.cs?at=default&fileviewer=file-view-default

    0 讨论(0)
  • 2020-12-10 06:04

    I read the Austin Salonen's answer and it's obvious better, but I've already started with regex. so I'll write it anyway.

    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);
    }
    
    0 讨论(0)
提交回复
热议问题