04.1コンソールまたはSYSLOGにメッセージを出す(WTOとWTL)
プログラムで起きていることを状況に応じてメッセージで伝えることは重要です。特にエラーが起きてオペレーターの操作や判断を必要する場合、適切なメッセージはシステムの運用面で大きな利益をもたらします。どのような時にどのようなメッセージを出すかは、プログラムのロジックと並びデザイナーの腕の見せ所でもあります。MVSにはコンソールへメッセージを出したり、オペレーターからの操作や応答を受け取るためのAPIも用意されています。これらはコンソールを操作するオペレーターとプログラムの間の通信機能でもあります。
コンソールへメッセージを出力する
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- WTO 'MYP001I ENQ ERROR' INFORM ENQ ERROR WTO 'MYP001I AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+ CDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDE' : : ENQ (QNAME,RNAME,E,L'RNAME,STEP),RET=USE CVD RF,DOUBLE EDIT RETCD IN WTO MESSAGE UNPK MSGPARM1+4+15(2),DOUBLE I OI MSGPARM1+4+16,C'0' V WTO MF=(E,MSGPARM1) INFORM ENQ ERROR WITH RC SPACE , ENQ (QNAME,RNAME,E,L'RNAME,STEP),RET=USE SLR RE,RE CLEAR WORKREG IC RE,3(,RF) LOAD ENQ ERROR CODE CVD RE,DOUBLE EDIT RETCD IN WTO MESSAGE UNPK MSGPARM1+4+15(2),DOUBLE I OI MSGPARM1+4+16,C'0' V WTO MF=(E,MSGPARM1) INFORM ENQ ERROR WITH RC : : DOUBLE DC D'0' DOUBLE WORD WORKAREA QNAME DC CL8'MYPROG' TEST ENQ QNAME RNAME DC C'TESTENQ1' TEST ENQ RNAME ******** ----0----+----1----+----2----+----3 MSGPARM1 WTO 'MYP001I ENQ RC=??', WTO LIST FORM PARAMETER + MF=L
WTOマクロはコンソールへメッセージを出力します。世の中のメインフレーム・アセンブラープログラマーに「初めて使ったOSのAPIマクロは何ですか?」とアンケートを取れば恐らく1位、少なくとも3位内には入るであろう、と言うぐらいポピュラーなマクロです。
使い方もいたって簡単で、マクロ名に続いて出したいメッセージテキストを”で囲めばOKです。テキストが長くて1行に書ききれないときは、71桁目まで目一杯書いて、72桁目に何か文字を置き、次の行の16桁目から続けます。16桁目が空白でもそのまま空白文字として扱われます。
残りの2例は、メッセージテキストの中の文字を置換えて出力したい場合に用いられる方法の1つです。実戦では固定のメッセージテキストだけでなく、メッセージの中にプログラムの処理によって内容が変わる値などを埋め込みたいことがよくあります。このような場合はリスト形式と実行形式のWTOマクロを組み合わせます。再入可能プログラムではモジュール内のWTOパラメーターを直接変更できないので、モジュール外の作業域に一旦コピーして、そちら側を修正して使用します。
わざと同じENQを2回出し、それぞれのENQサービスの復帰コードをメッセージ中のRC=??の??部分に埋め込んでコンソールに出力するものです。単にENQ ERRORと出すよりはるかに実用的です。復帰コードの値がわからなければ対処のしようがありません。サンプルでは簡単にするために10進数に変換していますが、16進数文字への変換なら、マニュアルのコード表示と一致するのでさらにわかりやすくなります。
メッセージテキストはWTOパラメーターの+4バイト目から始まります。アセンブルしてマクロの展開形を見ればすぐにわかります。本来ならOSマクロの中を、直接変位を指定して場所をポイントするのは決していいことではないのですが、WTOのような基本的なマクロはその内容が変わることは現実的にありませんし、サンプルの方法は古典的ではありますが、昔から多くのプログラムで行われている、言わば標準的・伝統的な方法です。
可変長のメッセージテキストを出力する
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- WTO TEXT=MSGLENG USE WTO WITH NEW FORMAT : MSGLENG DC AL2(L'MSGTEXT) MSG LENGTH AND TEXT MSGTEXT DC C'MYP002I VARIABLE LENGTH MESSAGE'
可変長のメッセージテキストを出力する例です(※MVSでのみ利用できる方法)。
TEXTパラメーターでコンソールへ出力するメッセージテキストの格納アドレスを指定します。メッセージ領域の先頭2バイトはメッセージテキストの長さです。メッセージ長フィールドの長さは含みません。長さに続いてメッセージテキストを格納します。
MSPおよびVOS3で可変長メッセージテキストを扱う場合、リスト形式のWTOマクロを使ってWTOパラメーターがどのように作成されるかをアセンブルリストで確かめます。それに合わせてプログラムでメッセージテキストをWTOパラメーターを作り、実行形式のWTOマクロでメッセージを出力します。
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- WTO MF=(E,WTOPARM) USE WTO WITH OLD FORMAT : WTOPARM DS 0F DC AL2(4+L'MSGTEXT) WTO PARAMETER LENGTH DC XL2'0000' MCSFLAGS MSGTEXT DC C'MYP002I VARIABLE LENGTH MESSAGE'
WTO PARAMETER LIST(OLD FASHION STYLE) +-------------+ +00| TEXT LENGTH | include 'TEXT LENGTH' and 'MCSFLAGS' field length. +-------------+ +02| MCSFLAGS | by MCSFLAG parameter +-------------+------------//-------------+ +04| MESSAGE TEXT | +-------------+------------//-------------+ +nn| DESC CODE | by DESC parameter +-------------+ +nn| ROUTE CODE | by ROUTCDE parameter +-------------+
メッセージテキストを’’で囲む従来からあるWTOパラメーターは上図のフォーマットになっています。先頭2バイトにメッセージテキスト長に4を加えた値を設定します。DESCまたはROUTCDEパラメーターを指定した場合、メッセージテキストの後ろに設定されますが、その長さは先頭のレングスフィールドには含まれません。パラメーターはワード境界に合わせます。
メッセージの種類と宛先を指定する
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- WTO 'MYP002I THIS MESSAGE HAS DESC CODE=6',DESC=(6) WTO 'MYP002I THIS MESSAGE HAS ROUTE CODE=2',ROUTCDE=(2)
メッセージの種類や宛先を指定することもできます。DESCパラメーターはメッセージの種類(性質)を表します。通常は省略してかまいませんが、指定するなら、一般のプログラムであれば6または7でいいでしょう。OSの出口ルーチンなどで重大なエラーを検出して、オペレーターにメッセージで伝えるような時、スクロールされてメッセージが流れないようにするにはDESCコードとして11を指定します。DESCコード11を指定した場合、WTOマクロ完了時にGR1に返されるメッセージ識別番号を保存します。この識別番号を使えばDOMマクロによってメッセージを削除することが可能です。DESCコード11のメッセージはプログラムがDOMマクロを使うか、オペレーターがコンソール操作(MVSの場合、K C,A,idコマンド)によってしか消されることはありません。
ROUTCDEパラメーターはメッセージの宛先を表します。これも通常は省略してかまいませんが、一般プログラムが指定するなら2がいいでしょう。MVSではSYSLOGの3?9桁目がメッセージのROUTE CODEを示します。16進表記ですが左ビットからROUTE1,2,3,4,5,6,…,28となっています。ここを見て他のソフトウェア製品などがどのようなROUTCDEを使っているかを参考にするのも1つの方法です。FFFFFFFFとなっていたらROUTCDEは省略されています。
DESCとROUTCDEのコードそのものの詳細な解説は「MVS 宛先コードおよび記述子コード」マニュアルに記載されています。コードの用途はMSP/VOS3でも基本的に同じです。
SYSLOGへメッセージを出力する
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- WTL 'MYP002I SYSLOG MESSAGE' WTO 'MYP002I SYSLOG MESSAGE',MCSFLAG=HRDCPY
コンソールへの表示は不要だがシスログには残したい、と言う場合もあります。そのような時はWTLマクロをWTOマクロの代わりに使うことができます。なお現在IBMではWTLマクロに代わり、MCSFLAG=HRDCPYを指定したWTOマクロによる方法を推奨しています。
MCSFLAG=HRDCPY指定のWTOを使った場合、SDSFのLOG機能やECSなどの仮想コンソールプログラムを使用すると、上記の方法ではメッセージが表示されることがあります。これはその仮想コンソール機能が純粋にコンソールとしてではなく、SYSLOGをベースにメッセージを表示しているからです。本当にコンソールには出ていないかを確認するには実コンソールを見て下さい。
補足
MVSではWTOマクロ発行前にGR0を0クリアーすることをマニュアルで注意事項として明記しています。MSP,VOS3と以前のMVSではGR0にコンソール識別番号を入れると特定のコンソールにメッセージを出すことができます。この場合MCSFLAGパラメーターでREG0オプションが必要です。現在のz/OSではこのオプションは廃止されたため、GR0は常に0クリアーすることがマニュアルに記述されています。互換の問題があるので絶対に0クリアーされていなければだめかどうかはわかりませんが、これから新たにWTOマクロを使うならマニュアル通り0クリアーした方がいいでしょう。MSPとVOS3ではこのオプションは有効です。
APF許可されていないプログラムが出したコンソール・メッセージの先頭には+記号が付きます。これはWTOサービスの仕様です。