Glueの実行時間が指定した値を超えた場合に通知を受け取る方法

2024.03.28

データアナリティクス事業本部のueharaです。

今回は、Glueの実行時間が指定した値を超えた場合に通知を受け取る方法をご紹介してみたいと思います。

はじめに

監視業務の一環として、Glueの実行時間が想定よりも長い場合に通知を受け取りたいことがあります。

GlueのCloudWatchメトリクスとして、経過時間を取得するための glue.driver.aggregate.elapsedTime がありますが(参考)、こちらは Spark にしか対応しておらず、取得可能なメトリクスが絞られる Python Shell では利用することができません。

今回は Python Shell でも設定可能な「Delay notification threshold」プロパティを用いてGlueの実行時間が指定した値を超えた場合に通知を受け取りたいと思います。

環境設定

概要図

今回設定する環境は、ざっくり以下の図の通りです。

Glueの通知をEventBridgeで捕捉し、それをSNSに渡したいと思います。

以下のように間にLambdaを挟んでメッセージ内容を加工したり、通知先をSlackにすることも可能ですが、今回はあくまで検証のためシンプルにGlueからの通知内容をそのままメールで受け取りたいと思います。

Glueの作成

CloudFormationでGlueを作成します。テンプレートのymlファイルは以下の通りです。(リソース名やスクリプトの保存場所は適宜書き換えて下さい)

glue.yml

AWSTemplateFormatVersion: "2010-09-09"

Resources:
  # Glue Job
  MyTestGlueJob:
    Type: AWS::Glue::Job
    Properties:
      Role:
        Fn::GetAtt: [GlueJobRole, Arn]
      GlueVersion: '3.0'
      Name: <YOUR GLUE JOB NAME>
      DefaultArguments:
        "library-set": "analytics"
      Command:
        Name: pythonshell
        ScriptLocation: "s3://<YOUR BUCKET NAME>/test_script.py"
        PythonVersion: "3.9"
      ExecutionProperty:
        MaxConcurrentRuns: 3
      MaxCapacity: 0.0625
      MaxRetries: 0
      NotificationProperty:
        NotifyDelayAfter: 1 # Notify after 1 minute
  # Glue Job Role
  GlueJobRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: <YOUR GLUE JOB IAM ROLE NAME>
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: glue.amazonaws.com
            Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole
        - arn:aws:iam::aws:policy/AmazonS3FullAccess

ポイントになるのは NotificationPropertyNotifyDelayAfter 部分です。

これが「Delay notification threshold」の設定値の部分で、指定した時間(分)を超えてGlueが実行される場合にCloudWatch経由で遅延を通知します。

今回は1分で設定しています。

Glueで実行するスクリプト test_script.py は以下のように単純に5分間sleepするだけの内容を記載しました。

test_script.py

import sys
import time


def main(argv):
    print("start")
    # sleep 5 minutes
    time.sleep(300)
    print("end")
    
main(sys.argv)

EventBridgeの作成

次に、CloudFormationでEventBridgeを作成します。テンプレートのymlファイルは以下の通りです。(通知先のSNSのARNは別途ご自身で用意したものをご用意下さい。)

eventbridge.yml

AWSTemplateFormatVersion: "2010-09-09"

Resources:
  GlueJobEventRule:
    Type: AWS::Events::Rule
    Properties:
      Name: <YOUR EVENT RULE NAME>
      Description: EventBridge rule to send notification of delay for Glue job 
      EventPattern:
        source:
          - aws.glue
        detail-type:
          - Glue Job Run Status
        detail:
          state:
            - RUNNING
      State: ENABLED
      Targets:
        - Arn: "<YOUR SNS ARN>"
          Id: TargetSns

「Delay notification threshold」に設定された時間(分)を超過するとGlueよりGlue Job Run Statusが通知されるので、それを捕捉するようにしています。

なお、通知を特定のジョブのみに絞りたい場合は以下のように記載することも可能です。

eventbridge.yml

AWSTemplateFormatVersion: "2010-09-09"

Resources:
  GlueJobEventRule:
    Type: AWS::Events::Rule
    Properties:
      Name: <YOUR EVENT RULE NAME>
      Description: EventBridge rule to send notification of delay for Glue job 
      EventPattern:
        source:
          - aws.glue
        detail-type:
          - Glue Job Run Status
        detail:
          state:
            - RUNNING
          jobName:
            - jobA
            - jobB
            - jobC
      State: ENABLED
      Targets:
        - Arn: "<YOUR SNS ARN>"
          Id: TargetSns

実行してみた

先に記載したCloudFormationテンプレートで作成したGlue Job(私の場合はuehara-glueJobで作成)を実行します。

Glueの実行から1分が経過すると、以下の通りSNS経由でメールで通知されました。(※1分にGlueの起動時間は含みません)

なお、上記はあくまで指定時間を超過した場合通知するのみであり、処理自体が正常に完了すればRun statusはSucceededとなります。

最後に

今回は、Glueの実行時間が指定した値を超えた場合に通知を受け取る方法をご紹介してみました。

参考になりましたら幸いです。

参考文献