2011年5月4日水曜日

ぷっすぷすにしてやんよ、Glimpseで。

Glimpse - A client side look at whats going on in your server

なんと素敵なツールでしょうね!

glimpse1

↑ChromeでGlimpseをオンにしたうえに、デベロッパーツールもオンにした状態。かぶせまくり。

これ何?っていうのは上記Glimpseサイトのビデオか、MIX11でのHanselmanさんのセッションビデオ見れば一発でわかります。と言ってしまうとブログに書く必要が無くなってしまうので、少し説明すると、Trace.axdやelmah.axd、RouteDebuggerを全部ひっくるめて組み合わせてさらにサーバーサイドの情報をひと通り参照できるようにするツールデス。分かりにくいっすね。

とにかく、NuGetでInstall-Package Glimpseと入力してプロジェクトに入れて見ましょう。

その状態でデバッグを開始すると、おや?ナニも変化ないですね。なので、URLに/Glimpse/ConfigといれてGlimpse機能をOnにしまいしょう。Onにした後はURLをもとのページに自分で戻すことを忘れずに。

glimpse2

そうすると画面右下に変な目玉アイコン(Glimpseアイコンね)が表示されるのでそこをクリック!

glimpse3

そうすると出てきます。

glimpse4

すごいねー。ちなみにブラウザに表示されてるのはプラグインとかじゃなくて100%JavaScriptだけで作られたものです。

glimpse5 glimpse6

ソース表示すると</html>の後にデータがレンダリングされて、最後にglimpseClinet.jsがロードされてるのが確認できます。

あとは、見たまんまです。各タブにそれぞれ情報が表示されます。

  • Binding
    まだ開発中~。Binderの情報がでる予定(だと思います)
  • Config
    Web.Configの設定内容をセクション別に表示
    config
  • Environment
    サーバーの実行環境の情報
    Application Assemblies/System Assembliesが見れるのは嬉しいですね
    emvironment
  • Execution
    ActionInvokderの実行内容を表示(だと思う)
    Filterの実行も見れるよ!
    execution
  • Glimpse Warnings
    Glimpseの何か
  • MetaData
    どこぞのMetadata
  • Remote
    リクエスト履歴っぽい
  • Request
    HttpRequestBaseの中身からCookie,Form,QueryStringを表示
    request
  • Routes
    表示内容(アクション)に到達するルーティングの解決順とマッチしたルート
    route
  • Server
    ServerValiablesの内容
  • Session
    Sessionの内容
  • Trace
    System.Diagnostics.Traceに出力した内容
  • Views
    表示内容(View)の解決に至る過程
    view
  • XHRequest
    まだっぽい

全部スクリーンショットをとるのが面倒だったから動かして確認してみてね!

んじゃ、そもそもGlimpseの仕組みはどうなってるの?って気になるよね。NuGetからインストールすると使うのは楽チンだけどソースが確認できないから、改めてソースをダウンロードしましょう。

Glimpse/Glimpse - GitHub

真っ先に気になるのが、PreApplicationStartCode。当たり前のようにスタートアップコードが書かれてる。んで、その中身はMicrosoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModuleを使ったカスタムIHttpModuleの動的登録。その中で各種プラグイン(タブで表示する情報を取得したりするもの)をMEFで登録。

Moduleでハンドリングするタイミングは以下の4つ。

context.BeginRequest += BeginRequest;
context.EndRequest += EndRequest;
context.PostRequestHandlerExecute += PostRequestHandlerExecute;
context.PreSendRequestHeaders += PreSendRequestHeaders;

ここから結構気になってるExecutionで表示してるのがホントにActionInvokerに介入した結果なのかチェックしてみよう。

ExecutionプラグインのSetupInitでいろいろ仕込んでますね。ControllerFactoryとDependencyResolverをGlimpseのものに置き換えてます。GlimpseControllerFactory.CreateControllerでIControllerExtentions.TrySetActionInvokerを呼んでCastleのInterceptorを利用して、プロキシを生成しそれをActionInvokerにセットしてました。これでプロキシが必ず呼び出されるから、実行をインターセプトして実行情報を取得できるということですね。うほ。

DependencyResolverを利用した場合にも大丈夫なようにGlimpseDependencyResolverが用意されてて、こっちでも同じくProxyを生成するように抜かりなし。

他のプラグインもIGlimpsePlugin実装になってて、SetupInitしてGetDataを呼ぶことで各種データをHttpContext.Itemsに入れることで、最終的にGlimpseRespondersがJsonにシリアライズ。まるっとApplication編集に保存してGlimpseResponders.StandardResponseがResponse.Writeしてる。

Glimpseの仕組み

MEFを使ったプラグイン構造でContext.ItemsからApplication変数にデータを保持(configのsaveRequestCountはこの履歴保持数ということみたい)し、それをレスポンス(リクエスト毎にGuidを発行してコンテキストがきちんと判定できるよう保持)。各種情報はプラグインが自立して取得するけど、実行状態のインターセプトはCastleがProxyを生成して介入。

イロイロなプラグインを作っていけば、データの取得と表示はベースの機能でまかなえる素敵設計であるのと、.NET4、MVC3の機能もめいいっぱい利用したお洒落実装。これは萌える。萌え萌え。ぷっすぷすにされちまったぜ!