Glimpse - A client side look at whats going on in your server
なんと素敵なツールでしょうね!
↑ChromeでGlimpseをオンにしたうえに、デベロッパーツールもオンにした状態。かぶせまくり。
これ何?っていうのは上記Glimpseサイトのビデオか、MIX11でのHanselmanさんのセッションビデオ見れば一発でわかります。と言ってしまうとブログに書く必要が無くなってしまうので、少し説明すると、Trace.axdやelmah.axd、RouteDebuggerを全部ひっくるめて組み合わせてさらにサーバーサイドの情報をひと通り参照できるようにするツールデス。分かりにくいっすね。
とにかく、NuGetでInstall-Package Glimpseと入力してプロジェクトに入れて見ましょう。
その状態でデバッグを開始すると、おや?ナニも変化ないですね。なので、URLに/Glimpse/ConfigといれてGlimpse機能をOnにしまいしょう。Onにした後はURLをもとのページに自分で戻すことを忘れずに。
そうすると画面右下に変な目玉アイコン(Glimpseアイコンね)が表示されるのでそこをクリック!
そうすると出てきます。
すごいねー。ちなみにブラウザに表示されてるのはプラグインとかじゃなくて100%JavaScriptだけで作られたものです。
ソース表示すると</html>の後にデータがレンダリングされて、最後にglimpseClinet.jsがロードされてるのが確認できます。
あとは、見たまんまです。各タブにそれぞれ情報が表示されます。
- Binding
まだ開発中~。Binderの情報がでる予定(だと思います) - Config
Web.Configの設定内容をセクション別に表示
- Environment
サーバーの実行環境の情報
Application Assemblies/System Assembliesが見れるのは嬉しいですね
- Execution
ActionInvokderの実行内容を表示(だと思う)
Filterの実行も見れるよ!
- Glimpse Warnings
Glimpseの何か - MetaData
どこぞのMetadata - Remote
リクエスト履歴っぽい - Request
HttpRequestBaseの中身からCookie,Form,QueryStringを表示
- Routes
表示内容(アクション)に到達するルーティングの解決順とマッチしたルート
- Server
ServerValiablesの内容 - Session
Sessionの内容 - Trace
System.Diagnostics.Traceに出力した内容 - Views
表示内容(View)の解決に至る過程
- XHRequest
まだっぽい
全部スクリーンショットをとるのが面倒だったから動かして確認してみてね!
んじゃ、そもそもGlimpseの仕組みはどうなってるの?って気になるよね。NuGetからインストールすると使うのは楽チンだけどソースが確認できないから、改めてソースをダウンロードしましょう。
真っ先に気になるのが、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の機能もめいいっぱい利用したお洒落実装。これは萌える。萌え萌え。ぷっすぷすにされちまったぜ!