alerta cuando falla cualquier trabajo en una categoría de trabajo


11

¿Es posible configurar una alerta en SQL Server 2008 que envíe un correo electrónico cada vez que falle un trabajo en una categoría específica?

Me pregunto porque me gustaría configurar un correo electrónico cada vez que falle una suscripción de SSRS, y todas estas suscripciones son trabajos en la categoría Servidor de informes .

EDITAR : resulta que cuando falla una suscripción SSRS, el trabajo en sí no falla, por lo que mi pregunta no se aplicará al uso de monitoreo de suscripción SSRS. Sin embargo, me gustaría saber para otros trabajos que ejecutamos en nuestro entorno.


¿Un paso falla al menos? Mi respuesta a continuación analiza los trabajos en la categoría 'Servidor de informes', pero si solo desea todos los trabajos, puede eliminar toda esa AND EXISTSparte del INSERT/SELECT. Y probablemente cambie el nombre ReportServerJob_FailQueuea algo más genérico. :-)
Aaron Bertrand

Desafortunadamente, ningún paso falla, ¡pero estoy seguro de que puedo encontrar algún otro mecanismo de monitoreo!
JHFB

Respuestas:


10

Puede crear un trabajo que compruebe la tabla msdb.dbo.sysjobhistory cada minuto (o con la frecuencia que desee). Es posible que desee implementar una tabla de cola para que solo envíe una vez el mensaje de una falla de instancia única.

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

Entonces, su código, que puede programar en un trabajo, se convierte en:

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

Ahora supongo que desea enviar un correo electrónico individual para cada falla, por lo que esto podría ser parte del trabajo también (o parte de un trabajo diferente, aunque eso no es necesariamente sabio):

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;

También hay algunas otras opciones:

  • tire de sysjobhistory.message
  • mira los pasos individuales que fallaron
  • solo envíe un mensaje para cualquier trabajo una vez en n minutos / horas, incluso si hay varias fallas
  • envíe un solo correo electrónico con una lista de todos los trabajos que han fallado, en lugar de un correo electrónico por cada falla
  • es posible que desee incluir run_date y run_time en el mensaje, ya que es posible que el correo electrónico no se envíe o reciba lo suficientemente rápido como para ser una medida precisa de cuándo el trabajo realmente falló (no lo incluí aquí debido a sus horribles opciones de tipo de datos hacer que formatear esas cosas sea una PITA real)
  • probablemente querrá limpiar las filas antiguas después de un tiempo, por lo que también puede desearse un comando de purga

Si el Correo electrónico de base de datos no está configurado, consulte este tutorial .

También puede usar herramientas de terceros (por ejemplo, SQL Sentry Event Manager ) que simplificarán mucho esto. Revelación completa: trabajo para SQL Sentry.


0

Según su edición, esto sería solo una extensión de la respuesta de Aaron, con respecto a las fallas de suscripción SSRS (no solo el trabajo del Agente SQL). Sugeriría simplemente agregar un paso al trabajo de supervisión del trabajo, o podría hacer esto como un trabajo separado por completo.

Para obtener el estado de suscripción, simplemente verifique la ReportServer.dbo.ExecutionLog3 vista . La Statuscolumna mostrará cualquier cosa menos rsSuccessfallas. Solo filtra por RequestType = 'Subscription'. Deberá incluir alguna verificación de tiempo, para que no verifique todos los registros cada vez. Si ejecuta el trabajo cada 15 minutos, solo verifique TimeStartlos últimos 15 minutos.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.