вторник, июля 24, 2007

job activity monitor своими руками

это первый пост в моем блоге...не знаю, не хотелось вот так просто написать что-то вроде "тест", поэтому постараюсь написать чтонить полезное...на мой взгляд:)

по ходу своей деятельности в рамках работы приходится постоянно заниматься разработкой хранимых процедур для mssql 2000, написанием различного рода скриптов по обработке данных, и, что самое рутинное для меня, проверять работоспособность системы...точнее, систем, причем каждое утро, а по понедельникам и за последние дни, на что убивается уйма времени, сил и нервов...
как один из этапов проверки, что касается моего участка сбора данных, подготовки отчетов, трекинга, парсинга (красивое слово) заключается в проверке job-ов на куче серверов, т.е. нужно точно сказать, что такой-то job точно работает, такой то упал, причем если падал, то почему, по какой причине...
для этих целей обычно приходится запускать окно job activity monitor, причем для каждого инстанса ms sql server, итого в taskbar висит иногда порядка 15 окон...затем я смотрю, чтобы все job-ы работали - для этого просто обращаю внимание на поле status - но данное поле, даже если и говорит что successfull, не говорит мне о том, а были ли проблемы с рассматриваемым job-ом, поэтому приходится лезть дополнительно еще и в историю выполнения...еще + порядка 15 окон, и хорошо если нужно проверить один job на каждой системе, их тоже порядка 20-ти...надеюсь, представляете рутинность :)...
ну да ладно, солдаты трудностей не боятся, вроде как справлялся, но эти проверки надоели до боли в почках, поэтому решил облегчить себе задачу, запуская на каждой из систем следующий скрипт:





select isnull(SM.description, '') sysmessages_description,
case
when SJ.enabled = 1 then 'yes'
else 'no'
end enabled,
SJ.name,
SJH.step_id,
SJH.step_name,
SJH.sql_message_id,
SJH.sql_severity,
SJH.message,
case
when SJH.run_status = 0 then 'failed'
when SJH.run_status = 2 then 'retry'
when SJH.run_status = 3 then 'canceled'
when SJH.run_status = 3 then 'in progress'
else 'unknown'
end run_status,
cast(convert(varchar(10), SJH.run_date, 21) as datetime) run_date,
substring(str(1000000 + SJH.run_time, 7), 2, 6) run_time,
SJH.run_duration,
SJS.job_id, SJS.step_id, SJS.step_name, SJS.database_name,
cast(convert(varchar(10), SJS.last_run_date, 21) as datetime) last_run_date,
substring(str(1000000 + SJS.last_run_time, 7), 2, 6) last_run_time,
SJS.last_run_duration,
case
when run_date = last_run_date
and cast(convert(varchar(10), SJH.run_date, 21) as datetime) = cast(convert(varchar(10), getdate(), 21) as datetime) then 1
else 0
end alert_flag
from msdb..sysjobs SJ (nolock)
join msdb..sysjobsteps SJS (nolock) on SJS.job_id = SJ.job_id
join msdb..sysjobhistory SJH (nolock) on SJH.job_id = SJ.job_id and SJH.step_id = SJS.step_id
left join master..sysmessages SM (nolock) on SM.error = SJH.sql_message_id
where SJH.run_status <> 1
and SJS.last_run_date > replace(replace(replace(convert(varchar(10), dateadd(dd, -3, getdate()), 21), '-', ''), '/', ''), '.', '')
and SJH.run_date > replace(replace(replace(convert(varchar(10), dateadd(dd, -3, getdate()), 21), '-', ''), '/', ''), '.', '')
and SM.msglangid = 1033 -- <-- only 2005
order by SJH.run_date, SJ.name, SJS.step_id




идея такова, я хочу увидеть только список упавших по какой-либо причине job-ов, причем рассматриваю период два дня назад (прихожу в понеделник, хочу видеть что творилось в выходные) - для этого джойню sysjobs и sysjobhistory таблицы, причем только для того случая, где sysjobhistory.run_status <> 1 и только за последние два дня...в полученный рекордсет дополнительно вытаскиваю last_run_date самого job и его состояние в текущий момент, а также run_date упавших записей из истории...т.е., если run_date и last_run_date у меня равны и равны getdate(), то job продолжает падать до сих пор, если нет, его состояние нормализовалось, но вижу, что он падал в предыдущие два дня...(наверно, сумбурно получилось, но будет нагляднее на сриншоте, приложенном внизу)

Таким образом, я избавился от лишних просмотров истории, однако, осталась проблема дополнительных просмотров всех остальных систем..Сначала хотел прописать с какого-нить сервера linked_server-а ко всем остальным и запустить скрипт циклом (в принципе нормальное решение) - но потом я вспомнил, что все-таки я какникак девелопер, написал для себя небольшую утилиту, сриншот которой и прикладываю:



В конфиге утилиты прописал connection strings ко всем серверам, указанный скрипт запускаю через sqlcommand ко всем серверам паралельно, тупо получаю datatables от каждой системы, мержу их в один и показываю в виде дерева через devexpress datagrid, красным подсвечиваю те записи, у которых last_run_date == run_date///

вообщем, получилось весьма неплохо, картинку получаю мгновенно по всем серверам и вижу практически общее состояние всех систем одним репортом...на что стоит обратить внимание, на что уже нет...

ps: в запросе был дополнительный join с sysmessages - объясню для чего... если в процессе работы job вываливалась куча ворнингов, скажем, на создание таблиц с длиной строки, прерышающей лимитное, sysjobhistory показывает все эти ворнинги вместо реального сообщения об ошибке, просто забивая и не оставляя места под последнее критическое сообщение...поэтому приходится брать sql_message_id (собственно id сообщения, которое было критическим в момент падения job) и вытаскивать по нему реальное сообщение об ошибке из sysmessages///

pps: по запросу программа высылается всем желающим, сейчас оформляю ее в нормальный gui, так что велкам...

ppps: мысль -> не реклама, а лень...двигатель прогресса

4 комментария:

V комментирует...

Здравствуйте, большое спасибо за скрипт. Нашел в гугле по sysjobhistory: ссылка на ваш блог на второй странице поиска :)

Unknown комментирует...

спасибо за комментарий
рад что помог

Анонимный комментирует...

Здравствуйте, тоже столкнулся с такой проблемой. Огромное спасибо за скрипт. Только устроился на новую работу а тут порядка 30 серверов только SQL. Буду очень признателен если вам не составит труда прислать вашу утилиту на malegik_z@mail.ru.
С уважением Олег.

Анонимный комментирует...

Добрый вечер, искал программу JAMS Sheduler и попал на вашу страницу. Поделитесь Вашей утилитой проверки джобов, если возможно? Буду очень признателен.
С уважением Арман. ninja475@gmail.com