Как узнать, какая ABL-программа сейчас работает у пользователя?
 
	
Иногда возникает ситуация, когда необходимо выяснить, какая программа работает у конкретного пользователя в данный момент времени. Особенно это актуально если некий процесс сильно загружает систему, и нужно выяснить почему. Обычный звонок пользователю, чтобы узнать что он запустил, вряд ли поможет, так как либо пользователь не совсем внятно ответит, либо его в это время просто может не быть на месте. Даже если он и укажет на пункт меню,  запущенная программа из этого меню в свою очередь может вызывать другие программы, о которых пользователь даже и не подозревает. Поэтому не стоит ему звонить и тратить своё время впустую. В этом случае вам поможет ABL Stack Trace. 
Начиная с версии 10.1С существует возможность передать определенный сигнал работающему OpenEdge процессу, чтобы он сгенерировал ABL Stack Trace и продолжил свою работу (на подобие C Stack Trace). Сигнал, который позволяет это сделать, называется SIGUSR1.  Синтаксис команды выглядит так: kill –USR1 <PID> 
Эта команда, в рабочем каталоге указанного процесса создаст файл с именем protrace.<PID>, содержащий информацию из стека. 
Как и для других подобных сигналов, необходимо обладать правами root, или находиться в той же группе, где и пользователь запустивший проблемный процесс.  
Таблица соответствия сигнала SIGUSR1 цифровому значению для разных операционных систем: 
  
    
      
        | Операционная система | 
        Цифровое значение сигнала | 
       
      
        | Linux | 
        10 | 
       
      
        | HP-UX | 
        16 | 
       
      
        | AIX | 
        30 | 
       
      
        | Solaris | 
        16 | 
       
      
        | UnixWare | 
         - | 
       
    
   
  
 
В каталоге $DLC/bin есть стандартный скрипт с именем proGetStack, который по сути просто выполняет команду kill –USR1. 
Стоит отметить, что этот сигнал может применяться только относительно ABL клиентов, включая AppServer`а и WebSpeed агентов, так как они запускают ABL код. Другие же процессы OpenEdge, такие как утилиты базы данных и процессы сервера не смогут сформировать ABL Stack Trace.  
Далее представлен небольшой скрипт, который можно использовать для определения запущенных ABL программ у первой десятки Progress процессов, которые в текущий момент наиболее загружают систему. Скрипт должен запускаться с правами root. Файлы protrace.<PID> берется из каталога /proc/<PID>/cwd/. Этот скрипт не претендует на идеальное решение, и приводится исключительно в демонстрационных целях. Перед его использованием на своих системах, пожалуйста, сначала протестируйте его на совместимость. У меня он работал под Linux 2.6.18. 
Скрипт abltop10.sh: #!/bin/bash
  
  
  
  
  
  
  
  
  
  
   #************************************************
  
  
  
  
  
  
  
  
  
  
   #abltop10.sh Created by Valeriy G. Bashkatov
  
  
  
  
  
  
  
  
  
  
   #************************************************
  
  
  
  
  
  
  
  
  
  
   #TOP 10 Progress-процессов с указанием текущих работающих ABL-программ
  
  
  
  
  
  
  
  
  
  
   #Запускать под root`ом!
  
  
  
  
  
  
  
  
  
  
   #************************************************
  
  
  
  
  
  
  
  
  
  
   PROGNAME=`/bin/basename $0`
  
  
  
  
  
  
  
  
  
  
   print_help()
  
  
  
  
  
  
  
  
  
  
   {
  
  
  
  
  
  
  
  
  
  
   printf "==================================================\n"
  
  
  
  
  
  
  
  
  
  
   printf "$PROGNAME - TOP 10 Progress-процессов с указанием текущих"
  
  
  
  
  
  
  
  
  
  
   printf "работающих ABL-программ\n"
  
  
  
  
  
  
  
  
  
  
   printf "Особенность: "
  
  
  
  
  
  
  
  
  
  
   printf "Запускать под root-ом, поскольку необходим доступ" 
  
  
  
  
  
  
  
  
  
  
   printf "к данным процесса (/proc/)\n"
    
    
    
    
    
    
    
    
    
    
     echo "==================================================="
    
    
    
    
    
    
    
    
    
    
     exit
    
    
    
    
    
    
    
    
    
    
     }
    
    
    
    
    
    
    
    
    
    
     
     [[ $1 = "-h" || $1 = "--help" ]] && print_help
    
    
    
    
    
    
    
    
    
    
     if [ -f ./top10.tmp ]
    
    
    
    
    
    
    
    
    
    
     then
    
    
    
    
    
    
    
    
    
    
        rm -f ./top10.tmp
    
    
    
    
    
    
    
    
    
    
     fi
    
    
    
    
    
    
    
    
    
    
     
     for f in `top -b -n 1 | sed -e "1,6d" | grep progres | head -11 | awk '{print $2","$1","$9}'`
    
    
    
    
    
    
    
    
    
    
     do
    
    
    
    
    
    
    
    
    
    
        echo $f >> ./top10.tmp
    
    
    
    
    
    
    
    
    
    
        fp=`echo $f|awk -F"," '{print $2}'`
    
    
    
    
    
    
    
    
    
    
        if [ -f /proc/$fp/cwd/protrace.$fp ]
    
    
    
    
    
    
    
    
    
    
        then
    
    
    
    
    
    
    
    
    
    
          #если по каким-то причинам protrace файл для этого процесса
    
    
    
    
    
    
    
    
    
    
          #уже существует - удалим его
    
    
    
    
    
    
    
    
    
    
          rm -f /proc/$fp/cwd/protrace.$fp
    
    
    
    
    
    
    
    
    
    
        fi
    
    
    
    
    
    
    
    
    
    
        kill -USR1 $fp
    
    
    
    
    
    
    
    
    
    
     done
    
    
    
    
    
    
    
    
    
    
     #дадим время для формирования protrace файлов после команды kill -USR1
    
    
    
    
    
    
    
    
    
    
     sleep 1.5 
    
    
    
    
    
    
    
    
    
    
     echo "---------------------------------------------------------------"
    
    
    
    
    
    
    
    
    
    
     printf "PID\t%-9s\t%-9s\tPROG\n" "USER" "CPU"
    
    
    
    
    
    
    
    
    
    
     echo "----------------------------------------- ---------------------"
    
    
    
    
    
    
    
    
    
    
     for f in `cat ./top10.tmp`
    
    
    
    
    
    
    
    
    
    
     do
    
    
    
    
    
    
    
    
    
    
         fp=`echo $f|awk -F"," '{print $2}'`
    
    
    
    
    
    
    
    
    
    
         if [ -f /proc/$fp/cwd/protrace.$fp  ]
    
    
    
    
    
    
    
    
    
    
         then
    
    
    
    
    
    
    
    
    
    
             fk=$f","`cat /proc/$fp/cwd/protrace.$fp | grep "\-\->"`
    
    
    
    
    
    
    
    
    
    
             vUSR=`echo $fk|awk -F"," '{print $1}'`
    
    
    
    
    
    
    
    
    
    
             vPID=`echo $fk|awk -F"," '{print $2}'`
    
    
    
    
    
    
    
    
    
    
             vCPU=`echo $fk|awk -F"," '{print $3}'` 
    
    
    
    
    
    
    
    
    
    
             vPRO=`echo $fk|awk -F"," '{print $4}'` 
    
    
    
    
    
    
    
    
    
    
             printf "%-6s\t%-8s\t%-6s\t$vPRO\n" "$vPID" "$vUSR" "$vCPU" 
    
    
    
    
    
    
    
    
    
    
             #Удалим protrace файл, чтобы не было "мусора"
    
    
    
    
    
    
    
    
    
    
             rm -f /proc/$fp/cwd/protrace.$fp
    
    
    
    
    
    
    
    
    
    
         fi
    
    
    
    
    
    
    
    
    
    
     done
    
    
    
    
    
    
    
    
    
    
     
     if [ -f ./top10.tmp ]
    
    
    
    
    
    
    
    
    
    
     then
    
    
    
    
    
    
    
    
    
    
          rm -f ./top10.tmp
    
    
    
    
    
    
    
    
    
    
     fi 
Результат будет выглядеть примерно  так :  
  # ./abltop10.sh
     
  --------------------------------------------------------------------- 
  PID     USER            CPU             PROG
---------------------------------------------------------------------
28315   valeriy         63.6    --> ./proUSR1 (./proUSR1.r) at line 2
27299   valeriy         0.0     --> adeedit/_proedit.p 
                                 (adeedit/_proedit.r) at line 12279
   
Скрипт можно использовать для сбора статистики по ABL программам, которые наиболее загружают систему. Например, чем чаще конкретная программа будет фигурировать в этой статистике, тем вероятнее, что ей стоит заняться более детально.  
Пример файла protrace для процесса 28315:  PROGRESS stack trace as of Thu Feb 25 13:15:57 2010
  
  
  
  
   Command line arguments are /usr/dlc102B/bin/_progres sports 
  
  
  
  
   
   Startup parameters:
  
  
  
  
   -pf /usr/dlc102B/startup.pf,-cpinternal 1251,-cpstream 1251,-cpcoll Russian,
  
  
  
  
   -cpcase Basic,-d dmy,-numsep 44,-numdec 46,(end .pf),-db sports
  
  
  
  
   #1   [0x8609f61] uttraceback+0x139  from /usr/dlc102B/bin/_progres
  
  
  
  
   #2   [0x860ca30] uttrace+0x14c  from /usr/dlc102B/bin/_progres
  
  
  
  
   #3   [0x80dfe83] drProTrace+0x43  from /usr/dlc102B/bin/_progres
  
  
  
  
   #4   [0x80df42d] drSigDo1+0x8f  from /usr/dlc102B/bin/_progres
  
  
  
  
   #5   [0x80df582] drSigDispatch+0xcf  from /usr/dlc102B/bin/_progres
  
  
  
  
   #6   [0xffffe500] _fini+0x805bf6c  from /lib/libm.so.6
  
  
  
  
   #7   [0x8494334] cxRowidNext+0x34e  from /usr/dlc102B/bin/_progres
  
  
  
  
   #8   [0x84d3f75] dsmCursorFindAndGet+0x40c  from /usr/dlc102B/bin/_progres
  
  
  
  
   #9   [0x84d3b58] dsmCursorFind+0x66  from /usr/dlc102B/bin/_progres
  
  
  
  
   #10  [0x855e61f] qrIxGet+0x195  from /usr/dlc102B/bin/_progres
  
  
  
  
   #11  [0x855f520] qrNext+0x16b  from /usr/dlc102B/bin/_progres
  
  
  
  
   #12  [0x80dd6ad] dbqry+0xb3  from /usr/dlc102B/bin/_progres
  
  
  
  
   #13  [0x8307e5a] proqry+0xd1  from /usr/dlc102B/bin/_progres
  
  
  
  
   #14  [0x83077d2] profnd+0x132  from /usr/dlc102B/bin/_progres
  
  
  
  
   #15  [0x8082298] fdfnd+0xc8  from /usr/dlc102B/bin/_progres
  
  
  
  
   #16  [0x835a44e] bfFindRow+0x2c2  from /usr/dlc102B/bin/_progres
  
  
  
  
   #17  [0x83ad4c8] rnbfnxtDoit+0x414  from /usr/dlc102B/bin/_progres
  
  
  
  
   #18  [0x83acf5c] rnbfnxtBody+0x393  from /usr/dlc102B/bin/_progres
  
  
  
  
   #19  [0x83acb6f] rnbfnxt+0x20e  from /usr/dlc102B/bin/_progres
  
  
  
  
   #20  [0x83b2a5f] rnexec_entry+0x27f  from /usr/dlc102B/bin/_progres
  
  
  
  
   #21  [0x83b3e50] rninterpret+0x2f  from /usr/dlc102B/bin/_progres
  
  
  
  
   #22  [0x8224e52] umeDispatchEvent+0xfd2  from /usr/dlc102B/bin/_progres
  
  
  
  
   #23  [0x85988fd] wvRunDispatcher+0xf3  from /usr/dlc102B/bin/_progres
  
  
  
  
   #24  [0x831f451] iodispatch+0xa5  from /usr/dlc102B/bin/_progres
  
  
  
  
   #25  [0x80c2d14] rnrq+0xd4  from /usr/dlc102B/bin/_progres
  
  
  
  
   #26  [0x8079717] main+0x419  from /usr/dlc102B/bin/_progres
  
  
  
  
   #27  [0x683e8c] __libc_start_main+0xdc  from /lib/libc.so.6
  
  
  
  
   
   ** ABL Stack Trace **
  
  
  
  
   
   -->./proUSR1 (./proUSR1.r) at line 2/home/valeriy/testdb/p56723_Untitled3.ped
  
  
  
  
        (/home/valeriy/testdb/p56723_Untitled3.ped) at line 1
  
  
  
  
        adecomm/_runcode.p (adecomm/_runcode.r) at line 665
  
  
  
  
        ExecuteRun adeedit/_proedit.p (adeedit/_proedit.r) at line 3613
  
  
  
  
        RunFile adeedit/_proedit.p (adeedit/_proedit.r) at line 10624
  
  
  
  
        USER-INTERFACE-TRIGGER adeedit/_proedit.p (adeedit/_proedit.r) 
  
  
  
  
        at line 1985 adeedit/_proedit.p (adeedit/_proedit.r) at line 12279
  
  
  
  
        _edit.p (/usr/dlc102B/tty/_edit.r) at line 408
  
  
  
  
   
   ** Persistent procedures/Classes **
  
  
  
  
  
  
Внимание!    Этот скрипт полностью работоспособен, но перед его использованием рекомендуется тщательно протестировать его работу в вашей операционной среде. 
    Код скрипта распространяется бесплатно на условиях "КАК ЕСТЬ" без каких-либо гарантий любого рода. 
    Все риски, возникающие от использования скрипта abltop10.sh, возлагаются на пользователя. 
	
  
 
 
		  |