ジョブが失敗したときに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スクリプトでemailコマンドレットを使用して、見つかったメッセージを送信します。

ここでアイデアを集めましたが、考えたのはほんの一部です。


3

前述のアイデアを経験しまし。それは良いことですが、より良いアイデアはショーンが言ったようなことをすることです。

5分ごとに実行され、ジョブの失敗についてMSDBテーブルをスキャンするジョブを作成しました。失敗した各ジョブについて、独自のIDを使用してSP spDBA_job_notificationを実行するため、SPはMSDB履歴ステップをスキャンしてエラーを検出し、すべてを電子メールで送信します。SPドキュメントから:「ストアドプロシージャは、ジョブIDを使用してmsdbエージェントテーブルを照会し、そのジョブの最新のエラーメッセージを取得します。」

したがって、すべてのジョブを単に変更するのではなく、すべてを実行する単一のジョブを作成する方が適切です;-)。

別のアイデアは、エラー/障害の場合にすべてのジョブをWindowsイベントビューアーに書き込み、拡張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

私はそれがSQL Server 2012の上で動作を確認することができます-私は、これは古いスレッドですけど、@Crazyイワンによって溶液を御馳走に動作します
マイケル・
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.