Как сделать так, чтобы SQL Server отправлял мне по электронной почте информацию об ошибке при сбое задания?

14

SQL Server позволяет настроить задание на отправку оповещений по электронной почте в случае сбоя. Это простой и эффективный способ контролировать вашу работу. Однако эти предупреждения не содержат никаких подробностей - только уведомление об успехе или сбое.

Если работа не удалась, вот как будет выглядеть типичное электронное письмо с предупреждением:

JOB RUN:        'DBA - Consistency Check Databases' was run on 8/14/2011 at 12:00:04 AM
DURATION:       0 hours, 0 minutes, 0 seconds
STATUS:         Failed
MESSAGES:       The job failed.  The Job was invoked by Schedule 2 (Nightly Before 
                Backup 12AM).  The last step to run was step 1 (Check Databases).

Чтобы определить причину сбоя, необходимо перейти к экземпляру в SQL Server Management Studio, найти задание и просмотреть его историю выполнения. В большой среде может быть больно постоянно делать это.

Идеальное электронное письмо с предупреждением должно включать в себя причину ошибки заранее и позволит вам сразу приступить к работе над решением.

Я знаком с этим решением этой проблемы. У кого-нибудь есть опыт с этим? Его недостатки:

  1. Вы должны добавить новый шаг к каждой вашей работе, и
  2. Вы должны молиться, чтобы никто не испортил процесс оповещения, spDBA_job_notification

Кто-нибудь придумал лучшее решение?

Ник Чаммас
источник

Ответы:

10

Что-то, что вы можете сделать, это просто мысль, выбрасывание идей ...

Создайте отдельное задание, которое периодически проверяет таблицу заданий в msdb, чтобы увидеть, не отображаются ли какие-либо задания как неудачные, что можно сделать с помощью хорошего запроса T-SQL . Затем вы можете зайти в таблицу sysjobsteps и посмотреть, установлен ли выходной журнал для задания. Попросите хранимую процедуру отправить электронное письмо с приложением этого файла. Вы сможете точно увидеть, что работа выполняла от начала до отказа, не касаясь сервера.

Затем мог бы также сценарий PowerShell проверить журнал событий на наличие ошибок. Это позволяет вам довольно неплохо отфильтровать, чтобы получить именно те типы сообщений, которые вы ищете. Вы можете настроить это как задание агента SQL для периодического запуска. Затем в сценарии PowerShell используйте командлет электронной почты, чтобы отправить сообщение, если оно найдет.

Здесь надуманные идеи, только некоторые, о которых я думал.


источник
3

У меня есть опыт работы с вышеупомянутой идеей . Это хорошо, но лучшей идеей было бы сделать что-то, как сказал Шон.

Мы сделали задачу, которая запускается каждые 5 минут и сканирует таблицы MSDB на предмет сбоев. Для каждого задания, в котором произошел сбой, мы запускали SP spDBA_job_notification с собственным идентификатором, поэтому SP будет сканировать шаги истории MSDB на наличие ошибок и отправлять их по электронной почте. Из документации SP: «Хранимая процедура использует идентификатор задания для запроса таблиц агента msdb для получения самого последнего сообщения об ошибке для этого задания».

Так что вместо того, чтобы просто менять каждую работу, лучше создать одну, которая делает все ;-).

Другая идея состоит в том, чтобы настроить все задания для записи в Windows Event Viewer в случае ошибок / сбоев и чтения оттуда с помощью расширенного proc xp_ReadErrorLog или автоматического инструмента, если он уже есть в вашей сети. Например, мы использовали HPOV для проверки любых системных проблем и могли настроить простое оповещение для всех ошибок средства просмотра событий (нет необходимости в каких-либо пользовательских заданиях или процедурах).

Мэриан
источник
2

Попробуйте и просто подключите свои переменные в соответствии с требованиями TSQL. Ключевым моментом здесь является поместить это в качестве самого последнего шага каждого отдельного задания агента SQL, но для каждого вышеприведенного шага задания необходимо переходить к СЛЕДУЮЩЕМУ ШАГУ, независимо от того, НЕ УКАЗАНО ли это или УСПЕХИ ... По большей части работает для меня просто отлично, но, пожалуйста, сообщайте о любых проблемах, с которыми вы столкнулись. Мы находимся на SQL Server 2008 R2, поэтому он используется там, где я сейчас его установил.

SELECT  step_name, message
FROM    msdb.dbo.sysjobhistory
WHERE   instance_id > COALESCE((SELECT MAX(instance_id) FROM msdb.dbo.sysjobhistory
                                WHERE job_id = $(ESCAPE_SQUOTE(JOBID)) AND step_id = 0), 0)
        AND job_id = $(ESCAPE_SQUOTE(JOBID))
        AND run_status <> 1 -- success

IF      @@ROWCOUNT <> 0
BEGIN
        RAISERROR('*** SQL Agent Job Prior Step Failure Occurred ***', 16, 1)

DECLARE @job_name NVARCHAR(256) = (SELECT name FROM msdb.dbo.sysjobs WHERE job_id = $(ESCAPE_SQUOTE(JOBID)))
DECLARE @email_profile NVARCHAR(256) = 'SQLServer Alerts'
DECLARE @emailrecipients NVARCHAR(500) = 'EmailAddr@email.com'
DECLARE @subject NVARCHAR(MAX) = 'SQL Server Agent Job Failure Report: ' + @@SERVERNAME
DECLARE @msgbodynontable NVARCHAR(MAX) = 'SQL Server Agent Job Failure Report For: "' + @job_name + '"'

--Dump report data to a temp table to be put into XML formatted HTML table to email out
SELECT sjh.[server]
    ,sj.NAME
    ,sjh.step_id
    ,sjh.[message]
    ,sjh.run_date
    ,sjh.run_time
INTO #TempJobFailRpt
FROM msdb..sysjobhistory sjh
INNER JOIN msdb..sysjobs sj ON (sj.job_id = sjh.job_id)
WHERE run_date = convert(INT, convert(VARCHAR(8), getdate(), 112))
    AND run_status != 4 -- Do not show status of 4 meaning in progress steps
    AND run_status != 1 -- Do not show status of 1 meaning success
    AND NAME = @job_name
ORDER BY run_date

IF EXISTS (
        SELECT *
        FROM #TempJobFailRpt
        )
BEGIN

-----Build report to HTML formatted email using FOR XML PATH
DECLARE @tableHTML NVARCHAR(MAX) = '
<html>
<body>
    <H1>' + @msgbodynontable + '</H1>
        <table border="1" style=
        "background-color: #C0C0C0; border-collapse: collapse">
        <caption style="font-weight: bold">
            ****** 
            Failure occurred in the SQL Agent job named: ''' + @job_name + ''' in at least one of the steps. 
            Below is the job failure history detail for ALL runs of this job today without needing to connect to SSMS to check.
            ******
        </caption>

<tr>
    <th style="width:25%; text-decoration: underline">SQL Instance</th>
    <th style="text-decoration: underline">Job Name</th>
    <th style="text-decoration: underline">Step</th>
    <th style="text-decoration: underline">Message Text</th>
    <th style="text-decoration: underline">Job Run Date</th>
    <th style="text-decoration: underline">Job Run Time</th>
</tr>' + CAST((
            SELECT td = [server]
                ,''
                ,td = NAME
                ,''
                ,td = step_id
                ,''
                ,td = [message]
                ,''
                ,td = run_date
                ,''
                ,td = run_time
            FROM #TempJobFailRpt a
            ORDER BY run_date
            FOR XML PATH('tr')
                ,TYPE
                ,ELEMENTS XSINIL
            ) AS NVARCHAR(MAX)) + '
    </table>
</body>
</html>';

EXEC msdb.dbo.sp_send_dbmail @profile_name = @email_profile
    ,@recipients = @emailrecipients
    ,@subject = @subject
    ,@body = @tableHTML
    ,@body_format = 'HTML'

--Drop Temp table
    DROP TABLE #TempJobFailRpt
END
ELSE
BEGIN
    PRINT '*** No Records Generated ***' 
    DROP TABLE #TempJobFailRpt
END
END

источник
Я знаю, что это старая ветка, но решение @Crazy Ivan прекрасно работает - могу подтвердить, что оно работает на SQL Server 2012
Майкл