
Как узнать, какая 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), Мониторинг


