読者です 読者をやめる 読者になる 読者になる

しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure WebJobs SDK Extensions を使って実行時のエラーハンドリングを行う

Azure WebJobs

Azure WebJobs SDK を使っていると、メソッドで発生した例外を処理する方法が標準で用意されていないので、内部で例外のキャッチが必要ですが、WebJobs SDK Extensions には良い感じにサマライズするトリガーが用意されているので、これを使うとかなり楽できます。

ErrorTrigger と TraceFilter を使って発生した例外を受け取るメソッドを用意します。

WebJobs SDK Extensions のインストールは NuGet から行います。当然ながら WebJobs SDK は必要です。

Install-Package Microsoft.Azure.WebJobs.Extensions

SDK の準備が出来れば、ErrorTrigger を付けたメソッドを用意します。

このトリガーは WebJobs で例外が発生しないと実行されないので、同時に TimerTrigger を使って 1 分毎に例外を投げるメソッドも用意しました。

ErrorTrigger のコンストラクタではトリガーが実行される条件を細かく設定できます。下の例では 30 分のスライディングウィンドウで 5 件以上のエラーが発生した場合に、メソッドが実行されるようになっています。

public class Functions
{
    public static void ProcessTimerMessage([TimerTrigger("0 * * * * *")] TimerInfo timerInfo, TextWriter log)
    {
        throw new InvalidOperationException();
    }

    public static void ErrorMonitor([ErrorTrigger("0:30:00", 5, Throttle = "1:00:00")] TraceFilter filter, TextWriter log)
    {
        log.WriteLine(filter.Message);
        log.WriteLine("=============================");
        log.WriteLine(filter.GetDetailedMessage(5));
    }
}

発生したエラーの情報は TraceFilter に含まれているので、例外の具体的な情報はここから取得します。

ただし、スロットリング時間を設定しているので、この例では 5 件以上のエラーが発生しても 1 時間に 1 回だけ呼び出されるようになります。これで大量のエラー通知が送られてくることを避けることが出来ます。

トリガーとなるメソッドの実装は簡単ですが、エントリポイントで UseCore 拡張メソッドを呼び出しておかないと、ランタイムから認識されないので注意が必要です。

class Program
{
    static void Main()
    {
        var config = new JobHostConfiguration();
        
        if (config.IsDevelopment)
        {
            config.UseDevelopmentSettings();
        }

        config.UseCore();
        config.UseTimers();

        var host = new JobHost(config);

        host.RunAndBlock();
    }
}

TimerTrigger を使うための設定が混ざっていますが、UseCore が必要だと認識してもらえれば問題ないです。

実際に Azure へデプロイした後、数分待つとエラー件数が 5 件を超えて、用意したメソッドが実行されるのが確認できると思います。実行ログにも条件が表示されています。

f:id:shiba-yan:20160802023553p:plain

後はメソッド内でメールを送信するなり、Slack などへ投げる処理を追加するだけで、WebJobs の実行エラーをいい感じにサマライズして通知することが出来ます。

Trigger WebJobs の場合は Kudu の WebHook だったので Azure Functions などが必要でしたが、WebJobs SDK を使っている場合はシンプルに実装できるのが良いですね。