[アップデート] Amazon SNS でも AWS X-Ray のアクティブトレース統合機能が追加されていました

2023.03.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

いわさです。

最近サーバーレスアプリケーションの AWS X-Ray トレースを有効化して観察するのが気に入っているのですが、先月のアップデートで Amazon SNS にもアクティブトレース機能が追加されていたことを知りました。

DevelopersIO でまだ機能の紹介がされておらず、今回トレース結果などを確認してみましたので紹介します。
ファンアウトなどさせた時に統合先コンポーネントの情報も確認出来て良さげでした。

今回の構成

今回は次のようなサーバーレスアプリケーションを用意しました。
API Gateway のリクエストを AWS サービス統合でそのまま SNS にマッピングさせています。

SNS からは複数の SQS へファンアウトさせて、そこからそれぞれ Lambda が実行される形です。まぁよくあるファンアウト構成に HTTP エンドポイントを生やした感じです。

上記構成を SAM テンプレートで作成してデプロイ後に HTTP エンドポイントへアクセスしました。
API Gateway と Lambda のアクティブトレースは有効化されています。

SAM テンプレート
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: '---'
Resources:
  Api:
    Type: AWS::Serverless::Api
    Properties:
      Name: !Sub
        - ${ResourceName} From Stack ${AWS::StackName}
        - ResourceName: Api
      StageName: Prod
      DefinitionBody:
        openapi: '3.0'
        info: {}
        paths:
          /:
            get:
              consumes:
              - "application/json"
              produces:
              - "application/json"
              responses:
                "200":
                  description: "200 response"
                  schema:
                    $ref: "#/definitions/Empty"
              x-amazon-apigateway-integration:
                responses:
                  default:
                    statusCode: "200"
                    responseTemplates:
                      application/json: "{\n  \"hoge\":\"iwasa\"\n}"
                requestTemplates:
                  application/json: "{\"statusCode\": 200}"
                passthroughBehavior: "when_no_match"
                type: "mock"
          /sns:
            post:
              produces:
                - application/json
              responses:
                '200':
                  description: 200 response
                  schema:
                    $ref: '#/definitions/Empty'
              parameters:
                - name: Message
                  in: query
                  required: true
                  type: string
                - name: topicArn
                  in: query
                  required: true
                  type: string
              x-amazon-apigateway-integration:
                credentials: !GetAtt ApiTopicSendMessageRole.Arn
                httpMethod: POST
                uri: arn:aws:apigateway:ap-northeast-1:sns:action/Publish
                responses:
                  default:
                    statusCode: '200'
                requestParameters:
                  integration.request.querystring.TopicArn: method.request.querystring.topicArn
                  integration.request.querystring.Message: method.request.querystring.Message
                passthroughBehavior: when_no_match
                type: aws
      EndpointConfiguration: REGIONAL
      TracingEnabled: true
  Topic:
    Type: AWS::SNS::Topic
    Connectors:
      sqsQueues:
        Properties:
          Destination:
            - Id: QueueC1
            - Id: QueueC2
          Permissions:
            - Write
    Properties:
      Subscription:
        - Endpoint: !GetAtt QueueC1.Arn
          Protocol: sqs
        - Endpoint: !GetAtt QueueC2.Arn
          Protocol: sqs
  ApiTopicSendMessageRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - apigateway.amazonaws.com
        Version: '2012-10-17'
      Path: /
      Policies:
        - PolicyDocument:
            Statement:
              - Action: sns:Publish
                Effect: Allow
                Resource: !Ref Topic
            Version: '2012-10-17'
          PolicyName: ApiTopicSendMessagePolicy
  QueueC1:
    Type: AWS::SQS::Queue
    Properties:
      MessageRetentionPeriod: 345600
  QueueC2:
    Type: AWS::SQS::Queue
    Properties:
      MessageRetentionPeriod: 345600
  Function1:
    Type: AWS::Serverless::Function
    Properties:
      Description: !Sub
        - Stack ${AWS::StackName} Function ${ResourceName}
        - ResourceName: Function1
      CodeUri: src/Function1
      Handler: handler.handler
      Runtime: python3.9
      MemorySize: 3008
      Timeout: 30
      Tracing: Active
      Events:
        QueueC1:
          Type: SQS
          Properties:
            Queue: !GetAtt QueueC1.Arn
            BatchSize: 1
  Function2:
    Type: AWS::Serverless::Function
    Properties:
      Description: !Sub
        - Stack ${AWS::StackName} Function ${ResourceName}
        - ResourceName: Function2
      CodeUri: src/Function2
      Handler: handler.handler
      Runtime: python3.9
      MemorySize: 3008
      Timeout: 30
      Tracing: Active
      Events:
        QueueC2:
          Type: SQS
          Properties:
            Queue: !GetAtt QueueC2.Arn
            BatchSize: 1

アクティブトレース無効時

Amazon SNS のアクティブトレースは、トピックの統合タブから有効化出来ます。
デフォルトは無効で、既存 SNS トピックについても無効状態になっています。

まず、アクティブトレース無効時のトレースマップは次のようになります。

SNS にトピック名などが表示されておらず、ファンアウト先に SQS が見当たりません。
SNS アイコンを選択すると次のように API Gateway から何らかの SNS に対してリクエストが送信されていることまではわかりますが、その先はわかりません。

タイムライン上も次のように、何らかの SNS にメッセージが送信されたところまではわかるという感じです。

アクティブトレース有効時

では、トピックのアクティブトレース機能を有効化して、再度リクエストを送信してみましょう。

今度はトレースマップ上に SNS の詳細情報と、各 SQS の情報まで表示されるようになりました。

ちなみに、SQS のトレースリンク機能については re:Invent 2022 直前にアップデートがありました。

SNS アイコンを選択すると、トピック名が取得されています。
また先程と異なり、各 SQS キューのレスポンスステータスレートも表示されています。

タイムライン上もトレース出来る範囲が拡張されていますね。

CloudFormation で有効化する

CloudFormation あるいは SAM テンプレートで有効化する場合はAWS::SNS::TopicTracingConfigプロパティをActiveを設定することで有効化されます。
デフォルトはPassThroughとなり、API Gateway から受け取ったトレースヘッダーを転送するだけです。

:
  Topic:
    Type: AWS::SNS::Topic
    Connectors:
      sqsQueues:
        Properties:
          Destination:
            - Id: QueueC1
            - Id: QueueC2
          Permissions:
            - Write
    Properties:
      Subscription:
        - Endpoint: !GetAtt QueueC1.Arn
          Protocol: sqs
        - Endpoint: !GetAtt QueueC2.Arn
          Protocol: sqs
      TracingConfig: Active
:

このプロパティは SAM のグローバルパラメータが使えないので、トピックごとに個別で有効化する必要があります。

FIFO では使えない

アクティブトレースはスタンダードトピックでのみ利用可能で、FIFO トピックでは利用出来ません。

さいごに

本日は Amazon SNS でも AWS X-Ray のアクティブトレース統合機能が追加されていることに気がついたので確認してみました。

トレース範囲が拡張されてとても良いです。使っていきたい。
一方で FIFO トピックのほうが使いたいシーン多いかもとちょっと思いました。さらなるアップデートに期待したいところです。