計算機インフラの御守では種々雑多なドキュメンテーションが不可欠です。日々の作業で証跡を残す、手順を整理して共有・再利用する、ユーザマニュアルや教材を整備する.. 国立情報学研究所(NII)のクラウド運用担当では、これらをシームレスに記述・蓄積する方法を研究しています。
表題の Literate Computing for Reproducible Infrastructure(以下 「LC4RI」)は、インフラ運用の場面において 機械的に再現できる、人が読み解ける手順 を手段として、過度に自動化に依存することのない、レジリエントな 人間中心の機械化 をめざしています。そこでは、作業を効率化しつつもブラックボックス化せず、作業に対する理解をチーム内でコミュニケーションできる、また、目的と手段の整合性や限界を理解し議論・評価できると言った場を維持することで、ノウハウの移転・共有を促し運用者のスキル向上とエンジニアリングチームの再生産をはかることを重視しています。
多くの現場では、管理サーバにログインしコンソール上で作業を行う、作業内容や証跡はWiki等に随時転記して共有する.. といった形態が一般的と思います。これに対しLC4RIでは運用管理サーバ上にNotebookサーバを配備し、作業単位毎にNotebookを作成、作業内容やメモを記述しながら随時実行するといった作業形態を推奨しています。作業の証跡を齟齬なく記録する仕組み、過去の作業記録を参照して機械的に再現あるいは流用できる仕組み、機械的に実行できるとともに人が読み解き補完することもできるNotebook手順を整備しています。
プロジェクトの成果物は GitHub NII Cloud Operation Teamで公開しています。
この Notebook では拡張した機能の概要を紹介します。
用途:
GitHub: Jupyter-LC_run_through
畳み込み表示 と まとめ実行の機能
表題の左側にある は、詳細な手順が畳み込まれていることを示しています。 をクリックすると、 に変化し、畳み込まれている内容を表示することができます。
畳みこまれている内容に「手順」が含まれていると、右のように表示されます。の数は畳み込まれている手順のステップ数を示しています。 表示から を押すと、配下の手順をまとめて実行することができます。
すべてのステップが終了すると右のように表示が変化します。実行が完了したステップは薄緑 に表示されます。また、完了したステップは、再度 まとめ実行ボタンをクリックしても実行されないよう凍結 されます。
途中でエラーが発生した場合は当該のステップが薄紅に表示されるので、 をクリックして内容を確認します。
をクリックすると4ステップをまとめ実行します。実行が終わったステップは薄緑の表示となります。以下の例では3番目がエラーとなり薄紅表示され、実行が中断します。
をクリックすることで畳み込み表示が解除され、それぞれのステップの実行内容を確認することができます。実行が終わったセルは凍結 されます、そのままでは実行できません。修正する、再度実行する場合にはウインドウ上部のをクリックすることで凍結を解除します。
エラーのセルは内容を修正して実行することができます。継続する未実行のセルは、そのまま実行することもできます。
! echo "This is 1st step" > foo; cat foo
! echo ".. 2nd step..." >> foo && cat foo
!echooooo ".. 3rd step... will fail" >> foo && cat foo
"echo" に修正して実行してみましょう。
! cat foo
用途:
例えば、某かのパッケージ群をインストールしたりすると大量のログが出力されますが、JupyetrのWeb UI上で大量の出力を扱うのはなにかと不便です。 Jupyterの Cell の中でログの内容を検索したり、比較したりするのはまどろっこしく手間がかかります。
Jupyter-LC_wrapper を用いると:
毎回 Cell を実行する度に、出力結果がファイルに保存されます (./notebooks/.log/yyyymmdd/yyyymmdd-hhmmss-xxxx.log)。
実行毎に各々のファイルに結果が保存されるので出力結果を比較することができます。
Cellでコマンドを実行する際に先頭に "!!" を付加すると、Output Cell には要約された結果が出力されるようになります(デフォルト:50行を超える出力があった場合、最初20行と最後の20行; また、要約表示で shell を実行する場合は "!!!" )。
要約中でも、エラーなど特定のパターン含む行を表示するので結果の確認が容易です(~/.lc_wrapper_regex.txt などいくつかの方法でカスタマイズ可)。
!!from time import sleep
with open("./resources/bootstrap.log", "r") as f:
count = 0
limit = 100
for line in f:
count = count+1
if count > limit: break
print(line,end=''),
sleep(0.05)
print ("after", limit, "lines are ignored")
#
# ここでは擬似的にログが大量に出力される状況を再現しています
#
ログファイルは 日付毎のディレクトリの下に保存されます。
!ls -laR .log/`date "+%Y%m%d"`
import pandas
import matplotlib
import matplotlib.pyplot as plt
import random
%matplotlib inline
plot_df = pandas.DataFrame({
'col1': [1, 3, random.randint(1,10), 4],
'col2': [3, random.randint(5,10), 5, 1],
'col3': [4, 7, 6, 2],
})
plot_df.plot()
Output Cell の左側に表示されている をクリックすると、出力内容をタブとして保存することができます。