ジョブカテゴリのいずれかのジョブが失敗したときにアラート


11

SQL Server 2008で、特定のカテゴリのジョブが失敗したときに電子メールを送信するアラートを設定することはできますか?

SSRSサブスクリプションが失敗するたびに電子メールをセットアップしたいと思っています。これらのサブスクリプションはすべて、カテゴリReport Serverのジョブです。

編集 -SSRSサブスクリプションが失敗しても、ジョブ自体失敗しないことが判明したため、私の質問はSSRSサブスクリプションの監視の使用には適用されません。しかし、私は私たちの環境で実行している他の仕事についてまだ知りたいです


ステップは少なくとも失敗しますか?以下の私の答えは、カテゴリ「レポートサーバー」のジョブを調べていますが、すべてのジョブが必要な場合は、のそのAND EXISTS部分全体を削除できますINSERT/SELECT。そしておそらく名前ReportServerJob_FailQueueをもっと一般的なものに変更します。:-)
アーロンベルトラン

残念ながら、失敗するステップはありません-しかし、他の監視メカニズムを思い付くことができると確信しています!
JHFB、

回答:


10

msdb.dbo.sysjobhistoryテーブルを毎分(または頻繁に)確認するジョブを作成できます。キューテーブルを実装して、単一インスタンスの障害に関するメッセージを1回だけ送信することができます。

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

したがって、ジョブでスケジュールできるコードは次のようになります。

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

ここで、失敗ごとに個別の電子メールを送信することを想定しているため、これもジョブの一部(または別のジョブの一部ですが、必ずしも賢明ではありません)になる可能性があります。

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;

他にもいくつかのオプションがあります:

  • sysjobhistory.messageを取り込む
  • 失敗した個々のステップを確認する
  • 複数の障害がある場合でも、ジョブのメッセージをn分/時間に1回だけ送信する
  • 失敗ごとの電子メールではなく、失敗したすべてのジョブのリストを含む単一の電子メールを送信する
  • run_dateとrun_timeをメッセージに含めると、ジョブが実際にいつ失敗したかを正確に測定するのに十分な速さで電子メールを送受信できない可能性があります(データタイプの選択がひどいため、ここには含めませんでした)ロイヤルPITAを構成するフォーマットを作成する)
  • おそらくしばらくしてから古い行をクリーンアップする必要があるので、パージコマンドも必要になる場合があります

データベースメールがまだ設定されていない場合は、このチュートリアルを参照してください

また、これを簡単にするサードパーティのツール(SQL Sentry Event Managerなど)を使用することもできます。完全な開示:私はSQL Sentryで働いています。


0

あなたの編集に基づくと、これはSSRSサブスクリプションの失敗自体(SQLエージェントジョブだけでなく)に関するAaronの回答の拡張にすぎません。ジョブモニタリングジョブにステップを追加するか、まったく別のジョブとして追加することをお勧めします。

サブスクリプションのステータスを取得するには、ReportServer.dbo.ExecutionLog3 ビューを確認するだけです。Status列には何も表示されますが、rsSuccess故障で。フィルターするだけですRequestType = 'Subscription'。時間チェックを含めたいので、毎回すべてのレコードをチェックする必要はありません。15分ごとにジョブを実行する場合TimeStartは、過去15分を確認してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.