alerte en cas d'échec d'un travail dans une catégorie d'emploi


11

Est-il possible de configurer une alerte dans SQL Server 2008 qui enverra un e-mail chaque fois qu'un travail dans une catégorie spécifique échoue?

Je me le demande parce que je voudrais configurer un e-mail chaque fois qu'un abonnement SSRS échoue - et tous ces abonnements sont des emplois dans la catégorie Report Server .

EDIT - il s'avère que lorsqu'un abonnement SSRS échoue, le travail lui - même n'échoue pas , donc ma question ne s'appliquera pas à l'utilisation de la surveillance des abonnements SSRS. Cependant, je voudrais toujours savoir pour d'autres emplois que nous exécutons dans notre environnement


Une étape échoue-t-elle au moins? Ma réponse ci-dessous examine les emplois dans la catégorie «Report Server», mais si vous voulez simplement tous les emplois, vous pouvez supprimer cette AND EXISTSpartie entière du INSERT/SELECT. Et probablement changer le nom ReportServerJob_FailQueueen quelque chose de plus générique. :-)
Aaron Bertrand

Malheureusement, aucune étape n'échoue - mais je suis convaincu que je peux trouver un autre mécanisme de surveillance!
JHFB

Réponses:


10

Vous pouvez créer un travail qui vérifie la table msdb.dbo.sysjobhistory toutes les minutes (ou à la fréquence souhaitée). Vous souhaiterez peut-être implémenter une table de files d'attente afin de n'envoyer le message pour une seule défaillance d'instance qu'une seule fois.

USE msdb;
GO

CREATE TABLE dbo.ReportServerJob_FailQueue
(
  job_id UNIQUEIDENTIFIER,
  run_date INT,
  run_time INT, -- horrible schema, just matching sysjobhistory
  sql_message_id INT,
  sent BIT NOT NULL DEFAULT 0,
  PRIMARY KEY (job_id, run_date, run_time)
);

Ainsi, votre code, que vous pouvez planifier dans un travail, devient:

INSERT dbo.ReportServerJob_FailQueue
  (job_id, run_date, run_time, sql_message_id)
SELECT job_id, run_date, run_time, sql_message_id
FROM msdb.dbo.sysjobhistory AS h
WHERE step_id = 0 
AND run_status = 0
AND EXISTS 
(
  SELECT 1 FROM msdb.dbo.sysjobs AS j
    INNER JOIN msdb.dbo.syscategories AS c
    ON j.category_id = c.category_id
    WHERE j.job_id = h.job_id
   AND c.name = 'Report Server'
)
AND NOT EXISTS 
(
  SELECT 1 FROM dbo.ReportServerJob_FailQueue
    WHERE job_id = h.job_id
    AND run_date = h.run_date
    AND run_time = h.run_time
);

Maintenant, je suppose que vous voulez envoyer un e-mail individuel pour chaque échec, donc cela pourrait également faire partie du travail (ou faire partie d'un travail différent, bien que ce ne soit pas nécessairement judicieux):

DECLARE 
  @subject NVARCHAR(4000),
  @body NVARCHAR(4000),
  @name SYSNAME,
  @id UNIQUEIDENTIFIER,
  @date INT,
  @time INT,
  @msg INT;

DECLARE c CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR SELECT q.job_id, q.run_date, q.run_time, q.sql_message_id, j.name
  FROM dbo.ReportServerJob_FailQueue AS q
  INNER JOIN msdb.dbo.sysjobs AS j
  ON q.job_id = j.job_id
  WHERE q.sent = 0;

OPEN c;

FETCH NEXT FROM c INTO @id, @date, @time, @msg, @name;

WHILE @@FETCH_STATUS = 0
BEGIN

  SET @subject = 'Report Server job ' + @name + ' failed.';
  SET @body = 'Error number: ' + RTRIM(@msg);

  BEGIN TRY
    EXEC msdb.dbo.sp_send_dbmail 
      @profile_name = 'default',     -- you may need to change this
      @recipients   = 'foo@bar.com', -- you will need to change this
      @subject      = @subject,
      @body         = @body;

    UPDATE dbo.ReportServerJob_FailQueue
      SET sent = 1 
      WHERE job_id = @id
      AND run_date = @date
      AND run_time = @time;
  END TRY
  BEGIN CATCH
    PRINT 'Will have to try that one again later.';
  END

  FETCH NEXT FROM c INTO @id, @date, @time, @msg, @name;
END

CLOSE c; DEALLOCATE c;

Il existe également d'autres options:

  • tirer dans sysjobhistory.message
  • regarder les étapes individuelles qui ont échoué
  • n'envoyez un message pour n'importe quel travail qu'une fois en n minutes / heures même s'il y a plusieurs échecs
  • envoyer un seul e-mail avec une liste de toutes les tâches qui ont échoué, au lieu d'un e-mail pour chaque échec
  • vous voudrez peut-être inclure les run_date et run_time dans le message, car l'e-mail peut ne pas être envoyé ou reçu assez rapidement pour être une mesure précise du moment où le travail a réellement échoué (je ne l'ai pas inclus ici car leurs choix de type de données horribles faire un formatage qui remplit un PITA royal)
  • vous voudrez probablement nettoyer les anciennes lignes après un certain temps, donc une commande de purge peut également être souhaitée

Si la messagerie de base de données n'est pas déjà configurée, consultez ce didacticiel .

Vous pouvez également utiliser des outils tiers (par exemple, SQL Sentry Event Manager ) qui simplifieront la tâche. Divulgation complète: je travaille pour SQL Sentry.


0

Sur la base de votre modification, cela ne serait qu'une extension de la réponse d'Aaron, concernant les échecs d'abonnement SSRS eux-mêmes (pas seulement le travail de l'Agent SQL). Je suggérerais simplement d'ajouter une étape au travail de surveillance des travaux, ou vous pourriez le faire en tant que travail distinct.

Pour obtenir le statut d'abonnement, il vous suffit de vérifier la ReportServer.dbo.ExecutionLog3 vue . La Statuscolonne affichera tout sauf rsSuccessen cas d'échecs. Il suffit de filtrer pour RequestType = 'Subscription'. Vous souhaiterez inclure une vérification de l'heure, de sorte que vous ne vérifiez pas tous les enregistrements à chaque fois. Si vous exécutez le travail toutes les 15 minutes, recherchez simplement TimeStartles 15 dernières minutes.

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.