Job Activity Monitor (PоSh)

by Alexey Knyazev 12. ноября 2009 22:59

Продолжая тему скриптов на PowerShell в помощь администраторам БД, предлагаю вариант Job Activity Monitor(Журнал выполнения заданий) на PowerShell.

Так как задания SQL Server Agent чаще всего выполняются по расписанию, то, скорее всего, вам потребуется просматривать историю их выполнения, например для того, чтобы убедиться, что они выполняются успешно и каких-либо проблем не возникает.

Год назад я публиковал вариант в виде Windows-приложения (http://www.itcommunity.ru/blogs/mssql/archive/2008/12/04/40235.aspx), теперь более лёгкий и гибкий скрипт.

#Строка коннекции к БД (в данном случае с Windows-авторизацией)
$ConnectionString="Data Source=(local);Trusted_Connection=yes;Integrated Security=SSPI;"

#Ниже СКЛ-авторизация (для примера)
#"$ConnectionString="Data Source=(local);User=UserName;password=MyPassword;"

[void][reflection.assembly]::LoadWithPartialName("System.Data.Sql")
[void][reflection.assembly]::LoadWithPartialName("System.Data.SqlClient")
[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")

#Основной запрос к Серверу БД, для получения списка Job`ов
$Query=
"SELECT * FROM
(SELECT top 1 with ties
t1.name, t1.originating_server,
last_run_outcome=case t1.last_run_outcome
when 0 then 'Failed'
when 1 then 'Succeeded'
when 3 then 'Canceled'
when 5 then 'Unknown'
end,
enabled=case t1.enabled when 0 then 'NO' else 'YES' end,
current_execution_status=case t1.current_execution_status
when 1 then 'Executing'
when 2 then 'Waiting For Thread'
when 3 then 'Between Retries'
when 4 then 'Idle'
when 5 then 'Suspended'
when 6 then '[obsolete]'
when 7 then 'PerformingCompletion'
end,
t2.last_executed_step_date,
t2.next_scheduled_run_date,
t1.job_id
FROM OPENROWSET('SQLOLEDB','$ConnectionString','EXEC msdb..sp_help_job') t1
INNER JOIN msdb.dbo.sysjobactivity t2
ON t1.job_id=t2.job_id
ORDER BY row_number() over (partition by t1.job_id order by t2.job_history_id desc)
) t ORDER BY name
"

#Создаём коннекцию
$SQLConnection = new-object System.Data.SqlClient.SqlConnection($ConnectionString)
#Идентификатор сессии, изначально=0
$jobid=0

#Функция для заполнения таблицы Job`ов
function GetJobs
{
$SQLConnection.Open()
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($Query, $SQLConnection)
$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)
$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet);
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
$reader=$SQLCommand.ExecuteReader()

$ListView.Items.Clear()
while ($reader.Read())
{
$item=new-object Windows.Forms.ListViewItem
$item.Text=$reader[0]
[void]$item.SubItems.Add($reader[1])
[void]$item.SubItems.Add($reader[2])
[void]$item.SubItems.Add($reader[3])
[void]$item.SubItems.Add($reader[4])
[void]$item.SubItems.Add($reader[5].ToString())
[void]$item.SubItems.Add($reader[6].ToString())
[void]$item.SubItems.Add($reader[7].ToString())

#Подкрашиваем красным строки у которых Job не выполнился
if ($reader[2] -eq "Failed")
{ $item.ForeColor="Red"}
[void]$ListView.Items.Add($item)
}

$SQLConnection.Close()
$ListView.Refresh()
#Время последнего считывания данных из БД потаймеру
$Time.Text="Last Update: $((Get-Date).ToString())"
}

#Функция для заполнения таблицы Step`ов
function GetHistory ($id)
{
$QueryHistory="SELECT
CASE run_date WHEN 0 THEN NULL ELSE
    convert(datetime,
            stuff(stuff(cast(run_date as nchar(8)), 7, 0, '-'), 5, 0, '-') + N' ' +
            stuff(stuff(substring(cast(1000000 + run_time as nchar(7)), 2, 6), 5, 0, ':'), 3, 0, ':'),
            120) END AS [RunDate],
step_id, step_name,
run_status=case run_status
when 0 then 'Failed'
when 1 then 'Succeeded'
when 2 then 'Retry (step only)'
when 3 then 'Canceled'
when 4 then 'In-progress message'
when 5 then 'Unknown'
end, message
FROM msdb.dbo.sysjobhistory
WHERE job_id='$id'
ORDER BY Instance_ID DESC"

$SQLConnection.Open()
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($QueryHistory, $SQLConnection)
$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)
$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet);
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
$reader=$SQLCommand.ExecuteReader()

while ($reader.Read())
{
$item=new-object Windows.Forms.ListViewItem
$item.Text=$reader[0].ToString()
[void]$item.SubItems.Add($reader[1])
[void]$item.SubItems.Add($reader[2])
[void]$item.SubItems.Add($reader[3])
[void]$item.SubItems.Add($reader[4])

#StepID=0 выделяем жирным
if ($reader[1] -eq "0")
{
$titleFont = new-object System.Drawing.Font($this.Font,
[System.Drawing.FontStyle]::Bold)
$item.Font=$titleFont
}
#Подкрашиваем красным строки у которых Шаг закончился неудачей
if ($reader[3] -eq "Failed")
{
$item.ForeColor="Red"
}
[void]$ListViewHistory.Items.Add($item)
}
$SQLConnection.Close()
$ListViewHistory.Refresh()
}

$timer = new-object Windows.Forms.Timer
#Значение (в мс), через которое автоматически обновляется таблица (в данном случае раз в 60 секунд)
$timer.Interval=60000

#Создаём форму
$form = new-object Windows.Forms.Form
$form.Text = "Job Activity Monitor"
$form.WindowState="Maximized"
$form.startposition = "CenterScreen"
$form.autosize = 0 

#add a PanelJobs
$PanelJobs = new-object Windows.Forms.Panel
$PanelJobs.Location = New-Object System.Drawing.Size(0,0)
$PanelJobs.Dock="Fill"

#add a PanelSteps
$PanelSteps = new-object Windows.Forms.Panel
$PanelSteps.Location = New-Object System.Drawing.Size(0,200)
$PanelSteps.Height=300
$PanelSteps.Dock="Bottom"

#add a Scroll
$Scroll = new-object Windows.Forms.Splitter
$Scroll.Location = New-Object System.Drawing.Size(0,190)
$Scroll.Dock="Bottom"

#add a ListViewHistory
$ListViewHistory = new-object Windows.Forms.ListView
$ListViewHistory.Location = New-Object System.Drawing.Size(0,0)
$ListViewHistory.Dock="Fill"
$ListViewHistory.FullRowSelect="True"
$ListViewHistory.View="Details"
$ListViewHistory.Columns.Add("Date", 140)
$ListViewHistory.Columns.Add("Step ID", 60)
$ListViewHistory.Columns.Add("Step Name", 120)
$ListViewHistory.Columns.Add("Status", 80)
$ListViewHistory.Columns.Add("Message", 500)

#add a ListViewJobs
$ListView = new-object Windows.Forms.ListView
$ListView.Location = New-Object System.Drawing.Size(0,0)
$ListView.Dock="Fill"
$ListView.FullRowSelect="True"
$ListView.View="Details"
$ListView.Columns.Add("Name", 150)
$ListView.Columns.Add("Server", 100)
$ListView.Columns.Add("Last_Run_Outcome", 120)
$ListView.Columns.Add("Enabled", 80)
$ListView.Columns.Add("Status", 100)
$ListView.Columns.Add("Last Run", 120)
$ListView.Columns.Add("Next Run", 120)

#Выводим Шаги у выбранного Job`a
$ListView.Add_ItemSelectionChanged({
$ListViewHistory.Items.Clear()
$jobid=$this.items[$_.itemindex].SubItems[7].Text
GetHistory $jobid
}
)

#add a statusStrip
$statusStrip = new-object System.Windows.Forms.StatusStrip
$Time = new-object System.Windows.Forms.ToolStripStatusLabel
$Time.Text="Last Update: "
[void]$statusStrip.Items.add($Time)

#По таймеру обновляем табличку
$timer.add_Tick({GetJobs})
$timer.Start()

$form.controls.add($scroll)
$form.controls.add($PanelJobs)
$PanelSteps.controls.add($ListViewHistory)
$form.controls.add($PanelSteps)
$PanelJobs.controls.add($ListView)
$form.controls.add($statusStrip)

GetJobs
$form.Add_Shown({$form.Activate()})
$form.ShowDialog()

Tags: , , ,

PowerShell | SQL Server

Добавить комментарий

  Country flag

biuquote
  • Комментарий
  • Предпросмотр
Loading