Comment puis-je demander à SQL Server de m'envoyer par e-mail les détails de l'erreur lorsqu'un travail échoue?


14

SQL Server vous permet de configurer un travail pour envoyer des alertes par e-mail en cas d'échec. Il s'agit d'un moyen simple et efficace de surveiller vos travaux. Cependant, ces alertes n'incluent aucun détail - juste un avis de réussite ou d'échec.

Si un travail échoue, voici à quoi ressemblera un e-mail d'alerte typique:

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

Pour déterminer la cause de l'échec, vous devez accéder à l'instance dans SQL Server Management Studio, rechercher le travail et afficher son historique d'exécution. Dans un grand environnement, il peut être pénible de devoir le faire constamment.

L'e-mail d'alerte idéal comprendrait la raison de l'échec à l'avance et vous permettrait de travailler directement sur la solution.

Je connais cette solution à ce problème. Quelqu'un en a-t-il une expérience? Ses inconvénients sont:

  1. vous devez ajouter une nouvelle étape à chaque travail que vous avez, et
  2. vous devez prier pour que personne ne gâche le processus d'alerte, spDBA_job_notification

Quelqu'un a-t-il trouvé une meilleure solution?

Réponses:


10

Quelque chose que vous pourriez faire, c'est juste une pensée, jeter des idées ...

Créez un travail unique qui vérifie périodiquement la table des travaux dans msdb pour voir si des travaux apparaissent comme ayant échoué, ce qui peut être fait avec une bonne requête T-SQL . Ensuite, vous pouvez aller dans la table sysjobsteps et voir si un journal de sortie est défini pour le travail. Demandez à une procédure stockée d'envoyer un e-mail en y joignant ce fichier. Vous pourrez voir exactement ce que le travail a fait du début à l'échec sans avoir à toucher le serveur.

Le script PowerShell pourrait également vérifier les erreurs dans le journal des événements. Il vous permet de filtrer assez bien pour obtenir exactement les types de messages que vous recherchez. Vous pouvez définir cela comme un travail de l'Agent SQL pour qu'il s'exécute périodiquement. Ensuite, dans le script PowerShell, utilisez l'applet de commande e-mail pour envoyer le message s'il en trouve un.

Des idées farfelues ici, juste quelques-unes auxquelles j'ai pensé.


3

J'ai de l'expérience avec l'idée susmentionnée . C'est bien, mais une meilleure idée serait de faire quelque chose comme Shawn l'a dit.

Ce que nous avons fait était de faire un travail qui s'exécute toutes les 5 minutes et analyse les tables MSDB sur les échecs de travail. Pour chaque travail qui a échoué, nous exécuterions le SP spDBA_job_notification avec son propre ID, donc le SP analysera les étapes de l'historique MSDB pour les erreurs et les enverra par e-mail. Dans la documentation du SP: "La procédure stockée utilise l'ID de travail pour interroger les tables d'agent msdb pour le message d'erreur le plus récent pour ce travail."

Donc, au lieu de simplement changer chaque travail, mieux vaut en créer un seul qui fait tout ;-).

Une autre idée est de définir tous les travaux pour écrire dans l'Observateur d'événements Windows en cas d'erreurs / échecs et de lire à partir de là avec proc xp_ReadErrorLog étendu ou un outil automatique, si vous l'avez déjà dans votre réseau. Par exemple, nous avons utilisé HPOV pour vérifier tous les problèmes du système et pourrions configurer une alerte simple pour toutes les erreurs de l'observateur d'événements (pas besoin de tâche ou de procédure personnalisée).


2

Essayez ceci et branchez simplement vos variables selon les besoins dans TSQL. La clé ici est de mettre cela comme la toute dernière étape de chaque travail d'agent SQL individuel, mais chaque étape de travail au-dessus doit passer à l'ÉTAPE SUIVANTE, que ce soit ÉCHEC ou SUCCÈS ... Fonctionne très bien pour moi pour la plupart, mais s'il vous plaît signalez tous les problèmes que vous rencontrez. Nous sommes sur SQL Server 2008 R2, c'est donc là qu'il est utilisé là où je l'ai configuré actuellement.

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

Je sais que c'est un vieux fil, mais la solution de @Crazy Ivan fonctionne un régal - je peux confirmer que cela fonctionne sur SQL Server 2012
Michael
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.