Treasure Data - Support Engineering Team blog

トレジャーデータのサポートエンジニアリングチームのブログです。

Custom Script開発手順およびデバッグ

こんにちは。Treasure Data 大村です。今回はCustom Scriptの基本的な開発手順およびデバッグについてご紹介していきたいと思います。 Custom Script開発環境構築については前回の記事(Custom Script開発準備)を参照下さい。

プログラム作成

pythonプログラムを実行するときには python xxxx.py というように実行し、ファイルの先頭から順に実行されていきます。 しかし、Custom ScriptではWorkflowファイルから関数を指定し、実行する形になりますのでプログラム実行のスタートポイントが 異なることを意識する必要があります。

そのため、以下のようにプログラムを記述しておくと便利になります。

1: os.system(f"{sys.executable} -m pip install --upgrade pip")
2: os.system(f"{sys.executable} -m pip install pytd")
    :
3: def func1(arg1, arg2):
4:    :
5:    :
6: if __name__=='__main__':
7:    func1('foo', 100)

上記の例ではworkflowから呼び出す関数func1の定義とそれを呼び出す部分である6,7行目を記述しています。 これを記述することで、python xxxx.pyとした場合にfunc1を呼び出してくれます。

つまり、ローカル実行時は1,2,6,7行目->3行目(func1)の実行となり、workflowによる実行の場合は6,7行目の実行がなくなり、3行目の関数部分からの実行となります(もちろん1,2行目は実行されますが)。 開発時にメインとなる部分は3〜5行目の関数部分となり、6行目以降はテストドライバとなります。

上記のようにCustom Scriptの実行プロセスを意識しておきますと、自分のテストがどの部分の確認になっているかと把握しやすくなりますのでエラーが生じた際の切り分けが楽になりますので把握しておくとよいかと思います。

単体ローカル実行確認1(without docker)

プログラムを作成して、自身のローカル環境でpython xxxx.pyとしてまずは実行確認することになるかと思います。 このローカル実行による動作確認とTD環境でのCustom Script上での実行ではどの部分が一致しており、どの部分が一致していないのかをしっかりと認識しておくことが重要となります。 pythonプログラム単体で実行した場合に確認できる部分は関数本体のみになります。(もちろんmain部分で呼び出した関数が他の関数を呼び出している場合はそちらも動作確認できます。)

実際の本番環境との違いはOS、ネットワークに依存している部分やworkflowからの呼び出し部分が異なります。 また、pythonの実行環境も異なります。本番環境ではpythonの実行環境をpyオペレータを呼び出すたびに新規構築しますので環境は1度の実行で失われます。そのため、上記のサンプルコードの1,2行目のモジュールインストールは毎回実行されます。

しかし、ローカルでの実行の場合は最初の1回目は動作することになりますが、一旦モジュールをアップデートすると2回目以降はローカルの環境は本番と異なり、リフレッシュされないことに注意が必要になります。

まとめますと以下のようになります。

  • 動作確認できる部分
    • 関数本体
  • 動作確認できない部分
    • pythonモジュールのインストール/アップデートに関する部分(最初の1回目は動作確認できます)
    • OS、ネットワークに依存している部分
    • workflowからの呼び出し部分

pythonプログラム単体でのローカル実行は非常に簡単にプログラムの動作確認ができるのですが、実際のCustom Script実行環境と異なる部分が大きいという点は注意する必要があります。

ローカル実行確認2(with docker and digdag)

自身のローカル環境にDigdagおよびdockerを入れることで、本番環境とほぼ同一の動作確認をすることが可能になります。 もちろん、dockerのイメージにTreasure DataのCustom Scriptで使用しているイメージを利用することが前提となります。

この実行環境の本番環境との違いはネットワーク環境のみとなります。(インターネットのアクセスにproxyサーバが必要であるとか)

そのため、以下のポイントで動作確認が可能となります。

  • 動作確認できる部分
    • 関数本体
    • pythonモジュールのインストール/アップデートに関する部分(最初の1回目は動作確認できます)
    • OSに依存している部分(pythonコード内)
    • workflowからの呼び出し部分
  • 動作確認できない部分
    • ネットワークに依存している部分

ここまで確認しましたら、ほぼ本番環境と同じになりますので仮に本番環境で何らかのエラーが生じても、ネットワークの問題である可能性が 高く、そちらを重点的に確認すればよいということになります。

ただし、pythonプログラム単体の実行確認と比べるとターンアラウンドが少々かかるのは事実ですので、プログラム単体の動作確認の後のWorkflowとの結合動作テストとして実施するのがよいかと思います。

最後にこちらを参考にTD側にアップロードして、本番環境での実行確認をすることになります。 TD側へのアップロードおよび実行に関しましては以下のドキュメントを参照ください。 https://tddocs.atlassian.net/wiki/spaces/PD/pages/1082059/Python+Custom+Scripting+Example#Reading-and-Writing-Data-from-Treasure-Data

まとめ

上記の手順を踏んで開発を行うことで、いざ問題が生じた際にどこが問題なのかの切り分けが非常に楽になります。 特にローカル環境でしたら、みなさん側で自由にログを取ることができますので問題解決に問い合せのターンアラウンドが必要なくなりますのでローカルで動作確認をすることをおすすめします。