7

もう少し洗練されたエラー処理を実装しようとしています。目標を達成するには、現在の StackTrace から非ユーザー コード メソッド (フレーム) を除外する必要があります。

おそらく推測できるように、ASP.NET の典型的な StackTrace には、ユーザー コードの外部にあるため、デバッグ目的にはまったく関係のない多くのメソッドがあります。Visual Studio には、この非ユーザー コード (フレーム) を除外するオプションが用意されているので、その可能性はあると思います。しかし、約 30 分間 StackFrames のメソッドとプロパティ (およびメソッド、モジュール、アセンブリなど) を調査した後、「システム」フレームの識別に使用できるものが見つかりませんでした。

ログに記録するモジュールを手動で指定することになりました(モジュールはアセンブリの一部であり、私の場合は1:1です)。

これを行うより良い方法はありますか?コア ASP.NET 以外のすべてを含めるだけです。

4

3 に答える 3

9

StackFrameクラスには、GetMethod()取得しMethodBaseたオブジェクトからのメンバー関数があります。

単純なフィルターだけが必要な場合は、次のいずれかを実行できます。

  • 「System」で始まるクラスのすべてのメソッドを取り除きます。または「マイクロソフト」。(すべての .NET ライブラリがそこに配置されるため)。
  • メソッドが存在するアセンブリを検索し (以降を参照)、AssemblyCompanyAttribute"Microsoft Corporation" によって作成されたアセンブリをチェックしてフィルター処理します)。System名前空間内に独自の型を配置するライブラリを時々見たので、これは前の方法よりも優れています。

さらに何かが必要な場合はMethodBase.Module、そのメソッドが定義されているモジュール ( ) を取得できます。次の 2 つのオプションがあります。

  • すべてのアセンブリが署名されている場合は、その公開キー トークンを持つメソッドのみを表示できます (モジュールがプロパティで定義されているアセンブリを取得し、オブジェクトをModule.Assemblyビルドして、プロパティの公開キーをチェックします。公開キー トークンと一致する必要があります (単純に比較します)と)。AssemblyNameAssembly.FullNameAssemblyName.KeyPairGetExecutingAssembly()
  • すべてのアセンブリが署名されていない場合は、同じ操作を実行できますが、システムアセンブリの公開キー トークンに一致するすべてのアセンブリを除外できます(これは最も単純なケースであり、サード パーツ ライブラリも含まれます)。

すべてのシステム アセンブリが同じ公開キー トークンを持っているわけではないことに注意してください (同じフレームワーク バージョン内であっても)。そのため、キーのリストを収集して確認する必要があります (参照c:\windows\assemblyして読み取るだけです)。良い方法は、公開鍵を確認してから、 を使用して 2 番目のフィルターを適用することAssemblyCompanyAttributeです。

于 2012-11-19T10:25:52.117 に答える
7

'*.pdb' ファイルを展開し、例外からスタック トレースを取得しようとしているだけの場合は、例外のStackTraceプロパティを取得して行に分割し、ソース コード参照のない行を除外することができます。

        catch (Exception ex)
        {
            var lines = ex.StackTrace
                .Split(new[] {Environment.NewLine}, StringSplitOptions.None)
                .Where(l => Regex.IsMatch(l, @"([^\)]*\)) in (.*):line (\d)*$"));
            var userStackTrace = string.Join(Environment.NewLine, lines);
        }
于 2014-01-21T11:57:34.667 に答える
0

私は同じ問題に遭遇しましたが、NLog と TraceSource を使用し、System.Net Trace Events を NLog ターゲットにリダイレクトしました。とはいえ、システム アセンブリを除外してもうまくいかなかったため、カスタム属性を確認する必要がありました。

    private static bool IsOkay(StackFrame arg)
    {
        var method = arg.GetMethod();
        var methodAttributes = new Attribute[] { }
            .Concat(method.GetCustomAttributes<DebuggerHiddenAttribute>())
            .Concat(method.GetCustomAttributes<CompilerGeneratedAttribute>());

        if (methodAttributes.Any())
            return false;

        var methodDeclearingType = method.DeclaringType;
        var methodDeclearingTypeAttributes = new Attribute[] { }
            .Concat(methodDeclearingType.GetCustomAttributes<CompilerGeneratedAttribute>());

        if (methodDeclearingTypeAttributes.Any())
            return false;

        var methodDeclearingTypeModule = methodDeclearingType.Module;
        var methodDeclearingTypeModuleAttributes = new Attribute[] { }
            .Concat(methodDeclearingTypeModule.GetCustomAttributes<UnverifiableCodeAttribute>());

        if (methodDeclearingTypeModuleAttributes.Any())
            return false;

        return true;
    }

BR、インキュアフォース

于 2016-05-17T13:16:19.073 に答える