Wie kann ich mir von SQL Server die Fehlerdetails per E-Mail zusenden lassen, wenn ein Auftrag fehlschlägt?

14

Mit SQL Server können Sie einen Auftrag so konfigurieren, dass bei einem Fehler E-Mail-Benachrichtigungen gesendet werden. Dies ist eine einfache und effektive Möglichkeit, Ihre Jobs zu überwachen. Diese Warnungen enthalten jedoch keine Details - lediglich eine Erfolgs- oder eine Fehlerbenachrichtigung.

Wenn ein Auftrag fehlschlägt, sieht eine typische Benachrichtigungs-E-Mail folgendermaßen aus:

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).

Um die Fehlerursache zu ermitteln, müssen Sie in SQL Server Management Studio zur Instanz navigieren, den Job suchen und den Ausführungsverlauf anzeigen. In einer großen Umgebung kann es schmerzhaft sein, dies ständig tun zu müssen.

Die ideale Benachrichtigungs-E-Mail würde den Fehlergrund im Voraus enthalten und Sie können direkt an der Lösung arbeiten.

Ich bin mit dieser Lösung für dieses Problem vertraut . Hat jemand irgendwelche Erfahrungen damit? Ihre Nachteile sind:

  1. Sie müssen für jeden Job, den Sie haben, einen neuen Schritt hinzufügen und
  2. du musst beten, dass niemand den Alarmprozess durcheinander bringt, spDBA_job_notification

Hat jemand eine bessere Lösung gefunden?

Nick Chammas
quelle

Antworten:

10

Etwas, das Sie vielleicht tun, ist nur ein Gedanke, der Ideen aus dem Weg wirft ...

Erstellen Sie einen einzelnen Job, der die Jobtabelle in msdb regelmäßig überprüft, um festzustellen, ob Jobs als fehlgeschlagen angezeigt werden. Dies kann mit einer guten T-SQL-Abfrage erfolgen . Dann können Sie in die sysjobsteps-Tabelle gehen und sehen, ob ein Ausgabeprotokoll für den Job festgelegt ist. Lassen Sie eine gespeicherte Prozedur eine E-Mail senden, die diese Datei anhängt. Sie können genau sehen, was der Job von Anfang an getan hat, ohne den Server berühren zu müssen.

Dann könnte auch das PowerShell-Skript das Ereignisprotokoll auf Fehler überprüfen. Sie können ein gutes Stück herausfiltern, um genau die Nachrichtentypen zu finden, nach denen Sie suchen. Sie können dies als SQL Agent-Job einrichten, der regelmäßig ausgeführt wird. Verwenden Sie dann im PowerShell-Skript das E-Mail-Cmdlet, um die Nachricht zu senden, falls eine gefunden wird.

Weit hergeholte Ideen hier, nur einige, über die ich nachgedacht habe.


quelle
3

Ich habe Erfahrung mit der oben genannten Idee . Es ist gut, aber eine bessere Idee wäre, so etwas wie Shawn zu tun.

Wir haben einen Job erstellt, der alle 5 Minuten ausgeführt wird und MSDB-Tabellen auf Jobfehler überprüft. Für jeden Job, bei dem ein Fehler aufgetreten ist, haben wir den SP spDBA_job_notification mit seiner eigenen ID ausgeführt, sodass der SP die MSDB-Verlaufsschritte auf Fehler überprüft und alle per E-Mail versendet. Aus der SP-Dokumentation: "Die gespeicherte Prozedur verwendet die Job-ID, um die msdb-Agententabellen nach der neuesten Fehlermeldung für diesen Job abzufragen."

Also anstatt einfach jeden Job zu ändern, solltest du lieber einen einzigen erstellen, der alles kann ;-).

Eine andere Idee ist, alle Jobs so einzustellen, dass sie im Falle von Fehlern / Ausfällen in die Windows-Ereignisanzeige geschrieben werden und von dort mit dem erweiterten Befehl xp_ReadErrorLog oder einem automatischen Tool gelesen werden , wenn Sie dies bereits in Ihrem Netzwerk haben. Beispielsweise haben wir HPOV zum Überprüfen von Systemproblemen verwendet und konnten eine einfache Warnung für alle Fehler in der Ereignisanzeige konfigurieren (keine benutzerdefinierten Jobs oder Prozeduren erforderlich).

Marian
quelle
2

Probieren Sie es aus und fügen Sie Ihre Variablen nach Bedarf in TSQL ein. Der Schlüssel hier ist, dies als den allerletzten Schritt jedes einzelnen SQL-Agentenjobs zu definieren, aber jeder Jobschritt darüber muss zum NÄCHSTEN SCHRITT gehen, ob es sich um FEHLER oder ERFOLG handelt ... Funktioniert für mich größtenteils in Ordnung, aber bitte Melden Sie alle Probleme, auf die Sie stoßen. Wir arbeiten mit SQL Server 2008 R2, daher wird dies dort verwendet, wo ich es gerade eingerichtet habe.

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) = '[email protected]'
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

quelle
Ich weiß, dass dies ein alter Thread ist, aber die Lösung von @Crazy Ivan ist eine Wohltat - ich kann bestätigen, dass sie auf SQL Server 2012 funktioniert
Michael,