ソケットごとの実行 SQL の収集 (V5R4)

System API で NETSTAT 拡張情報の取得 (V5R4)」で得たジョブ情報をもとに、「ジョブの最終実行 SQL ステートメントの取得」のロジックを組み合わせて、指定したソケット毎に実行された SQL の情報を取得するプログラムを作ってみました。

実際には「System API で NETSTAT 情報の取得 (V5R4)」などと組み合わせて、接続元となっているポートへの接続情報を取得して、さらにその個々のソケットに対してこのプログラムを実行する、というところまで行く必要がありそうですが、とりあえず形になったところでいったん記事にしておこうと思ってこういうかたちになっています。

ジョブの最終実行 SQL ステートメントの取得」は、実際のところ「こうすれば『ジョブの最終実行 SQL』は取ってこれるんだ」というところで終わっていたので、今回部品として使ってみていくつかの不具合がわかりました。
今回、ここで修正しています。


ソケットを指定して拡張情報の取得

プロトタイプの追加

System API で NETSTAT 拡張情報の取得 (V5R4)」に、「ジョブの最終実行 SQL ステートメントの取得」を呼び出すためのプロトタイプを追加しています。

     D RtvSQLInf       PR                                                                           
     D  JobName                      10a   CONST                                                    
     D  UserName                     10a   CONST                                                    
     D  JobNumber                     6a   CONST                                                    
     D  SQLStmt                   65535a   Options(*VarSize)                                        
     D  SQLStmtLen                   10u 0                                                          

ジョブ情報が得られた時点で、↑を呼び出しています。

                for i = 1 to NCND0200.HowManyJobsCnn ;                                              
                // do something                                                                     
                  RtvSQLInf( JobInfo.JobName                                                        
                           : JobInfo.JobUser                                                        
                           : JobInfo.JobNumber                                                      
                           : pSQLStmt                                                               
                           : pSQLStmtLen                                                            
                           );                                                                       
                                                                                                    
                  vSQLStmt = %subst(pSQLStmt : 1 : pSQLStmtLen) ;                                   
                                                                                                    
                  p2JobInfo = p2JobInfo + NCND0200.EntLenLstJobs ;                                  
                endfor ;                                                                            

あとは、必要なワークフィールド等を追加しているだけですね。

コーディング例

     H bnddir('QC2LE')                                                                              
      *                                                                                             
     D RtvNetCnnD      PR                                                                           
     D  pProtocol                     4a                                                            
     D  lAddr                        15a                                                            
     D  lPort                         5a                                                            
     D  rAddr                        15a                                                            
     D  rPort                         5a                                                            
      *                                                                                             
     D RtvNetCnnD      PI                                                                           
     D  pProtocol                     4a                                                            
     D  lAddr                        15a                                                            
     D  lPort                         5a                                                            
     D  rAddr                        15a                                                            
     D  rPort                         5a                                                            
      *                                                                                             
     D RtvNetCnnDta    Pr                  ExtProc( 'QtocRtvNetCnnDta' )                            
     D  spRcvVar                  65535a   Options( *VarSize )                                      
     D  spRcvVarLen                  10i 0 Const                                                    
     D  spFmtName                     8a   Const                                                    
     D  spSocReq                       *   value                                                    
     D  spError                   32767a   Options( *VarSize: *Omit )                               
     **                                                                                             
      *                                                                                             
     D inet_addr       Pr            10u 0 ExtProc( 'inet_addr' )                                   
     D  srcAddr                        *   value options(*string)                                   
      *                                                                                             
     D RtvSQLInf       PR                                                                           
     D  JobName                      10a   CONST                                                    
     D  UserName                     10a   CONST                                                    
     D  JobNumber                     6a   CONST                                                    
     D  SQLStmt                   65535a   Options(*VarSize)                                        
     D  SQLStmtLen                   10u 0                                                          
      *                                                                                             
     **-- Api error data structure:                                                                 
     D ERRC0100        Ds                  Qualified                                                
     D  BytPro                       10i 0 Inz( %Size( ERRC0100 ))                                  
     D  BytAvl                       10i 0 Inz                                                      
     D  MsgId                         7a                                                            
     D                                1a                                                            
     D  MsgDta                      128a                                                            
     **-- Global variables:                                                                         
     D ApiRcvSiz       s             10u 0                                                          
     **                                                                                             
     DSocReqInfo       DS                  Qualified                                                
     D Protocol                      10U 0                                      Protocol            
     D LocalIP                       10U 0                                      Local IP Address    
     D LocalPort                     10U 0                                      Local Port Number   
     D RemoteIP                      10U 0                                      Remote IP Address   
     D RemotePort                    10U 0                                      Remote Port Number  
      *                                                                                             
     DNCND0100         DS                  Qualified BASED(p2CnnInfo)                               
     D BytRtnd                       10U 0                                      Bytes Returned      
     D BytAvl                        10U 0                                      Bytes Available     
     D TCPConnCur                    10U 0                                      TCP Connections Cur 
     D TCPActiveOpn                  10U 0                                      TCP Active Opens    
     D TCPPasiveOpn                  10U 0                                      TCP Passive Opens   
     D TCPAtOpnFail                  10U 0                                      TCP Attempted Opn F 
     D TCPEstRset                    10U 0                                      TCP Established And 
     D TCPSegSent                    10U 0                                      TCP Segments Sent   
     D TCPRtrsmtSeg                  10U 0                                      TCP Retransmited Sg 
     D TCPRsetSeg                    10U 0                                      TCP Reset Segments  
     D TCPSegRcvd                    10U 0                                      TCP Segments Rcvd   
     D TCPSegRcvdErr                 10U 0                                      TCP Segments Rcvd Er
     D UDPDtagrmSent                 10U 0                                      UDP Datagrams Sent  
     D UDPDtagrmRcvd                 10U 0                                      UDP Datagrams Rcvd  
     D UDPDtagrmNDNF                 10U 0                                      UDP Datagrms ND NF  
     D UDPDtagrmNDDE                 10U 0                                      UDP Datagrms ND Err 
     D OffSet2Add                    10U 0                                      Offset To Add Info  
     D Len4AddInf                    10U 0                                      Length Of Add Info  
      *                                                                                             
     DNCND0200         DS                  Qualified BASED(p2Cnd2Info)                              
     D Protocol                      10U 0                                      Protocol            
     D LocalIP                       10U 0                                      Local IP Address    
     D LocalPort                     10U 0                                      Local Port Number   
     D RemoteIP                      10U 0                                      Remote IP Address   
     D RemotePort                    10U 0                                      Remote Port Number  
     D RoundTripTime                 10U 0                                      Round Trip Time     
     D RoundTripVar                  10U 0                                      Round Trip Variance 
     D OutByteBuf                    10U 0                                      Outgoing Bytes Buff 
     D UsrSndNxt                     10U 0                                      User Send Next      
     D SndNxt                        10U 0                                      Send Next           
     D SndUnAck                      10U 0                                      Send Unacknowledged 
     D OutPushNbr                    10U 0                                      Outgoing Push No    
     D OutUrgNbr                     10U 0                                      Outgoing Urgency No 
     D OutWindNbr                    10U 0                                      Outgoing Window No  
     D InByteBuf                     10U 0                                      Incoming Bytes Buff 
     D RcvNxt                        10U 0                                      Receive Next        
     D UsrRcvNxt                     10U 0                                      User Receive Next   
     D InPushNbr                     10U 0                                      Incoming Push No    
     D InUrgNbr                      10U 0                                      Incoming Urgency No 
     D InWindNbr                     10U 0                                      Incoming Window No  
     D TotRetrnsmt                   10U 0                                      Total Retransmit    
     D CurRetrnsmt                   10U 0                                      Currect Retransmit  
     D MaxWindSize                   10U 0                                      Maximum Window Size 
     D CurWindSize                   10U 0                                      Current Window Size 
     D LastUpdate                    10U 0                                      Last Update         
     D LastUpdateAckd                10U 0                                      Last Update Acked   
     D CongWind                      10U 0                                      Congestion Window   
     D SlowStrThresld                10U 0                                      Slow Start Threshold
     D MaxSegSize                    10U 0                                      Max Segment Size    
     D InitSendSeqNbr                10U 0                                      Init Send Seq No    
     D InitRcvSeqNbr                 10U 0                                      Init Receive Seq No 
     D ConnTrnpLayr                  10U 0                                      Conn Transport Layer
     D TCPState                      10U 0                                      TCP State           
     D CnnOpnType                    10U 0                                      Conn Open Type      
     D IdleTimeMsec                  10U 0                                      Idle Time Millisec  
     D IPOptions                     40a                                        IP Options          
     D ByteIn                        10U 0                                      Bytes In            
     D BytesOut                      10U 0                                      Bytes Out           
     D SocState                      10U 0                                      Socket State        
     D OfsLstSocOpt                  10U 0                                      Offset List Of Sock 
     D SocOptNbr                     10U 0                                      Num Soc Opts W Cnn  
     D EntLenSocOpt                  10U 0                                      Ent Len Soc Opts    
     D Ofs2LstJobs                   10U 0                                      Ofs List Jobs A W C 
     D HowManyJobsCnn                10U 0                                      Num Jobs A W Conn   
     D EntLenLstJobs                 10U 0                                      Ent Len Jobs A W Cnn
     D AssocUSRPRF                   10a                                        Associated USRPRF   
     D rsvd                           2a                                        reserved            
      *                                                                                             
     DJobInfo          DS                  Qualified  BASED(p2JobInfo)                              
     D FmtEntry                      10u 0                                      Format Entry        
     D Taskname                      16a                                        Format Entry        
     D JobName                       10a                                        Job Name            
     D JobUser                       10a                                        Job User            
     D JobNumber                      6a                                        Job Number          
     D IntJobID                      16a                                        Job Internal ID     
     D JobType                        1a                                        Job Type            
     D rsvd                           7a                                        reserved            
     D CurUSRPRF                     10a                                        Associated USRPRF   
      *                                                                                             
     D  i              S             10u 0                                                          
     D  pSQLStmt       S          65535a                                                            
     D  pSQLStmtLen    S             10u 0                                                          
     D  vSQLStmt       S          65535a   Varying                                                  
      /Free                                                                                         
                                                                                                    
             *inLR = *on;                                                                           
                                                                                                    
             ApiRcvSiz = 65535;                                                                     
             p2CnnInfo = %alloc( ApiRcvSiz );                                                       
             NCND0100.BytAvl = *Zero;                                                               
                                                                                                    
              Select ;                                                                              
                when pProtocol = '*TCP' ;                                                           
                     SocReqInfo.Protocol = 1 ;                                                      
                when pProtocol = '*UDP' ;                                                           
                     SocReqInfo.Protocol = 2 ;                                                      
                other ;                                                                             
                     return ;                                                                       
              endSL ;                                                                               
                                                                                                    
              if lAddr = *blank ;                                                                   
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.LocalIP = inet_addr(%trimR(lAddr)) ;                                   
              endif ;                                                                               
                                                                                                    
              if lPort = *blanks ;                                                                  
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.LocalPort = %int(lPort) ;                                              
              endif ;                                                                               
                                                                                                    
              if rAddr = *blank ;                                                                   
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.RemoteIP = inet_addr(%trimR(rAddr)) ;                                  
              endif ;                                                                               
                                                                                                    
              if rPort = *blanks ;                                                                  
                  return ;                                                                          
              else ;                                                                                
                  SocReqInfo.RemotePort = %int(rPort) ;                                             
              endif ;                                                                               
                                                                                                    
             DoU  NCND0100.BytAvl <= ApiRcvSiz     Or                                               
                  ERRC0100.BytAvl  > *Zero;                                                         
                                                                                                    
               If  NCND0100.BytAvl > ApiRcvSiz;                                                     
                 ApiRcvSiz = NCND0100.BytAvl;                                                       
                 p2CnnInfo = %reAlloc( p2CnnInfo: ApiRcvSiz );                                      
               EndIf;                                                                               
                                                                                                    
               RtvNetCnnDta( NCND0100                                                               
                           : ApiRcvSiz                                                              
                           : 'NCND0200'                                                             
                           : %addr(SocReqInfo)                                                      
                           : ERRC0100                                                               
                           );                                                                       
                                                                                                    
              EndDo;                                                                                
                                                                                                    
              If  ERRC0100.BytAvl = *Zero;                                                          
                                                                                                    
                p2Cnd2Info = p2CnnInfo + NCND0100.OffSet2Add ;                                      
                                                                                                    
                 If NCND0200.HowManyJobsCnn = *Zero;                                                
                   return ;                                                                         
                 endIf ;                                                                            
                                                                                                    
            //  p2JobInfo = p2Cnd2Info + NCND0200.Ofs2LstJobs ;                                     
            //  Not offset from NCND0200 but NCND0100 ... (see above)                               
                p2JobInfo = p2CnnInfo + NCND0200.Ofs2LstJobs ;                                      
                                                                                                    
                for i = 1 to NCND0200.HowManyJobsCnn ;                                              
                // do something                                                                     
                  RtvSQLInf( JobInfo.JobName                                                        
                           : JobInfo.JobUser                                                        
                           : JobInfo.JobNumber                                                      
                           : pSQLStmt                                                               
                           : pSQLStmtLen                                                            
                           );                                                                       
                                                                                                    
                  vSQLStmt = %subst(pSQLStmt : 1 : pSQLStmtLen) ;                                   
                                                                                                    
                  p2JobInfo = p2JobInfo + NCND0200.EntLenLstJobs ;                                  
                endfor ;                                                                            
                                                                                                    
              else ;                                                                                
                                                                                                    
                // sndmsg ERRC0100.MSGID                                                            
                                                                                                    
              EndIf;                                                                                
                                                                                                    
              Dealloc p2CnnInfo ;                                                                   
                                                                                                    
              return;                                                                               
                                                                                                    
      /End-Free  

ジョブ情報の取得

SQL 文を可変長に

今回はまだそこまで造ってはいないのですが、最終的に、得られた SQL 文はデータベースに入れようと考えています。
その際できるだけ効率よくなるように、可変長で扱うように変更しています。

     D RtvSQLInf       PR                                                                           
     D  JobName                      10a   CONST                                                    
     D  UserName                     10a   CONST                                                    
     D  JobNumber                     6a   CONST                                                    
     D  SQLStmt                   65535a   Options(*VarSize)                                        
     D  SQLStmtLen                   10u 0   

↓は受け取り側のデバッグ画面ですが、きちんと SQL がわたってきて、

後続ブランクを含まない文字数がわたってきていることが確認できますね。

「最終実行 SQL」が存在しないケース

事前開始されて、まだ SQL が実行されていない状態のジョブもいます。

そんな場合はそもそも SQL が入ってこないので、特殊値として "*NONE" を渡すようにしています。
受け取り側で "*NONE" だった場合に処置できるように、ということで今回はこうしてみました。

          If JOBI0900.NBROPNCRS <> 0 ;                                                              
                                                                                                    
           StartPosC = %addr(JOBI0900) + (JOBI0900.OFSOPNCRS) ;                                     
                                                                                                    
           for i = 1 to %dec(JOBI0900.NBROPNCRS) ;                                                  
              SQLCurName = CursorInfo.SQLCurName ;                                                  
              SQLStmtname = CursorInfo.SQLStmtname ;                                                
              StartPosC = StartPosC + %size(CursorInfo) ;                                           
           endfor ;                                                                                 
                                                                                                    
           StartPosS = %addr(JOBI0900) + (JOBI0900.OFSCURCRS) ;                                     
           SQLStmt = %str(StartPosS:%dec(JOBI0900.LENCURCRS)) ;                                     
                                                                                                    
          else ;                                                                                    
                                                                                                    
           SQLCurName = '*NONE' ;                                                                   
           SQLStmt = '*NONE' ;                                                                      
                                                                                                    
          endIf ; 

一回実行されてそのあとずっとアイドルしているような場合、呼び出し元でアイドル時間などもあわせて取って記録して後でつきあわせるか、何か処理してしまうか、というのも考えどころですね。

コーディング例

     H*DFTACTGRP(*no)                                                                               
      *                                                                                             
     D RtvSQLInf       PR                                                                           
     D  JobName                      10a   CONST                                                    
     D  UserName                     10a   CONST                                                    
     D  JobNumber                     6a   CONST                                                    
     D  SQLStmt                   65535a   Options(*VarSize)                                        
     D  SQLStmtLen                   10u 0                                                          
      *                                                                                             
     D RtvSQLInf       PI                                                                           
     D  ParmJobName                  10a   CONST                                                    
     D  ParmUserName                 10a   CONST                                                    
     D  ParmJobNumber                 6a   CONST                                                    
     D  SQLStmt                   65535a   Options(*VarSize)                                        
     D  SQLStmtLen                   10u 0                                                          
      *                                                                                             
     D CrtUsrspcP      PR              *                                                            
     D  Name                         20a                                                            
      *                                                                                             
     D RtvJobSQL       PR                  EXTPGM('QUSRJOBI')                                       
     D  RcvVar                    65535a   Options(*VarSize)                                        
     D  RcvVarLen                    10i 0 Const                                                    
     D  FmtName                       8a   Const                                                    
     D  QualJobName                  26a   Const                                                    
     D  InternalJobID                16a   Const                                                    
     D  ErrorCode                          like(APIErr)                                             
     D  ResetPfrStat                  1a   Const                                                    
      *                                                                                             
     D JOBI0900        DS                  Qualified Based(usPtr)                                   
     D  NbrBytesRtn                  10i 0                                                          
     D  NbrBytesAvl                  10i 0                                                          
     D  JobName                      10a                                                            
     D  UsrName                      10a                                                            
     D  JobNbr                        6a                                                            
     D  InternalJobID                16a                                                            
     D  JobSts                       10a                                                            
     D  JobType                       1a                                                            
     D  JobSubType                    1a                                                            
     D  SvrMode                       1a                                                            
     D  rsvd                          1a                                                            
     D  OfsOpnCrs                    10i 0                                                          
     D  SizOpnCrs                    10i 0                                                          
     D  NbrOpnCrs                    10i 0                                                          
     D  OfsCurCrs                    10i 0                                                          
     D  LenCurCrs                    10i 0                                                          
     D  StsCurCrs                    10i 0                                                          
     D  CCSIDCurCrs                  10i 0                                                          
     D  RDBname                      18a                                                            
     D  SQLObj                       10a                                                            
     D  SQLLib                       10a                                                            
     D  SQLObjType                   10a                                                            
     D  rsvd2                         4a                                                            
     D  CumNbrFullOpn                20i 0                                                          
     D  CumNbrPsedOpn                20i 0                                                          
     D  OfsCurSQL                    10i 0                                                          
     D  LenCurSQL                    10i 0                                                          
      *                                                                                             
     D CursorInfo      DS                  Qualified Based(StartPosC)                               
     D   ObjName                     10a                                                            
     D   ObjLib                      10a                                                            
     D   ObjType                     10a                                                            
     D   SQLCurName                  18a                                                            
     D   SQLStmtname                 18a                                                            
      *                                                                                             
     D APIErr          DS                  Qualified                                                
     D  ErrSize                      10i 0 inz(%size(APIErr))                                       
     D  ErrLen                       10i 0 inz(0)                                                   
     D  ErrID                         7a                                                            
     D  rsvd                          1a                                                            
     D  ErrData                   32767a                                                            
      *                                                                                             
     D QualJobName     DS            26    Qualified                                                
     D  JobName                      10a                                                            
     D  UserName                     10a                                                            
     D  JobNumber                     6a                                                            
      *                                                                                             
     D pName           S             20a                                                            
     D usPtr           S               *                                                            
      *                                                                                             
     D RcvSize         S             10  0 INZ(16776704)                                            
      *                                                                                             
     D i               S              5  0                                                          
     D StartPosC       S               *                                                            
     D StartPosS       S               *                                                            
      *                                                                                             
     D HandleErr       PR                                                                           
      *                                                                                             
     D SQLCurName      S             18a                                                            
     D SQLStmtname     S             18a                                                            
      *                                                                                             
      /Free                                                                                         
          QualJobName.JobName = ParmJobName ;                                                   
          QualJobName.UserName = ParmUserName ;                                                 
          QualJobName.JobNumber = ParmJobNumber ;                                               
                                                                                                    
          pName =    'JOBI0900  QTEMP     ' ;                                                   
          usPtr = CrtUsrspcP  (pName ) ;                                                        
                                                                                                    
          RtvJobSQL( JOBI0900 :                                                                 
                      RcvSize :                                                                       
                   'JOBI0900' :                                                                    
                  QualJobName :                                                                   
                      *blanks :                                                                       
                       APIErr :                                                                        
                        '0' ) ;                                                                         
                                                                                                    
          If APIErr.ErrLEN <> 0 ;                                                                   
                                                                                                    
            HandleErr() ;                                                                            
                                                                                                    
          else ;                                                                                    
                                                                                                    
            If JOBI0900.NBROPNCRS > 0 ;                                                              
                                                                                                    
              StartPosC = %addr(JOBI0900) + (JOBI0900.OFSOPNCRS) ;                                     
                                                                                                    
              for i = 1 to %dec(JOBI0900.NBROPNCRS) ;                                                  
                 SQLCurName = CursorInfo.SQLCurName ;                                                  
                 SQLStmtname = CursorInfo.SQLStmtname ;                                                
                 StartPosC = StartPosC + %size(CursorInfo) ;                                           
              endfor ;                                                                                 
                                                                                                    
              StartPosS = %addr(JOBI0900) + (JOBI0900.OFSCURCRS) ;                                     
              SQLStmt = %str(StartPosS:%dec(JOBI0900.LENCURCRS)) ;                                     
                                                                                                    
            else ;                                                                                    
                                                                                                    
              SQLCurName = '*NONE' ;                                                                   
              SQLStmt = '*NONE' ;                                                                      
                                                                                                    
            endIf ;                                                                                   
                                                                                                    
            SQLStmt = %trimR(SQLStmt) ;                                                                      
            SQLStmtLen = %len(SQLStmt) ;                                                     
                                                                                                    
          endIf ;                                                                                   
                                                                                                    
          *inLR = *on ;                                                                             
          return ;                                                                                  
                                                                                                    
      /End-Free                                                                                     
      *                                                                                             
      *                                                                                             
     P HandleErr       B                                                                            
     D HandleErr       PI                                                                           
      *                                                                                             
      /Free                                                                                         
                                                                                                    
      /End-Free                                                                                     
      *                                                                                             
     P HandleErr       E                                                                            

ILE RPG での可変長の扱いかた」に書いてあるようなことに則って、ILE RPG の可変長フィールドの機能を活かして書き直したものが「ソケットごとの実行 SQL (可変長) の収集 (V5R4)」にあります。そちらも参照してみてください。

[Top Pageに戻る]

Ads by TOK2