Amazon Web Services ブログ

Amazon CloudWatch Contributer Insights による時系列分析の簡素化

複数のロググループとログストリームを検査すると、問題の影響をリアルタイムで分析して診断することが困難になり、時間がかかります。どのような顧客が影響を受けるでしょうか? それはどの程度の影響でしょうか? 一部の顧客は他よりも影響を受けていますか、それとも外れ値ですか? おそらく、段階的なロールアウト戦略を使用して更新のデプロイを実行し、問題が発生したかどうか、またはさらに続行する前にターゲットの顧客に対してすべてが期待どおりに動作しているかどうかを知りたいと考えているのではないでしょうか。これらの質問に答えるのに役立つデータポイントはすべて、エンジニアがアドホックの測定結果を取得するためにクエリする大量のログに埋もれてしまうことでしょう。または、追跡できるようにカスタムダッシュボードを構築および維持します。

Amazon CloudWatch Contributor Insights は、現在一般公開されている新機能で、CloudWatch Logs の時系列データに対する上位 N 番のコントリビューターの分析を簡素化するのに役立ちます。これにより、システムとアプリケーションのパフォーマンスに影響を与えている人またはものをリアルタイムで大規模に、より迅速に理解することができます。これにより、運用上の問題の原因を特定し、誰または何が最も影響を受けるかを理解できるため、運用上の問題に対処する時間を節約できます。Amazon CloudWatch Contributor Insights は、外れ値、パフォーマンスのボトルネック、上位の顧客、使用率の高いリソースを一目で簡単に確認できるため、システムとビジネスの最適化を継続的に分析するのにも役立ちます。ログに加えて、Amazon CloudWatch Contributor Insights は、メトリクスやアラームなど、CloudWatch ポートフォリオの他の製品でも使用できます。

Amazon CloudWatch Contributor Insights は、JSON または Common Log Format (CLF) のいずれかで構造化ログを分析できます。ログデータは、Amazon Elastic Compute Cloud (EC2) インスタンス、AWS CloudTrailAmazon Route 53、Apache アクセスおよびエラーログ、Amazon Virtual Private Cloud (VPC) フローログ、AWS Lambda ログ、および Amazon API Gateway ログから取得できます。また、CloudWatch に直接公開された構造化ログを使用するか、CloudWatch エージェントを使用するかを選択できます。Amazon CloudWatch Contributor Insights は、これらのログイベントをリアルタイムで評価し、データセット内の上位のコントリビューターと一意のコントリビューターの数を示すレポートを表示します。コントリビューターは、CloudWatch Logs のログフィールドとして含まれるディメンションに基づく集計メトリクス (たとえば、Amazon Virtual Private Cloud フローログ中の Amazon の account-id や interface-id) やその他のカスタムのディメンションのセットです。独自のカスタム基準に基づいて、コントリビューターデータをソートおよびフィルタリングできます。Amazon CloudWatch Contributor Insights のレポートデータは、CloudWatch ダッシュボードに表示し、CloudWatch メトリクスとともにグラフ化し、CloudWatch アラームに追加できます。たとえば、顧客は 2 つの Amazon CloudWatch Contributor Insights レポートの値を単一のメトリクスにグラフ化して、障害の影響を受ける顧客の割合を説明し、この割合が事前に定義されたしきい値に違反したときに警告するようにアラームを設定できます。

Amazon CloudWatch Contributor Insights の開始方法
Amazon CloudWatch Contributor Insights を使用する際に必要な作業は、1 つ以上のルールを定義することだけです。ルールは、コンテキストデータを定義する単なるデータスニペットで、CloudWatch Logs から報告されたメトリクスを抽出します。特定のメトリクスの上位のコントリビューターを識別するルールを設定するために、ロググループ、上位のコントリビューターが評価されるディメンション、およびそれらの上位のコントリビューターを絞り込むフィルターという 3 つのデータ項目を提供します。これを行うには、Amazon CloudWatch コンソールのダッシュボードに移動し、左側のナビゲーションリンクから [Contributor Insights] を選択します。これにより Amazon CloudWatch Contributor Insights ホームに移動し、ルールの作成 [Create] をクリックして開始できます。

すぐに始めるために、ログを CloudWatch Logs に送信するさまざまなサービスのサンプルルールのライブラリから選択できます。上記を見ると、現在 Amazon API Gateway、Amazon Route 53 クエリログ、Amazon Virtual Private Cloud フローログ、およびコンテナサービスのログ向けの各種ルールのサンプルがあることが確認できます。または、この記事でこれからそうするようように、独自のルールを定義できます。

構造化されたログデータを JSON 形式で直接 CloudWatch Logs に公開しているデプロイ済みのアプリケーションがあるとします。このアプリケーションには 2 つの API バージョンがあり、1 つはしばらく使用されており、安定していると考えられているバージョンです。もう 1 つは、顧客への提供を開始したばかりのバージョンです。新しい API をターゲットにした新しいバージョンを受け取った人が障害を受け取っているかどうか、およびトリガーされている障害の数をできるだけ早く知りたいと思います。この記事の安定した API バージョンは 1 つのロググループにログデータを送信し、新しいバージョンは別のグループを使用しているため、複数のロググループをモニタリングする必要があります (バージョンに関係なく、誰かがエラーを経験しているかどうかも知りたいので)。

ルールを定義し、任意の API から発生する 500 エラーについてレポートし、ディメンションとしてアカウント ID、HTTP メソッド、およびリソースパスを使用する JSON を以下に示します。

{
  "Schema": {
    "Name": "CloudWatchLogRule",
    "Version": 1
  },
  "AggregateOn": "Count",
  "Contribution": {
    "Filters": [
      {
        "Match": "$.status",
        "EqualTo": 500
      }
    ],
    "Keys": [
      "$.accountId",
      "$.httpMethod",
      "$.resourcePath"
    ]
  },
  "LogFormat": "JSON",
  "LogGroupNames": [
    "MyApplicationLogsV*"
  ]
}

[Wizard] タブを使用してルールを設定するか、[Syntax] タブの [Rule body] フィールドに上記の JSON を貼り付けることができます。上記の JSON を使用していますが、この記事では [Wizard] タブを使用して表示し、以下の入力済みのフィールドを確認できます。ロググループを選択するとき、すでに存在する場合はドロップダウンから選択するか、または [Select by prefix match] オプションでワイルドカード構文を使用できます (たとえば、MyApplicationLogsV *)。

[Create] をクリックすると、新しいルールが保存され、データの処理と分析がすぐに開始されます (もちろん、そのような動作を無効にした状態で作成を選択した場合を除きます)。Amazon CloudWatch Contributor Insights は、ルールがアクティブになると作成された新しいログデータを処理し、履歴検査を実行しないことに注意してください。そのため、将来発生すると予想される運用シナリオのルールを作成する必要があります。

ルールが用意されたら、ログデータの生成を開始する必要があります。 開始するために、Windows PowerShell 用 AWS Tools を使用して記述されたスクリプトを使用して、デプロイされたアプリケーションが一連の顧客によって呼び出されるのをシミュレートします。それらの顧客のうち、限られた少数の顧客 (不運な顧客と呼ぶことにしましょう) は、HTTP POST リクエストでランダムに失敗する新しい API バージョンを受け取ります。古い API バージョンを使用している顧客は常に成功します。5000 回の反復を実行するスクリプトを以下に示します。CloudWatch Logs の操作に使用されているコマンドレットは、名前に CWL が含まれているものです (例: Write-CWLLogEvent)。

# Set up some random customer ids, and select a third of them to be our unfortunates
# who will experience random errors due to a bad api update being shipped!
$allCustomerIds = @( 1..15 | % { Get-Random })
$faultingIds = $allCustomerIds | Get-Random -Count 5

# Setup some log groups
$group1 = 'MyApplicationLogsV1'
$group2 = 'MyApplicationLogsV2'
$stream = "MyApplicationLogStream"

# When writing to a log stream we need to specify a sequencing token
$group1Sequence = $null
$group2Sequence = $null

$group1, $group2 | % {
    if (!(Get-CWLLogGroup -LogGroupName $_)) {
        New-CWLLogGroup -LogGroupName $_
        New-CWLLogStream -LogGroupName $_ -LogStreamName $stream
    } else {
        # When the log group and stream exist, we need to seed the sequence token to
        # the next expected value
        $logstream = Get-CWLLogStream -LogGroupName $_ -LogStreamName $stream
        $token = $logstream.UploadSequenceToken
        if ($_ -eq $group1) {
            $group1Sequence = $token
        } else {
            $group2Sequence = $token
        }
    }
}

# generate some log data with random failures for the subset of customers
1..5000 | % {

    Write-Host "Log event iteration $_" # just so we know where we are progress-wise

    $customerId = Get-Random $allCustomerIds

    # first select whether the user called the v1 or the v2 api
    $useV2Api = ((Get-Random) % 2 -eq 1)
    if ($useV2Api) {
        $resourcePath = '/api/v2/some/resource/path/'
        $targetLogGroup = $group2
        $nextToken = $group2Sequence
    } else {
        $resourcePath = '/api/v1/some/resource/path/'
        $targetLogGroup = $group1
        $nextToken = $group1Sequence
    }

    # now select whether they failed or not.GET requests for all customers on
    # all api paths succeed.POST requests to the v2 api fail for a subset of
    # customers.
    $status = 200
    $errorMessage = ''
    if ((Get-Random) % 2 -eq 0) {
        $httpMethod = "GET"
    } else {
        $httpMethod = "POST"
        if ($useV2Api -And $faultingIds.Contains($customerId)) {
            $status = 500
            $errorMessage = 'Uh-oh, something went wrong...'
        }
    }

    # Write an event and gather the sequence token for the next event
    $nextToken = Write-CWLLogEvent -LogGroupName $targetLogGroup -LogStreamName $stream -SequenceToken $nextToken -LogEvent @{
        TimeStamp = [DateTime]::UtcNow
        Message = (ConvertTo-Json -Compress -InputObject @{
            requestId = [Guid]::NewGuid().ToString("D")
            httpMethod = $httpMethod
            resourcePath = $resourcePath
            status = $status
            protocol = "HTTP/1.1"
            accountId = $customerId
            errorMessage = $errorMessage
        })
    }

    if ($targetLogGroup -eq $group1) {
        $group1Sequence = $nextToken
    } else {
        $group2Sequence = $nextToken
    }

    Start-Sleep -Seconds 0.25
}

スクリプトの実行を開始し、ルールを有効にすると、グラフに失敗が表示され始めます。以下は、スクリプトを実行して数分後のスナップショットです。シミュレートされた顧客のあるサブセットが新しい v2 API への HTTP POST リクエストで問題を抱えていることがはっきりと確認できます。

[Rules] パネルの [Actions] プルダウンから、このレポートから単一のメトリクスを作成し、障害の影響を受けた顧客の割合を説明してから、このメトリクスにアラームを設定し、このパーセンテージが事前に定義したしきい値に違反したときにアラートが出されるようにします。

ここで概説するサンプルシナリオでは、新しい API が起動した場合にアラームを使用して新しい API のロールアウトを停止し、他の顧客への影響の拡大を防ぎながら、増加した障害の背後にある原因の調査を実行します。メトリクスとアラームの設定方法の詳細については、ユーザーガイドをご覧ください。

Amazon CloudWatch Contributor Insights は、中国や GovCloud を含むすべての商用 AWS リージョンのユーザーにご利用いただけるようになりました。

— Steve