
Как узнать, какая 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/. Этот скрипт не претендует на идеальное решение, и приводится исключительно в демонстрационных целях. Перед его использованием на своих системах, пожалуйста, сначала протестируйте его на совместимость.
Скрипт whowork.sh:
#!/bin/bash #****************************************************************************** #whowork.sh Created by Valeriy G. Bashkatov #****************************************************************************** #TOP 10 Progress-процессов с указанием текущих работающих ABL-программ #Запускать под root`ом! #****************************************************************************** PROGNAME=`/bin/basename $0` print_help() { printf "==============================================================\n" printf "$PROGNAME - TOP 10 Progress-процессов с указанием текущих работающих ABL-программ\n" printf "Особенность: " printf "Запускать под root-ом, поскольку необходим доступ к данным процесса (/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" rm -f /proc/$fp/cwd/protrace.$fp #Удалим protrace файл, чтобы не было "мусора" fi done if [ -f ./top10.tmp ] then rm -f ./top10.tmp fi
Результат его работы будет выглядеть примерно так:
-------------------------------------------------------------------------------------- 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 **
Метка:ABL(4GL), Мониторинг