ULS ログのヒント パート 2

ULS ログのヒント パート 2

ULS ログのヒントのパート 1 (http://blogs.msdn.com/b/sharepoint_jp/archive/2011/03/21/uls.aspx ) では、カスタム ULS ログ領域を追加するためのコードを用意し、それをプロジェクトで使用する方法を示しました。 あの後でいくつか気付いたことがあります。

1. 一部のコードが最新の SDK と一致していませんでした。基本的に、SDK で示されていた一部のコードが必要ではなく、使用した方法が SDK の例とは若干異なっていました (更新する必要がありますが、それについては別に行います)。

2. ログの記録は TraceSeverity を Medium に設定したときに行われます。別のトレース レベルに設定する有効な方法はありません。

3. 最大の問題は、カスタム領域に必要なカスタム クラスを呼び出そうとしたとき、POST アクティビティの間にログを記録しようとすると失敗することです。 AllowUnsafeUpdates プロパティを true に設定しないと、POST の間に SPWeb を更新できないことについてのあらゆる一般的なエラーが発生します。 このログ イベントを動作させるためだけに、ログ イベントの間に SPWeb でそれを設定していますが、ばかげたことです (このような表現を使うことを許してください)。 そこで、もっとよい方法を使うことにしました。

この投稿では、前回の例を改善することにします。 以下のことを示します。

1. カスタム領域の改善したクラス。実際にはこのバージョンでは少しスリムになっています。

2. サーバーの全体管理の [監視] (Monitoring) セクションの [診断ログの構成] (Configure diagnostic logging) との統合。 この統合により、カスタム領域およびカテゴリでトレース レベルを構成できるようになります。

3. 登録情報。カスタム ULS ログ クラスを登録および登録解除する非常に簡単な方法であり、サーバーの全体管理と統合したり削除したりできます。

最初に、簡素化された新しいクラスを見ておきます。 多くは最初の投稿で示したバージョンと似ていますが、少しだけスリム化されて簡単になっています。 以下がそのクラスです。

    [Guid("833B687D-0DD1-4F17-BF6A-B64FBC1AC6A8")]

    public class SteveDiagnosticService : SPDiagnosticsServiceBase

    {

        private const string LOG_AREA = "Steve Area";

        public enum LogCategories

        {

            SteveCategory

        }

        public SteveDiagnosticService()

        {

        }

        public SteveDiagnosticService(string name, SPFarm parent)

            : base(name, parent)

        {

        }

        public static SteveDiagnosticService Local

        {

            get

            {

                return SPDiagnosticsServiceBase.GetLocal<SteveDiagnosticService>();

            }

        }

        public void LogMessage(ushort id, LogCategories LogCategory,

TraceSeverity traceSeverity, string message,

params object[] data)

        {

            if (traceSeverity != TraceSeverity.None)

            {

                SPDiagnosticsCategory category

                 = Local.Areas[LOG_AREA].Categories[LogCategory.ToString()];

                Local.WriteTrace(id, category, traceSeverity, message, data);

            }

     }

        protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()

        {

yield return new SPDiagnosticsArea(LOG_AREA, 0, 0, false,

new List<SPDiagnosticsCategory>()

{

new

SPDiagnosticsCategory(LogCategories.AzureConfig.ToString(),

                     TraceSeverity.Medium, EventSeverity.Information, 1,

                     Log.LOG_ID)

                });

        }

    }

 

ここには最初のバージョンから重要な変更があります。

1.  クラスに Guid 属性が追加されています。

[Guid("833B687D-0DD1-4F17-BF6A-B64FBC1AC6A8")]

 

Guid 属性をクラスに追加したのは、SharePoint が構成データベースで一意に識別するために必要なためです。

2. 既定のコンストラクターを変更しました。

        public SteveDiagnosticService()

        {

        }

 

標準の空のコンストラクターになっています。 前は、サービスの名前と SPFarm を受け取るコンストラクターの他のオーバーロードを呼び出していました。 少ないコードで問題なければ、それにこしたことはありません。

3. HasAdditionalUpdateAccess オーバーライドを削除しました。 やはり、実際には使っていないことがわかったため、"少ない方がよい" ということで削除しました。

 

4. ProvideAreas メソッドを大幅に短くしました。SDK で使用されている同じパターンと一致するようになっています。

 

yield return new SPDiagnosticsArea(LOG_AREA, 0, 0, false,

new List<SPDiagnosticsCategory>()

{

new

SPDiagnosticsCategory(LogCategories.AzureConfig.ToString(),

                     TraceSeverity.Medium, EventSeverity.Information, 1,

                     Log.LOG_ID)

                });

前記の問題 #1 に対処したことで、コードは少しだけ簡潔で小さくなっています。 トレース レベルの欠如、POST の間にログを行ったときのスローされる例外、サーバーの全体管理との統合などの他の問題は、コードをさらに修正して登録することで基本的にすべて解決しました。 現在 SDK の例はこの部分は弱点ですが、必要を満たすことができるようになりました。 問題を簡単にするため、前に説明したカスタム ULS クラスを含むアセンブリ用の新しい機能を作成しました。 機能レシーバーを追加し、FeatureInstalled イベントの間にカスタム ULS を登録し、FeatureUninstalling イベントの間に登録を解除しています。 この機能をファーム スコープの機能にしたため、ソリューションが追加されて展開されると自動的にアクティブ化されるため、これはこの場合にはよい解決策でした。 わかったことは、この登録と登録解除を行うためのコードは次のようにとても簡単であるということです。

public override void FeatureInstalled(SPFeatureReceiverProperties properties)

{

try

       {

SteveDiagnosticsService.Local.Update();

}

catch (Exception ex)

       {

throw new Exception("Error installing feature: " + ex.Message);

}

}

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)

{

try

       {

SteveDiagnosticsService.Local.Delete();

}

catch (Exception ex)

{

throw new Exception("Error uninstalling feature: " + ex.Message);

}

}

もう 1 つ指摘することは、"SteveDiagnosticService" を参照できたことです。これは、a) 機能をパッケージ化したプロジェクトでカスタム ログ クラスのアセンブリに参照を追加し、b) カスタム ログ クラスのアセンブリに対する機能レシーバー クラスに using ステートメントを追加したためです。

カスタム ULS ログ クラスを登録することで、いくつかのメリットがあります。

· POST の間に ULS ログを書き込んでも、SPWeb 更新の問題に関するエラーが発生しなくなります

· カスタム ログ領域とカテゴリがサーバーの全体管理に表示されるので、[診断ログの構成] (Configure diagnostic logging) でトレースとイベントのレベルを変更できます。 たとえば、既定の Medium トレース レベルの場合、TracingSeverity.Medium であるすべての ULS はログに書き込まれますが、TracingSeverity.Verbose は書き込まれません。 TracingSeverity.Verbose のエントリをログに書き込むには、[診断ログの構成] (Configure diagnostic logging) でトレースのレベルを Verbose に変更するだけで済みます。

ソリューション全体はいっそう簡単になり、機能も向上しました。 これはよく耳にする一挙両得ということだと思います。

補足 私はここでポートランド トレイルブレイザーズの LaMarcus Aldridge に関して抗議したいと思います。 彼がウエスタン カンファレンスの NBA オール スター チームに選ばれなかったことはとてもばかげたことです。 個人的論評は十分でしょう。ここを訪れるときはみんな Share-n-Dipity-icous の情報を探しているということはわかっています。 これが役に立つことを祈ります。

これはローカライズされたブログ投稿です。原文の記事は、「Tips for ULS Logging Part 2」をご覧ください。