1.21 jigowatts

Great Scott!

ASP.NET Health Monitoring機能を実装してみた

概要

前回何とか動かすことに成功したのですが、よくわからなかったので実際に自分の環境で実装してみることにしました。
Health Monitoring機能によってWebアプリケーションの状態を監視し、エラーが発生したらデータベースに登録する仕様です。

環境

Visual Studio 2015
ASP.NET Web Forms
.NET Framework 4.6
SQL Server 2012 Express LocalDB

実装

Webイベントアプリケーションサービスのインストール

Visual Studio Toolsにある開発者コマンドプロンプトを立ち上げ、以下のコマンドを実行します。

C:\Program Files (x86)\Microsoft Visual Studio 14.0>aspnet_regsql.exe -E -S (localdb)\v11.0 -A w -d LocalDB

コマンドのオプションには、現在のログオンユーザのWindows認証でLocalDBにWebイベントのアプリケーションサービスをインストールしてくださいって指定します。
f:id:sh_yoshida:20160308220254p:plain

LocaDBデータベースに以下のオブジェクトが作られました。
インストールといってもDBにTable、View、Procedureが作成されるだけなのかな。
f:id:sh_yoshida:20160308220303p:plain

Webアプリケーションの設定

ASP.NET Web Formsのアプリケーションを作成し、Web.configを設定します。
■Web.config

<configuration>
  <connectionStrings>
    <add name="ConnectionString" connectionString="server=(localdb)\v11.0;database=LocalDB;Integrated Security=True"/>
  </connectionStrings>
  <system.web>
    <healthMonitoring enabled="true">
      <providers>
        <add connectionStringName="ConnectionString" maxEventDetailsLength="1073741823" buffer="false" name="mySqlWebEventProvider" type="System.Web.Management.SqlWebEventProvider" />
      </providers>
      <rules>
        <add name="my All Errors Default" eventName="All Errors" provider="mySqlWebEventProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" custom="" />
      </rules>
    </healthMonitoring>

    //(省略)

  </system.web>
</configuration>

providersタグのconnectionStringNameプロパティには接続文字列を指定します。
rulesタグはeventNameプロパティにルートのWeb.configでデフォルト定義されているeventMappingsタグの"All Errors"を紐づけ、すべてのエラーを補足します。providerプロパティにはprovidersタグで定義したnameを指定します。

前回動かしたオリジナルコードと比べてみる

■オリジナルWeb.config

<healthMonitoring enabled = "true" >
    <eventMappings>
    <clear />
    <add name="All Errors" type="System.Web.Management.WebBaseErrorEvent" startEventCode="0" endEventCode="2147483647" />
    </eventMappings>
    <providers>
    <clear />
    <add connectionStringName = "ConnectionString" maxEventDetailsLength="1073741823" buffer="false" name="SqlWebEventProvider" type="System.Web.Management.SqlWebEventProvider" />
    </providers>
    <rules>
    <clear />
    <add name = "All Errors Default" eventName="All Errors" provider="SqlWebEventProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom="" />
    </rules>
</healthMonitoring>

そもそもオリジナルコードに記載されたclearタグがあちこちにあって、全部取ったら動かなくなってなんだこれってなったんですが、やろうとしてたことは理解できました。ルートのデフォルト定義を上書きしてたわけですが、eventMappingsタグはデフォルト定義を利用すればよさげなので今回は書いてません。

■Default.aspx.cs
適当な場所で明示的に例外をスローしてあげて、ビルドして実行。

protected void Page_Load(object sender, EventArgs e)
{
    throw new InvalidOperationException();
}

エラーどーんっ
f:id:sh_yoshida:20160308230727p:plain

テーブルに登録された!
f:id:sh_yoshida:20160308230737p:plain
f:id:sh_yoshida:20160308230744p:plain
ExceptionTypeカラムを見ると、InvalidOperationExceptionが拾えていることが確認できますね。