Как узнать, какая 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, возлагаются на пользователя.
|