Wicket wicket-devutils を使って Session や Datastore の 状況を確認する


Wicket の ページ Cache の具合等を確認できる術がないのか
調べていたところ、wicket/wicket-devutils at master · apache/wicketで、
確認ができそうだったので、試しに使ってみました。
使ってみた結果をメモします。


参考


何ができるのか?

以下、開発時に役に立ちそうな機能を追加できます。

  • Wicket Inspector Wicket が Session に保持しているオブジェクトを2つの View で参照することができます。

  • Active sessions
    Wicket の Datastore の状況を確認できます。

  • StatelessChecker
    Page が Stateless か を検証する IComponentOnBeforeRenderListener の実装クラスが含まれています。


インストール と 設定方法

前提. 使用している Wicket Version

  • Wicket 7.5
    <dependency>
        <groupId>org.apache.wicket</groupId>
        <artifactId>wicket-core</artifactId>
        <version>7.5.0</version>
    </dependency>

pom.xml に Dependency を追加する

<!-- https://mvnrepository.com/artifact/org.apache.wicket/wicket-devutils -->
<dependency>
    <groupId>org.apache.wicket</groupId>
    <artifactId>wicket-devutils</artifactId>
    <version>7.5.0</version>
</dependency>

Application クラスでページをマウントする

以下、Developmentモードの場合に、wicket-devutils のページをマウントします。

    // configure Logger of MongoDB
    if (usesDevelopmentConfig()) {
        // -----------------------------------
        // mount Dev utils Page
        // -------
        DebugDiskDataStore.register(this);
        mountPage("wicket/internal/debug/utils", DevUtilsPage.class);
        // -----------------------------------
        // add StatelessChecker
        // -------
        getComponentPostOnBeforeRenderListeners().add(new StatelessChecker());
    }
  • 説明1

    DebugDiskDataStore.register(this);
    
    の内の処理は、以下の通りです。
        public static void register(Application application) {
            application.setPageManagerProvider(new DebugPageManagerProvider(application));
            ((WebApplication)application).mountPage("wicket/internal/debug/diskDataStore", DiskStoreBrowserPage.class);
        }
    
    DiskStore の閲覧用途で、DebugPageManagerProvider を設定してから、
    DiskStoreBrowserPage を、wicket/internal/debug/diskDataStore にマウントしております。
    DebugPageManagerProvider を設定なしに mount したところ、
    ClassCastException が発生しました。
    ! java.lang.ClassCastException: org.apache.wicket.DefaultPageManagerProvider cannot be cast to org.apache.wicket.devutils.diskstore.DebugPageManagerProvider
    ! at org.apache.wicket.devutils.diskstore.browser.DataStoreHelper.getDataStore(DataStoreHelper.java:38)
    ! at org.apache.wicket.devutils.diskstore.browser.SessionsProviderModel.load(SessionsProviderModel.java:40)
    ! at org.apache.wicket.devutils.diskstore.browser.SessionsProviderModel.load(SessionsProviderModel.java:31)
    ! at org.apache.wicket.model.LoadableDetachableModel.getObject(LoadableDetachableModel.java:135)
    ! at org.apache.wicket.markup.html.form.AbstractChoice.getChoices(AbstractChoice.java:230)
    ! at org.apache.wicket.markup.html.form.AbstractChoice.onComponentTagBody(AbstractChoice.java:376)
    ! at org.apache.wicket.markup.html.panel.DefaultMarkupSourcingStrategy.onComponentTagBody(DefaultMarkupSourcingStrategy.java:70)
    ! at org.apache.wicket.Component.internalRenderComponent(Component.java:2613)
    

  • 説明2

    mountPage("wicket/internal/debug/utils", DevUtilsPage.class);
    
    DevUtilsPage の Mount で、devutils の Debug 用のページには一通り、
    アクセスできるようになります。
    個別にもマウントできましたが、
    DevUtilsPage から DiskStoreBrowserPage 以外の全てのページへのリンクが貼られていたので、
    このページのみマウントしました。

  • 説明3

    getComponentPostOnBeforeRenderListeners().add(new StatelessChecker());
    
    StatelessChecker を Listener クラスとして追加、 そして、Stateless かを検証したいページ側に、以下のアノテーションを付与します。
    @StatelessComponent
    public class FestivalsPage extends BasePage {
    .....
    }
    
    ちなみに、@StatelessComponent を付与したページが、Stateless でないと例外が発生します。
    男らしく、厳しい実装になっています。
    Last cause: '[Page class = xyz.monotalk.FestivalsPage, id = 0, render count = 1]' claims to be stateless but isn't. Offending component: [Link [Component id = heldYearLink]]
    


画面イメージ

Wicket Inspector

  • TOP画面
    http://localhost:8080/wicket/internal/debug/utilsにアクセスすると、
    以下のページが表示されます。
    右上に小さく、InspectorSession リンクがあり、各ページに移動できます。
    utils page

  • Inspector
    Inspector リンクをクリックで以下の画面が表示されます。
    この画面で、Session上に存在するPageオブジェクトなどを、Tree 形式で閲覧できます。
    初期状態では、記録する設定になっていないので、Session に移動して、記録を開始します。
    Inspector

  • Session
    Session リンクをクリックで、以下の画面が表示されます。
    Enable request recording リンクをクリックすると、Session の記録が開始されます。
    All Session

  • リクエスト記録後の、View リクエストセッションが記録され、SessionId ごとに表示されます。
    SesssionId ごとのリンクをクリックします。
    Request Records

  • Session ごとの View Session ID ごとのViewです。発生したリクエストごとの消費Sessionのサイズ
    Time Token (たぶんレスポンスにかかった時間)が表示されます。
    Session

  • Inspector に戻る 記録している状態で、Inspector に戻ると、Session 上のオブジェクト Tree が表示されます。
    Pageに Add しているコンポーネントが、どれくらいのデータサイズかが確認可能です。
    Session Tree

  • 想像する実際の開発での使い方
    Session にサイズが大きすぎるコンポーネントを設定していないか?
    実際に大きすぎる場合は、何のサイズが大きいのか?
    等を確認する用途に使えそうに思いました。
    開発環境でテスト中に記録を ON にしておき、たまに画面を確認して、
    ListView などで、サイズが大きすぎるコンポーネントがないかをチェックするイメージかと。

Active sessions

作成した画面にいくつかアクセスした後に、
http://localhost:8080/wicket/internal/debug/diskDataStore にアクセスすると、
以下のページが表示されます。
DiskDataStoreDiskDataStore 上に存在する、Java オブジェクトと、そのサイズがどれくらいかと確認することができます。
Wicket はデフォルトだと、File システムが DataStore となるので、Datastore ディレクトリ の配下にある、
ディレクトリのリストが表示されるようです。
wicketstuff に DataStore 向けの拡張がありますが、
そちらには、対応はしてません。
独自に実装すれば、同じようなことはできそうに思います。

StatelessChecker

これは、特にアノテーションの話なので、特に画面などがあるわけじゃなさそうです。
ただ、Stateless でないと、例外にするという厳しい実装なので、 Warning くらいで、止められるようにコントロールできとくのがよいかと思い、少し実装を修正してみましたので、
Gistに置いておきます。

以上です。

コメント