[[PageOutline]] = 電子ログシステム & 画像ログシステム = KEK cERL/PF 加速器の運転のため、電子ログシステム(botlog)と画像ログシステム(!PrintAnyServer)を開発した。[[br]] 2018年加速器学会でも報告している([https://www.pasj.jp/web_publish/pasj2018/abstracts/index.html Abstract ページ]「Webベース電子ログ及び画像ログシステムの開発」WEP102) = 使い方 = [wiki:misc/botlog_pas/users_manual 使い方]は記述中。 = パッケージインストール = パッケージは以下のURLからダウンロードできる。インストールや運用は、サーバーシステム管理者でroot権限を持っていることを前提としている。 [http://cerldev.kek.jp/botlog_pas/botlog_pas_20180821_16.tar.gz botlog & PrintAnyServer パッケージ(2018/08/21版)] == インストール環境 == 今回のインストールに使用したシステムは、 * Intel_x86_64 * CentOS 6.9(最新は6.10) * インストールディスク: netinstall * インストールパッケージ: desktop * apache 2.2.x(CentOS 6.x標準) のみで動作検証している。[[br]] これはパッケージ中に、コンパイル済の python2.7、epics_base とapache用 mod_wsgi.so が入っているためなので、 もし別のOSにインストールする場合には、これらを別途コンパイルするか、OSのpackageとpythonのpackageを自力でインストールする必要がある。 また、apache関連の設定も上書きするので、既存のサーバーにインストールする際には、一旦別ディレクトリに展開するなどの注意が必要。[[br]] なるべくなら新規のサーバーか仮想マシン上に展開するほうがいい。 '''新規サーバーにインストールする際には、selinuxをoffにすることを忘れないように。設定し忘れると、ログ出力ができずにInternalErrorになる。''' ''' このシステムは、Web画面表示用javascriptのほとんどをCDN(Content Delivery Network)経由で取得しているので、外部ネットワークから完全に隔離されたネットワークでは動作しない。[[br]] 必ず、グローバルネットワークへ接続可能なネットワークで使用すること。[[br]] ''' (この問題はいつかは解決する予定だが、現時点では優先順位は高くない。要望があれば連絡して欲しい。) === 余談 === CentOS6.10 x86_64 をminimalインストール後に、デフォルト状態のまま(botlog,PrintAnyServer本体のみ)でよければ、{{{httpd}}}だけ追加すれば動作した。[[br]] 他にも配布パッケージをコピーするために{{{wget}}}を、PrintAnyServerの状態確認のために{{{telnet}}}を入れたが、動作には関係ない。[[br]] == パッケージ展開 == 電子ログシステム関連のプログラムのほとんどは、{{{/opt/OperationLog}}}に置くようにしてある。[[br]] 追加/上書きされるディレクトリ一覧は、次のようになっている。 {{{ /opt/OperationLog/botlog botlog本体 /PrintAnyServer PrintAnyServer本体 /data データ保存ディレクトリ /botlog botlog用DB /pas 画像保存用 /epics EPICS base R.14.12.7 /etc 環境設定用 /local 環境用プログラム(python2.7等) /log ログ保存ディレクトリ /var/www/html 初期サイトディレクトリ /printView PrintAnyServer用ディレクトリ(/opt/OperationLog/PrintAnyServer/Printviewへのシンボリック) /etc/httpd/conf/httpd.conf apache 2.2用設定ファイル /conf.d/botlog.conf botlog用設定ファイル /conf.d/pas.conf PrintAnyServer用設定ファイル /etc/ld.so.conf.d/OperationLog.conf /opt/OperationLog/local/libを登録 /usr/lib64/httpd/modules/mod_wsgi.so /opt/OperationLog/local以下のpython2.7を使用するようにコンパイル済 /etc/selinux/targeted/contexts/files/file_contexts.local selinuxコンテキスト設定ファイル }}} そのまま上書きする場合には、rootで実行する必要がある。 {{{ [root@localhost ~]# tar zxf botlog_pas_xxxxxx.tar.gz -C / }}} 展開後、ライブラリパスを設定し、{{{/opt/OperationLog/local/lib}}}を使用可能にする。 {{{ [root@localhost ~]# ldconfig }}} また、httpd(apache)のサービスを起動していない場合には、設定ファイルのチェック後にサービスを起動する。 {{{ [root@localhost ~]# apachtctl -t Syntax OK [root@localhost ~]# service httpd status httpd is stopped [root@localhost ~]# service httpd start Starting httpd: [ OK ] [root@localhost ~]# chkconfig --list httpd httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off [root@localhost ~]# chkconfig httpd on [root@localhost ~]# chkconfig --list httpd httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off }}} == 管理ユーザー設定 == 電子ログの管理ユーザーを設定する。[[br]] {{{root}}}で問題なければそのままでも構わないが、管理用のユーザーを作ったほうが安全だと思われる。[[br]] 展開した{{{/opt/OperationLog}}}以下のディレクトリは、所有者が{{{uid:501,gid:502}}}になっているので、ファイルは適切な所有者に変更すること。 == PrintAnyServerの起動 == PrintAnyServerの本体は、httpdとは別のプロセスとして動作しているので、事前に起動させておく必要がある。[[br]] 起動用のスクリプトを作成してあるが、まずはコマンドラインから起動して動作確認をする。[[br]] PrintAnyServerは、内部でuid,gid等を変更する機能があるので、rootで実行すること。[[br]] {{{ [root@localhost ~]# cd /opt/OperationLog/PrintAnyServer [root@localhost PrintAnyServer]# source /opt/OperationLog/etc/env.sh [root@localhost PrintAnyServer]# python2.7 printAnyServer.py conf/test.cfg Bottle v0.12.13 server starting up (using PasteServer())... Listening on http://0.0.0.0:9090/ Hit Ctrl-C to quit. serving on 0.0.0.0:9090 view at http://127.0.0.1:9090 }}} 正常に起動できれば、以上のようなメッセージが表示される。[[br]] == 動作確認 == 同一ネットワーク上のPCでWebブラウザを立ち上げて、それぞれ{{{http://(HOSTNAMEorIPADDR)/TEST/botlog/edit}}}と{{{http://(HOSTNAMEorIPADDR)/printView}}}にアクセスすると画面が表示されるはずである。[[br]] 下記の画面は、電子ログシステム起動後に入力した画面の例。 [[Image(2018_08_17_18_08_56.png,300)]][[Image(2018_08_17_18_09_17.png,300)]] 時々、ログを登録しても表示されない場合があるが、表示タイミングの問題なので、{{{F5}}}キーでWeb画面を更新すれば表示される。[[br]] 画面を確認したら、PrintAnyServerは一旦{{{CTRL+C}}}で終了しておく。 = 設定 = この状態でも一般的な使用は可能なので、そのまま使っても問題はないが、最低でも{{{http://(HOSTNAMEorIPADDR)/TEST/botlog/***}}}の{{{/TEST}}}は変更したほうがいいだろう。[[br]] botlog,PrintAnyServer共に設定を変更した際には、必ずhttpdを再起動する必要がある。 {{{ [root@localhost ~]# service httpd restart Stopping httpd: [ OK ] Starting httpd: [ OK ] }}} == botlog == === URL変更 === 接続先URLが、{{{/TEST/botlog/***}}}となっているので、これを変更する。[[br]] 修正するファイルは、{{{/opt/OperationLog/botlog/modules/botlogConfig.py}}}。このファイルは、{{{/opt/OperationLog/botlog/botlogConfig_default.py}}}のシンボリックなので、一旦シンボリックを削除して、{{{botlogConfig_default.py}}}をコピーしてから修正する。[[br]] 今回は{{{"EUJP"}}}に変更する。 ここからは、管理ユーザーで行う。 {{{ [user@localhost ~]$ cd /opt/OperationLog/botlog/ [user@localhost botlog]$ rm modules/botlogConfig.py [user@localhost botlog]$ cp botlogConfig_default.py modules/botlogConfig.py [user@localhost botlog]$ vi modules/botlogConfig.py      : # 正式版(or 外部プログラム)用サーバー設定 def getServerCfg(self): # type: [ httpd | standalone ] # standalone: 単体動作用デバッグサーバ # httpd: WebApplicaiotn return {'type':'httpd', 'host':'localhost', # Set server IP address 'port':80, 'root':'/EUJP'} # Set Site Name      : }}} 修正箇所は{{{getServerCfg:root}}}。[[br]] 他にも、apacheの設定ファイルを変更する必要がある。これは{{{root}}}で。[[br]] 変更箇所は、{{{WSGIScriptAlias}}}[[br]] {{{ [root@localhost ~]# vi /etc/httpd/conf.d/botlog.conf WSGIPythonPath /opt/OperationLog/local/lib/python2.7/site-packages/ #WSGIScriptAlias /TEST/botlog /opt/OperationLog/botlog/botlogApp.wsgi WSGIScriptAlias /EUJP/botlog /opt/OperationLog/botlog/botlogApp.wsgi Options All AllowOverride All Order allow,deny Allow from all }}} 修正後に、httpdを再起動し、{{{http://(HOSTNAMEorIPADDR)/EUJP/botlog/edit}}}にアクセスすると変更前と同じデータが表示される。 === DB === デフォルトでは、sqlite3が動作確認用DBとして設定されている。[[br]] sqlite3のDBは単一ファイルなので、ファイルの保存ディレクトリを変更すればいい。[[br]] {{{ # sqlite3用DB設定 def getSqlite3Cfg(self): # file: db file # dbファイルのフルパスを設定 # * 作成したファイルとファイルのあるディレクトリのパーミッションは"777"にしておくか # Webサーバーのユーザー(通常はapache/apache)が読み書きできるようにしておくこと return {'file':'/opt/OperationLog/data/botlog/db/sqlite3/botlog.sqlite3'} }}} コメントにも書いてあるように、DBファイルとディレクトリのパーミッションは"777"にしないと動作しなくなるので注意。[[br]] DBをPostgreSQLに変更する場合には、 {{{ # DB種別設定 def getDbCfg(self): # type: [ sqlite3 | postgresql ] #return {'type':'sqlite3'} return {'type':'postgresql'} # postgresql用設定 # userは設定しないとhttpd user(apache)で書き込むので、 # DB管理用ユーザー(作成ユーザー)を設定すること def getPostgresqlCfg(self): return {'host':'localhost', <-- DBホスト 'port':5432, <-- 接続ポート番号 'db':'botlog', <-- DB名(これは変えなくてもいい) 'user':'logoper', <-- DB接続ユーザー名 'passwd':''} <-- DB接続パスワード }}} の設定を変更する。[[br]] PostgreSQL自体の設定はここでは説明しない。 === セクション(グルーブ)設定 === セクション名の設定は、SQLを直接実行するか、{{{/opt/OperationLog/botlog/sql/[sqlite3|PostgreSQL]/section.sql}}}を編集したデータを各DB用のコンソールから設定する。[[br]] 但し、idが0,1は特別な意味を持っているので、設定は変更しないこと。[[br]] データがない初期状態ならば、テーブルを一括で作成するスクリプトを作成しているので、それを利用すると一括でテーブルを再構築する。[[br]] '''このスクリプトは一度全てのテーブルを削除するので、消してもいいデータしかない場合以外は実行しないこと。'''[[br]] * sqlite3 の場合 {{{ [user@localhost ~]$ /opt/OperationLog/botlog/sql/sqlite3/createTable.sh /opt/OperationLog/data/botlog/db/sqlite3/botlog.sqlite3 }}} * PostgreSQLの場合 PostgreSQLの場合には、DBへ接続するための設定をシェルスクリプト内に記述してから実行すること。 {{{ [user@localhost ~]$ /opt/OperationLog/botlog/sql/PostgreSQL/createTable.sh }}} テーブルがない状態でこれらのスクリプトを起動すると、いくつかエラーが表示されるが、無視してもいい。 == !PrintAnyServer == === URL変更 === ''' 設定の変更は管理ユーザーで行うが、プログラムの実行は{{{root}}}で行うので注意。'''[[br]] ディレクトリ名をbotlogと合わせるようにする場合には、設定ファイルと{{{/var/www/html/~}}}のディレクトリ名を変更する。[[br]] 変更しない場合にはここを読み飛ばして、動作確認を参照。[[br]] ここでは、例としてbotlogと同じく{{{EUJP}}}としておく。[[br]] まずは、設定ファイル名が{{{test.cfg}}}になっているので、これを適当なものに変更する。[[br]] {{{ [user@localhost ~]$ cd /opt/OperationLog/PrintAnyServer/conf [user@localhost conf]$ cp test.cfg eujp.cfg }}} 次に設定を変更する。[[br]] {{{ [user@localhost conf]$ vi eujp.cfg : [server] rcvHost=0.0.0.0 host=localhost port=9090 root=/EUJP debug=1 reload=0 : [URL] baseURL=/EUJP/printView/Print convURL= : }}} URLに設定したディレクトリから参照できるように、実ディレクトリを移動する。ここは{{{root}}}で作業[[br]] {{{ [root@localhost ~]$ cd /var/www/html [root@localhost html]$ mkdir EUJP [root@localhost html]$ mv printView EUJP }}} === 動作確認 === PrintAnyServerは、サーバー起動後にWeb画面から画像を登録して動作を確認する。[[br]] まずは、rootになってからPrintAnyServerを再起動する。 {{{ [root@localhost ~]# cd /opt/OperationLog/PrintAnyServer [root@localhost PrintAnyServer]# source /opt/OperationLog/etc/env.sh [root@localhost PrintAnyServer]# python2.7 printAnyServer.py conf/eujp.cfg Bottle v0.12.13 server starting up (using PasteServer())... Listening on http://0.0.0.0:9090/ Hit Ctrl-C to quit. serving on 0.0.0.0:9090 view at http://127.0.0.1:9090 }}} Web画面を起動し、クリップボードに画像を読み込んでから、"Paste clipboard image or Drop image file"上で右クリックして、"Paste"を選択する。[[br]] 画像のサムネイルとキャプションが入力できるダイアログボックスが表示されるので、"登録"ボタンを押下する。[[br]] 正常に動作すれば画像が表示され、{{{/opt/OperationLog/data/pas}}}に日付ディレクトリとindex_list.txtというファイルが作成される。[[br]] === 起動スクリプト === PrintAnyServerをprocServで起動するためのスクリプト"{{{/opt/OperationLog/PrintAnyServer/bootPas.sh}}}"を作成してあるので、通常運用時に使用して欲しい。[[br]] ファイルの内容は以下の通り。 {{{ #!/bin/sh TOP=/opt/OperationLog PROCSERV=$TOP/local/bin/procServ PYTHON=$TOP/local/bin/python PAS_TOP=$TOP/PrintAnyServer PAS=$PAS_TOP/printAnyServer.py PAS_CONFIG=$PAS_TOP/conf/test.cfg PROC_LOG=$TOP/log/pas/procServ.log PROC_PORT=20200 $PROCSERV -P $PROC_PORT -L $PROC_LOG $PYTHON $PAS $PAS_CONFIG }}} 通常は、{{{PAS_CONFIG}}}で設定ファイルの名前を変更する程度だが、実際に使用する際には、環境に合わせてスクリプトの内容は変更してから使用すること。[[br]] === その他の設定 === 基本的な設定以外にも、[wiki:misc/botlog_pas/client_download クライアント用プログラムのダウンロード機能]と[wiki:misc/botlog_pas/printer 同時印刷機能]があるが、これらは別ページで解説する。 == EPICS record monitor == EPICS record monitor は、botlog用Web APIを使用した外部プログラムで、登録されているEPICSレコードに変化があった場合、botlogに自動的にメッセージを登録する。[[br]] 監視するレコードとメッセージの関連付けは、pythonで記述し、1メッセージにつき、1ファイルを作成する必要がある。[[br]] プログラム本体は、{{{/opt/OperationLog/botlog/tools/epicsRecordMonitor}}}の{{{epicsRecordMonitor.py}}}で、各設定は{{{/opt/OperationLog/botlog/tools/epicsRecordMonitor/Modules}}}に設定する。 === 設定ファイル === 設定ファイルは、{{{/opt/OperationLog/botlog/tools/epicsRecordMonitor/test_ermi.py}}}をひな型にして作成し、{{{/opt/OperationLog/botlog/tools/epicsRecordMonitor/Modules}}}に保存すれば、{{{epicsRecordMonitor.py}}}を起動した際に読み込まれ、実行される。 {{{ # -*- coding: utf-8 -*- # """ このプログラムを EPICS Record Monitor 定義のひな型として使用すること 各設定に使用する場合に変更する箇所は、pvs変数とexecFunc関数 クラス名は変更しないこと """ from epicsRecordMonitorItem import * # # # class ermi(epicsRecordMonitorItemIF): # # クラスコンストラクタ # ここで使用するレコード名を設定 # def __init__(self): pvs = ['jane', 'fred'] # ここに使用するレコード名をリスト形式で設定 self.setPvs(pvs) # # メッセージ出力条件を記述 # 関数の引き数 pvs に関数実行時のデータが渡される # データの形式は辞書型を含んだリストで、構造は以下のようになっている # # [ # { # 'name' : record name, # 'prevVal': previos value, # 'val' : current value, # 'time' : record process time # }, # : # ] # # リストの順番はコンストラクタで設定した順番 # # 戻り値はメッセージのみを返すようにして、メッセージがない場合には None を返すこと # def execFunc(self, pvs): janePv = pvs[0] fredPv = pvs[1] rtn = None if janePv['val'] < fredPv['val'] and fredPv['prevVal'] != fredPv['val']: rtn = "fred is over jane!!!" return rtn }}} 設定ファイルのチェック機能はまだ作成していないので、動作チェックは実際に動かしてみるしか方法が無い。[[br]] === 動作確認 === 動作テストは、{{{/opt/OperationLog/botlog/tools/epicsRecordMonitor/test_ermi.py}}}を{{{Modules}}}にコピーして、プログラムを実行することで行う。 {{{ [user@localhost ~]$ source /opt/OperationLog/etc/env.sh [user@localhost ~]$ cd /opt/OperationLog/botlog/tools/epicsRecordMonitor [user@localhost epicsRecordMonitor]$ cp test_ermi.py Modules [user@localhost epicsRecordMonitor]$ python2.7 epicsRecordMonitor.py }}} プログラムを実行すると、botlogに{{{Initial Disconnect Pvs:jane, fred}}}というメッセージが表示される。[[br]] 一旦プログラムを終了し、{{{excas}}}を別画面で起動する。[[br]] 再度プログラムを起動し、{{{test_ermi.py}}}に設定してある条件が満たされると、{{{fred is over jane!!!}}}というメッセージが追加される。[[br]] 後は、{{{Modules/test_ermi.py}}}を削除してから、設定ファイルを作成後にプログラムを実行すれば、メッセージが自動的にbotlogに追加される。[[br]] このプログラム用の起動スクリプトは作成していないので、ユーザーが作成すること。