この記事は Splunk Advent Calendar 2019 の記事の一つです。
他の記事 もお楽しみくださいね。
今回は、自作の App を Splunkbase で公開したは良いけれど、
そろそろ (?!) Python 3 対応をしないとなぁ・・
Splunk も Python 3 移行するよ! と言ってたしなぁ・・
という締め切りに追われる Splunk App 開発者向けの内容です。
簡単に自己紹介しますと、
普段のお仕事では、Splunk の構築やトラブルシュートを主に担当しています。
好きな機能は Metrics type インデックスです。
記事の背景について、簡単に。
そもそも Python 3 移行って?
インタプリタ系プログラミング言語の Python は
v2 系と v3 系が長らく使われてきていますが、
開発コミュニティによる v2 系 (v2.7) のメンテナンスが
2020/1/1 をもって終了することが、
12 年前 (2008 年) からアナウンスされていました。
さあ、2019 年もいよいよ、あと残すところ僅か。
重い腰を上げるときが来ました。
ちなみに、メンテナンスが終了するだけで、
2020/1 以降、急に動かなくなるわけでは無いですよ。 念の為。
そもそも、Python 3 対応で書いておけば良いじゃない。
はい。おっしゃる通りです。
しかしながら、
- 利用しているライブラリがまだ v3 対応していない。
- 改修ポイントがよく分からない (不勉強なだけか・・)。
- 動いてるんだから良いじゃない。
などと言った、理由で先送りされてしまうケースも多いかと思います。
Splunk の Python 事情。
しかも、Splunk に関しては、ちょっと特殊な事情があります。
Splunk というソフトウェアには、
Python 実行環境が同梱されています。
ですので、OS 側に別途 Python をインストールしたりすることなく、
プラグイン (App, Add-on) で利用することができました。
この同梱 Python が、つい先日 (2019/10/22) まで、
Python 2.7 しか選択できない状況でした。
v3 系である Python 3.7 が同梱され始めたのは、Splunk v8.0.0 から。
さぁ、環境を言い訳にできなくなったのです (誤解を生むニュアンスだな)。
ちなみに v8.0.0 には、Python 2.7 と Python 3.7 の
両方の環境が同梱されており、
App, Add-on で利用する機能ごとに
どちらの環境で動かすかを選ぶことができます。
デフォルトでは、従来どおりの v2.7 系で動作します
(ただし、ウェブアプリ機能など一部の例外を除く)。
今後のロードマップとしては、
2020 年の中頃を目処にデフォルトの Python が v2.7 から v3.7 に変更 (v2.7 を選択することは可能)。
2020 年の後半のリリースでは、v2.7 の同梱が廃止され、v3.7 のみになるようです。
v3.7 に書き換えるだけ?
移行にあたっての注意点として、
v2/v3 の互換記法が強く推奨されます。
えー、v2 は EOL でメンテナンスされなくなるって言ってたじゃん、
というご意見はごもっともなのですが・・
Splunk に馴染みのある方には、聞き覚えがあるかと思いますが、
分散サーチ、という機能があります。
Splunk は、単一のインスタンスで all-in-one で利用することもできますし、
主要な機能ごとにインスタンスを分け、より検索効率や可用性を高めることも可能です。
主な役者としては、
- サーチ (検索) を受付け、結果の表示を行うサーチヘッド (SH)
- データの格納とサーチに基づくデータを返すインデクサ (IDX)
- 新しいデータを取り込みインデクサに転送するフォワーダ (FWD)
に分けられます。
この分散構成を採ったとき、
サーチヘッドで受け付けたサーチ命令を、
複数のインデクサ (peers とも呼ばれます) に、
分散サーチ処理を依頼します。
このとき、サーチヘッド上にある App も、
命令の一部としてインデクサに渡され、インデクサ上で実行されます。
カスタムサーチコマンド等で、
Python を利用した処理を書いてある場合、
サーチヘッドとインデクサの設定 (Python 環境の指定) も
同一なら良いのですが、
サーチヘッドは v3.7 対応済み、
インデクサは v2.7 で動作するという指定の場合、
v3 準拠、v2 非互換の記法があると
インデクサ上の分散処理が失敗してしまう、という
シナリオが待ち受けています。
そんな状況のため、Python v2/v3 両対応の記法が
推奨されています。
Python v2/v3 の違いって?
だんだん、本題から逸れていきそうなので
Python のバージョンに関連する違いの詳細は端折りますが、
詳しくは他の記事などをご参考ください。
- Python 2 から Python 3 への移植
- Python2からPython3.0での変更点
- Python 2.7.x と 3.x の決定的な違いを例とともに
- Python3にすんなり移行できないから 2-3 互換を考えよう
私の経験としては、
-
print
が文から関数に (print
の後に丸カッコが必要に) - 除算の演算子 (
/
,//
) の挙動が変更に。 - 四苦八苦して対応した文字コード対応が、却って誤動作。
- 通ぶって使っていた
reduce
等が、functools
へ移行。 -
ConfigParser
がconfigparser
に。
といったあたり、ハマった憶えがあります。
互換記法への書き換えにあたっては、
six と tox という 2 つをご紹介しておきます。
一言で言うと、six は、関数名などの違いを吸収するためのもの、
tox は、v2/v3 両方の単体テストを行うものです。
Python v2 と v3 の違いを
ライブラリで吸収しようという取組み
six は、
こちらは、Splunk App 開発向けのライブラリにも同梱されています。
また、Python 2 および Python 3 それぞれの
環境で単体テストを実行するための
tox
フレームワークも用意されています。
同じコードの単体テストを、
複数のインタプリタ環境 (Python v2 と v3 など) で実行することができます。
文法的に問題ないというチェックまでは、
ある程度、フレームワーク等で機械的に対応できます。
自作 Splunk App の書換え。
さて、話のマクラがだいぶ長くなりましたが、そろそろ本題に。
App の互換性チェックには、
Splunk Platform Upgrade Readiness App も用意されていますが、
Splunk Enterprise 環境が必要だったりするので、
まずは、お手軽に AppInspect の REST API からご紹介。
その後、Splunk Platform Upgrade Readiness App についても後述します。
互換性チェックその 1: AppInspect REST API
認証トークンの取得
$ curl -X GET \
-u {splunk.com のユーザ名} \
--url "https://api.splunk.com/2.0/rest/login/splunk"
パスワードを聞かれるので、
splunk.com のユーザアカウントのパスワードを入力します。
{
"data": {
"token": "{トークン文字列。以下、$TOKEN で参照}",
"user": {
"email": "{登録しているメールアドレス}",
"groups": [
"Beta Users"
],
"name": "{登録している名前}",
"username": "{splunk.com のユーザ名}"
}
},
"msg": "Successfully authenticated user and assigned a token",
"status": "success",
"status_code": 200
}
ここで応答の中にある、token
の文字列をこの後の手順で使って確認していきます。
(トークン文字列はだいぶ長いので、シェル変数などに入れておくと良いかもしれません)
以下では、環境変数 TOKEN
にここで取得したトークンが設定されているものとします。
($TOKEN
で参照します)
App 検査依頼の発行
$ curl -X POST
-H "Authorization: bearer $TOKEN"
-H "Cache-Control: no-cache"
-F "app_package=@\"line-alert-for-splunk_100.tgz\""
-F "included_tags=py3_migration"
--url "https://appinspect.splunk.com/v1/app/validate"
{
"request_id": "a32e91f8-7767-400f-a33f-xxxxxxxxxxxx",
"message": "Validation request submitted.",
"links": [
{
"rel": "status",
"href": "/v1/app/validate/status/a32e91f8-7767-400f-a33f-xxxxxxxxxxxx"
},
{
"rel": "report",
"href": "/v1/app/report/a32e91f8-7767-400f-a33f-xxxxxxxxxxxx"
},
{
"rel": "package",
"href": "/v1/app/package/a32e91f8-7767-400f-a33f-xxxxxxxxxxxx"
}
]
}
応答に含まれるリクエスト ID を結果の問合せに使います。
App 検査状況および結果の確認
検査リクエストの進行状況を確認するには、
status エンドポイントに問合せます。
$ curl -X GET
-H "Authorization: bearer $TOKEN"
-H "Cache-Control: no-cache"
--url https://appinspect.splunk.com/v1/app/validate/status/a32e91f8-7767-400f-a33f-xxxxxxxxxxxx
{
"request_id": "a32e91f8-7767-400f-a33f-xxxxxxxxxxxx",
"status": "SUCCESS",
"info": {
"error": 0,
"failure": 0,
"skipped": 0,
"manual_check": 0,
"not_applicable": 3,
"warning": 0,
"success": 10
},
"links": [
{
"rel": "self",
"href": "/v1/app/validate/status/a32e91f8-7767-400f-a33f-xxxxxxxxxxxx"
},
{
"rel": "report",
"href": "/v1/app/report/a32e91f8-7767-400f-a33f-xxxxxxxxxxxx"
}
]
}
status が SUCCESS になっていれば完了しています。
結果の取得には report エンドポイントを使います。
$ curl -X GET
-H "Authorization: bearer $TOKEN"
-H "Cache-Control: no-cache"
--url https://appinspect.splunk.com/v1/app/report/a32e91f8-7767-400f-a33f-xxxxxxxxxxxx
無指定では json が返ってきます。
Content-Type
を適宜指定すると、HTML でも結果を取得できます。
$ curl -X GET
-H "Authorization: bearer $TOKEN"
-H "Content-Type: text/html"
-H "Cache-Control: no-cache"
--url https://appinspect.splunk.com/v1/app/report/a32e91f8-7767-400f-a33f-xxxxxxxxxxxx
こちらのほうが見やすいですね。
Totals 欄の Failures と Error がゼロならば、ひと安心かと。
互換性チェックその 2: Splunk Platform Upgrade Readiness App
次に、Splunk Platform Upgrade Readiness App での、
チェック方法をご紹介します。
本来は、Splunk v7.x から Splunk v8.0 へのアップグレードにあたっての
チェックをする App なのですが、
Python 3 対応のチェックもできるので、便利です。
ただし、実行するには、
アップグレード元となる Splunk Enterprise v7.1, v7.2, v7.3 の
何れかの環境が必要になります。
なお、
アップグレード後の Splunk 8 では、動作しません!
運良く対象となる v7.x 系をお持ちの場合は App をインストールし、
Splunk Web UI の App リストから
Splunk Platform Upgrade Readiness App を開きます。
右上の Run New Scan ボタンを選択し、
Scan Settings のプルダウンから
Scan custom selection of apps を選択します。
画面右にインストール済みの App 一覧が表示されるので、
リストからチェックしたい App を選択。
Scan ボタンを選択します。
しばらく待つと、結果が表示されるはず。
App に含まれるファイル次第ですが、数分〜数十分とけっこうかかりますので、
気長に待つのが吉かと。
完了すると、GUI に Scan completed と表示され、
スキャン結果を見ることができます。
ちなみに、Upgrade Readiness App の動作ログは
$SPLUNK_HOME/var/log/upgrade_readiness_app/upgrade_readiness.log
に
出力されます。
2019-12-11 16:57:44,671 INFO 140663382782080 - Scan initiated
2019-12-11 16:57:44,671 INFO 140663382782080 - Retrieving key to write progress
2019-12-11 16:57:44,771 INFO 140663382782080 - Found key for existing entry: 5df0a1788f02502eb0569f21
2019-12-11 16:57:44,829 INFO 140663382782080 - Total 1 apps found for user: admin
2019-12-11 16:57:44,905 INFO 140663382782080 - 0 apps out of 1 scanned. Scanning App: Microsoft Teams alert for Splunk
2019-12-11 16:57:59,288 INFO 140084004323456 - Handling a request
2019-12-11 16:57:59,289 INFO 140084004323456 - Executing function, name=get_read_progress
(中略)
2019-12-11 17:19:17,115 INFO 140663382782080 - Deployment scanned successfully for user: admin
公開ドキュメント には、
Some Splunk apps are too large to scan.
If you cannot scan a Splunk app,
follow the app's documentation for updates on Python 3 readiness.
という但し書きも見つかったりするので、失敗にならないよう祈るくらいでしょうか。
じりじりしながら待っていても生産的ではないので、
Splunk App 向けの改修ポイントを眺めておきましょう。
公開ドキュメントの Act on scan results を見ると、
次のような項目が記載されています。
- Advanced XML を削除する (Splunk v6.3.0 で非推奨済)。
- Splunk Web レガシーモードを無効化する (Splunk v6.4.0 で非推奨済)。
-
test.py
というファイル名は使わない。 - M2Crypto ライブラリは使わない。
- アプリケーションサーバ機能の Mako テンプレートを Python 3 互換にする。
- アプリケーションサーバ機能の CherryPy エンドポイントを更新する。
- その他の Python ファイルを更新する。
対応できそうな部分は、予め実施しておくのも手ですね。
スキャンが終了すると、結果一覧が表示されます。
Check 7: Python scripts の Status: が Warning になっているのが見つかります。
この App は、ちょっと古い Add-on Builder でひな型作成しているので、
そのファイル群がばっちりひっかかったようです。
なお、Issues リストのそれぞれの項目右側に表示される
See Issues リンクをクリックすると、
修正ポイントが表示されます (これは便利)。
Upgrade Readiness App のスキャンは、
Python ファイルを独立に見ているようなので (私の想像です)、
v2/v3 を条件分岐させて別ファイルで処理させている場合などでも、
改修候補に上がってくる可能性があるようです。
スキャン結果の数に一瞬ギョッとしますが、
地道にチェックして、必要に応じて改修しましょう。
(番外編) 自作以外のサードパーティ App の互換性に、問題が見つかってしまったのだけれど・・
Splunkbase で公開されていたものであれば、
更新版が無いか、探してみましょう。
作者やメンテナによってサポートが続いてれば、
改修をお願いするのも手かもしれません。
気骨のある方は、自分で改修するのも一案かもしれませんが、
ライセンス上問題ないか確認の上、他への動作影響なども考慮しつつ、
対応されるのが良いかと思います。
晴れて、対応版が完成したら、
作者にコンタクトして、マージしてもらうのも
オープンソースの醍醐味かもしれませんね。
Splunkbase へ更新版をアップロード。
いよいよ、更新版をアップロードして再申請しましょう。
Splunkbase にログインして、
上部メールから My Account - My Profile に移動します。
Your Apps のうち、対象 App を選んで、
上部の Administrator Tools メニューから
Manage App を選択。
右上部にある New Version を選択します。
Splunkbase Developer Distribution Agreement が表示されるので、
Agree します。
Version: New Release というドロップ領域が表示されるので、
新しい版の App をアップロードします。
Release Note 等を記載できるページに遷移するので、適宜記載します。
Splunk Version Compatibility の欄もあるので、
ついでに 8.0 もチェックしてみたり。
SAVE すれば申請は完了です。
あとは、無事審査が通ることを祈りましょう。
最後に。
この記事では、サーチなどの Splunk の使い方や、
便利な Add-on のご紹介、気の利いた構成の活用方法、には触れずに、
Splunk App 開発と公開方法、にスポットライトを当ててみました。
何かしらご参考になる内容があれば幸いです。
もちろん、更新版の App を
Splunk v8 環境で実行して動作確認することも、大事ですね。
Splunk App に限らず、アプリケーションの修正にあたっては、
ビジネスロジック上、差異が無い、という部分まで チェックすることも、求められることがあります。
理想論かもしれませんが、きちんと単体テストを用意し、
tox 等で Python 2 でも Python 3 でも同じ結果が得られることをチェックするのが、
デグレ (regression) を防ぐ手立てではないか、とも思います。
なお、自作 App の新規公開については、
My First Splunk App on Splunkbase という記事を書いていますので、ご興味のある方は、ご覧ください。
それでは、Happy Merry Christmas!!