1

System.Diagnostics でトレース機能を使用していて、ある種の問題に遭遇しました。問題なくアプリケーションにトレース自体を実装しましたが、いくつかのベスト プラクティスについて苦労しています。もっと簡単に言えば、方法は理解できますが、理由は理解できません。

クライアントがWebブラウザーであるRESTfulクライアント/サーバーアプリがあり、サーバーは他の場所で呼び出しを行いません(たとえば、他のサーバープロセスへのWCF呼び出しはありません)。

私が理解しようとしている概念は、アクティビティの概念です。トレースは概念的にグループ化されているため、特定のアクティビティのすべてのトレース メッセージを表示できます。1 回のページ読み込み中に、さまざまなクラスを多数呼び出して、データベースからデータを取得したり、データに対してビジネス ロジックを実行したりします。

アクティビティの粒度はどれくらいですか? 「ページの読み込みは単一のアクティビティ」または「各メソッド呼び出しは新しいサブ アクティビティ」の両極端ですか? それとも、おそらく中間にあるものでしょうか: 「データ アクセス呼び出しとページ読み込み時のビジネス ロジック呼び出しは両方ともサブ アクティビティであり、それ以外はすべてメイン ページ読み込みアクティビティの下にあります」?

もう 1 つの概念は、CorrelationManager.StartLogicalOperationメソッドの概念です。繰り返しますが、これの実装はトリッキーではありませんが、それを使用する理由を理解するのは難しいです。これにより、一連のトレースを logicalOperation 名の下にグループ化できるようです。ただし、ここにはトレース アクティビティ グループの概念との重複があるようです。これら 2 つの概念を一緒に使用する必要がありますか? なぜ/どのような状況でどちらを使用しますか?

4

1 に答える 1

0

これらの概念 (Activity と LogicalOperation) は直交していると思います。内部に多くの LogicalOperations を持つ Activity を持つことができます。または、Activity が変更される可能性のある LogicalOperation を持つこともできます。アクティビティが LogicalOperation よりも高いレベルにあることがより一般的だと思います。

私がそう言うのはおそらくあまり役​​に立ちませんが、ロギングを整理する限り、あなたとあなたのアプリケーションにとって何が最も理にかなっているのかを決めるのはあなた次第です。

単一のリクエストの結果が単一のアクティビティになるのが一般的だと思います。

Activity と LogicalOperation の管理を容易にするヘルパー クラスがあると役立つ場合があります。このようなもの:

class ActivityScope : IDisposable
{
  Guid oldActivity;
  ActivityScope()
  {
    oldActivity = System.Diagnostics.CorrelationManager.ActivityId;
    System.Diagnostics.CorrelationManager.ActivityId = Guid.NewGuid();
  }

  public void Dispose()
  {
    System.Diagnostics.CorrelationManager.ActivityId = oldActivity;
  }
}

class LogicalOperationScope : IDisposable
{
  public LogicalOperationScope(string logicalOperation)
  {
    System.Diagnostics.CorrelationManager.StartLogicalOperation(logicalOperation);
  }

  public void Dispose()
  {
    System.Diagnostics.CorrelationManager.StopLogicalOperation();
  }
}

次のように使用できます。

void ServiceARequest()
{
  using (new ActivityScope())
  {
    //Do some stuff

    using (new LogicalOperationScope("SomeWork"))
    {
      DoSomeWork();

      for (int i = 0; i < 10; i++)
      {
        using (new LogicalOperationScope(string.Format("nested {0}", i))
        {
          DoNestedWork(i);
        }
      }
    }
  }
}

void DoSomeWork()
{
  using (new LogicalOperationScope("DoSomeWork"))
  {
  }
}

void DoNestedWork(int level)
{
}

明らかに、私の例は診断コードに重点を置いており、実際のコードは軽視していますが、その考えは理解できます。ActivityId または LogicalOperation を持つことに意味がある場合は、これに似た「スコープ」クラスでそれらを管理してみてください。

幸運を!

于 2013-03-29T20:09:38.760 に答える