#!/usr/bin/env python
# coding: utf-8
# # Literate Computing for Reproducible Infrastructure
#
#
# 計算機インフラの御守では種々雑多なドキュメンテーションが不可欠です。日々の作業で証跡を残す、手順を整理して共有・再利用する、ユーザマニュアルや教材を整備する.. 国立情報学研究所(NII)のクラウド運用担当では、これらをシームレスに記述・蓄積する方法を研究しています。
#
# 表題の Literate Computing for Reproducible Infrastructure(以下 「LC4RI」)は、インフラ運用の場面において **機械的に再現できる、人が読み解ける手順** を手段として、過度に自動化に依存することのない、レジリエントな **人間中心の機械化** をめざしています。そこでは、作業を効率化しつつもブラックボックス化せず、作業に対する理解をチーム内でコミュニケーションできる、また、目的と手段の整合性や限界を理解し議論・評価できると言った場を維持することで、ノウハウの移転・共有を促し運用者のスキル向上とエンジニアリングチームの再生産をはかることを重視しています。
#
# 多くの現場では、管理サーバにログインしコンソール上で作業を行う、作業内容や証跡はWiki等に随時転記して共有する.. といった形態が一般的と思います。これに対しLC4RIでは運用管理サーバ上にNotebookサーバを配備し、作業単位毎にNotebookを作成、作業内容やメモを記述しながら随時実行するといった作業形態を推奨しています。作業の証跡を齟齬なく記録する仕組み、過去の作業記録を参照して機械的に再現あるいは流用できる仕組み、機械的に実行できるとともに人が読み解き補完することもできるNotebook手順を整備しています。
#
# プロジェクトの成果物は GitHub [NII Cloud Operation Team]( https://github.com/NII-cloud-operation )で公開しています。
#
# ---
# この Notebook では拡張した機能の概要を紹介します。
# ## Jupyter-run_through - まとめ実行機能
#
# 用途:
# * 詳細は気にせずNotebook形式の手順を気軽に利用したい。
# * 定型的な作業をまとめて実行する。アレンジやカスタマイズはあまり必要がない。
# * まとめて実行してエラーが発生した場合には、詳細を確認したい。
#
# [GitHub: Jupyter-LC_run_through](https://github.com/NII-cloud-operation/Jupyter-LC_run_through)
#
# ---
#
# **畳み込み表示 と まとめ実行の機能**
# 表題の左側にある は、詳細な手順が畳み込まれていることを示しています。 をクリックすると、 に変化し、畳み込まれている内容を表示することができます。
#
# 畳みこまれている内容に「手順」が含まれていると、右のように表示されます。の数は畳み込まれている手順のステップ数を示しています。
# 表示から を押すと、配下の手順をまとめて実行することができます。
#
# すべてのステップが終了すると右のように表示が変化します。実行が完了したステップは薄緑 に表示されます。また、完了したステップは、再度 まとめ実行ボタンをクリックしても実行されないよう凍結
# されます。
#
# 途中でエラーが発生した場合は当該のステップが薄紅に表示されるので、 をクリックして内容を確認します。
#
#
# ### **畳み込んだステップのまとめ実行**
#
# をクリックすると4ステップをまとめ実行します。実行が終わったステップは薄緑の表示となります。以下の例では3番目がエラーとなり薄紅表示され、実行が中断します。
#
# をクリックすることで畳み込み表示が解除され、それぞれのステップの実行内容を確認することができます。実行が終わったセルは凍結
# されます、そのままでは実行できません。修正する、再度実行する場合にはウインドウ上部のをクリックすることで凍結を解除します。
#
# エラーのセルは内容を修正して実行することができます。継続する未実行のセルは、そのまま実行することもできます。
# In[ ]:
get_ipython().system(' echo "This is 1st step" > foo; cat foo')
# In[ ]:
get_ipython().system(' echo ".. 2nd step..." >> foo && cat foo')
# In[ ]:
get_ipython().system('echooooo ".. 3rd step... will fail" >> foo && cat foo')
# "echo" に修正して実行してみましょう。
# In[ ]:
get_ipython().system(' cat foo')
# ## セルの実行結果の保存と要約表示
#
# 用途:
# * Cell単位の実行ログを各々ファイルに常時保存し、後で全体を参照したり、結果を比較できるようにする。
# * Output Cell に大量出力される場合に、必要に応じて要約表示する(出力全体は上記の機能によって保存されている)。
#
# [GitHub: Jupyter-LC_wrapper](https://github.com/NII-cloud-operation/Jupyter-LC_wrapper)
#
# ---
# 例えば、某かのパッケージ群をインストールしたりすると大量のログが出力されますが、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 などいくつかの方法でカスタマイズ可)。
#
# In[ ]:
get_ipython().getoutput('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")
#
# ここでは擬似的にログが大量に出力される状況を再現しています
#
# ログファイルは 日付毎のディレクトリの下に保存されます。
# In[ ]:
get_ipython().system('ls -laR .log/`date "+%Y%m%d"`')
# ## セル実行結果の pin 留め
# In[ ]:
import pandas
import matplotlib
import matplotlib.pyplot as plt
import random
# In[ ]:
get_ipython().run_line_magic('matplotlib', 'inline')
# In[ ]:
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 の左側に表示されている をクリックすると、出力内容をタブとして保存することができます。
# ## 参考
# [Jupyter-code_cell_status](https://github.com/NII-cloud-operation/Jupyter-code_cell_status)
#
# [Jupyter-multi-outputs](https://github.com/NII-cloud-operation/Jupyter-multi_outputs)
#
# [Jupyter-LC_nblineage](https://github.com/NII-cloud-operation/Jupyter-LC_nblineage)