Alexaスキルを作る時は、エラートラッキングツール入れておこうという話

スキル作ってますか? 無事レビュー通過して公開できました? 突然「スキル動かないんだけど」って連絡きて慌てたことありませんか? ということで、エラートラッキングちゃんとやろうぜという話です。 なぜエラートラッキング VU […]

広告ここから
広告ここまで

目次

    スキル作ってますか?

    無事レビュー通過して公開できました?

    突然「スキル動かないんだけど」って連絡きて慌てたことありませんか?

    ということで、エラートラッキングちゃんとやろうぜという話です。

    なぜエラートラッキング

    VUIアプリは目に見えない分エラーに気づきにくいという点があります。

    ErrorHandlerを適切に実装している場合、「壊れている」というよりは「俺の滑舌悪いの?」とか「こいつポンコツだなぁ」という認識をされて終わるというケースもあります。

    なので利用しているAPIの仕様変更やトラブル、はたまたAWSのIAMロール触ってしまって403のような事故が起きていないか監視してやる必要があります。

    どうやってトラッキングするか?

    よく用いられる方法としては、以下の2種類が考えられます。

    • AWSのサービスでトラッキング・通知する
    • 外部のSaaSでトラッキング・通知する

    AWSのサービスでトラッキング・通知する

    AWSの中で完結させる方法です。コストを集約できることや、従量課金なので制限がかからないこと、様々なサービスと連携させて自動復旧の仕組みなども作れないこともないなどのメリットがあります。

    一方デメリットとしては、ほぼDIYになるということでしょうか。Serverless Application RepositoryやServerless系のコミュニティなどで使えそうなスタックがOSSになっていないか調べる必要があるかもしれません。

    CloudWatchのAlertを仕掛ける

    最も手早く作れるのはCloudWatchのアラートでしょう。

    Lambdaが正常に終了しなかった場合などにアラームを出し、SNS経由でメール通知・Lambda経由でSlack通知などの実装ができます。

    CloudWatch LogsからElasticsearchにログを流してKibanaで分析するとか、Lambdaをバージョン管理するようにして、エラーが続くようなら1世代前にロールバックするとかそういう運用を組み合わせるといい感じに自動化できるかもしれません。

    こういう知見はServerless FrameworkやSAMなどのServerless系のコミュニティに集積されていると思いますので、Serverless Confの動向を見ているといいかなと思います。

    外部サービスを利用する

    「そこまで時間かけたくないし、そういうスタックのメンテもしたくない」という方はおとなしくSaaS使いましょう。

    SentryRollbarなど、無料からはじめることができるサービスは複数あります。

    どちらもnpmでライブラリを追加して、APIキーなどを設定すればあとはエラーが起きた時にダッシュボードから確認できます。

    Sentryを使っている例

    Sentryでやっておきたい実装

    Sentryはカスタムでイベントを設定したり、トラッキングIDのようなものをつけることができます。Rollbarも可能だと思いますが、諸事情(仕事で使ってるから混ぜたくない)のため使っていません誰かそっち側の記事書いてください。

    ということで、こういうErrorHandler系をまとめたファイルを作っておくと便利です。

    import { ErrorHandler, getLocale , RequestInterceptor} from 'ask-sdk-core'
    import * as Sentry from '@sentry/node'
    Sentry.init({ dsn: process.env.SENTRY_DNS as string })
    
    export const ErrorHandler: ErrorHandler = {
      canHandle() {
        return true
      },
      handle(handlerInput, error) {
        // ErrorHandlerがよばれた時にイベントを記録する
        Sentry.captureEvent({
          message: error.message,
          extra: {
            request: handlerInput.requestEnvelope,
            error: error,
            stack: error.stack
          }
        })
        console.log(`~~~~ Error handled: ${error.message}`);
        return handlerInput.responseBuilder
            .speak('Well. I find some trouble. What do you want to do?')
            .reprompt('What do you want to do?')
            .getResponse();
      }
    }
    
    export const SetErrorTrackerInterceptor: RequestInterceptor = {
      process(input) {
        Sentry.configureScope(scope => {
          // request_idとuser_idで追跡できるようにする
          scope.setTag("request_id", input.requestEnvelope.request.requestId);
          scope.setUser({
            id: input.requestEnvelope.context.System.user.userId
          })
        })
      }
    }

    あとはそれぞれRequestHandlerとRequestIntereptorに挿してやればOKです。

    ErrorHandlerがよばれた場合、Lambdaの処理としては正常系として終了します。というかそうじゃないとAlexaのデフォルトエラーメッセージが発話されて会話が終わってしまいます。

    ただ、正常系で終了するとエラーとしてトラッキングされませんので、カスタムのイベントを作っておくってやりましょう。

    設定するなら申請前から

    そしてエラートラッキングツールを仕込んでおくメリットの1つが審査で指摘された内容と関連のあるエラーを見つけやすいという点です。

    複雑な会話を作ると時々handleされていないケースに突っ込んでしまうことがあります。

    そういうケースでもrequestの値をログりつつトラッキングツールでモニタリングしておくことで、「あ、こういう時に事故ったのね」ということにすぐ気づいて修正することができます。

    はじめよう、エラートラッキング for Alexa Skill

    やりはじめるまで「??なんのことやら」という気持ちになりますが、実際仕込んでおくとかなり便利です。

    だいたい無料枠でも一通りのトラッキングができますし、1ヶ月程度は保持してくれます。上限を超えると記録してくれなくなるので月末「頼むから事故るなよー」と祈ることになるかもしれませんが、5000件もエラーを記録する位使われるスキルを公開するならISPで費用を捻出できるようにマネタイズしましょう。

    今の所公開してるスキルにはほぼ必ず入れてるので、そのうちSentry向けハンドラーとか作るかもしれませんが、その時はぜひ使ってやってください。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark