USE [HCITools] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[mon].[Check_Critical_Job]') AND type in (N'P', N'PC')) DROP PROCEDURE [mon].[Check_Critical_Job] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [mon].[Check_Critical_Job] AS /*============================================================================= Explication du traitement realise par la SP ------------------------------------------- La SP va vérifier la bonne execution des jobs critiques et envoyer un SMS de rapport aux personnes de piquet Contexte d'utilisation ---------------------- Appelé depuis le job D92210 - Check Critical Jobs Creation : 26.02.19 / FLA Modifications : 13.03.19 / FLA : utilisation de la table DBA_Mailing_list plutôt que SMSOperator changement du schema des objets dans [mon] 15.03.19 / FLA : changement du format d'envoi de mail 18.03.19 / FLA : centralisation du calendrier + mailing list opérateur de piquet ajout du type de calendrier (1=Critical Jobs) 24.05.19 / FLA : add WITH (NOLOCK) to avoid locking system table 27.06.19 / FLA : deplacement du status dans l'object du mail 02.09.19 / FLA : ajout check état des steps du job même si job success 12.09.19 / FLA : correction bug check état des steps du job 10.02.20 / SPE : Modification du compte sqlMonDBACalendar 03.03.20 / RTC : correction bug, rajout check session 23.06.20 / SPE : Ajout du monitoring dans DBA_monitoring_alerts_history 06.08.20 / SPE : Mise a jour de la SP complete bug60296 06.10.20 / SPE : Critical job not always send a status bug60296 27.10.20 / RTC : Migrate DBACC to HCIMON 16.08.21 / SPE : Replace hardcoded password in sp and scripts 17.03.22 / FLA : Change DBA mail =============================================================================*/ SET NOCOUNT ON; /*------------------- Declaration des variables --------------------*/ DECLARE @cmd nvarchar(max), @Message varchar(500), @Operator varchar(500), @JobName varchar(100), @JobDescription varchar(100), @JobStatus varchar(20), @Format varchar(4), @BouquetID uniqueidentifier, @StepID tinyint, @EndJobExecution tinyint, @LastStepID tinyint, @NbStepFailed tinyint, @EndBouquetExecution tinyint, @StartBouquetExecution datetime /*------------ Affectation des parametres aux variables ------------*/ SET @Operator = 'DBA_operator' SET @JobDescription = '' SET @JobStatus = '' SET @Message = '' SET @EndJobExecution = 0 SET @EndBouquetExecution = 0 SET @LastStepID = 0 SET @NbStepFailed = 0 SET @StartBouquetExecution = NULL /*-------------------------- Traitement ---------------------------*/ /* Get operator if SMS is needed */ BEGIN TRY SELECT @Operator = @Operator /*+';'+ORS.DML_Recipients FROM OPENROWSET('SQLNCLI', 'DRIVER={SQL Server};SERVER=hcimon.centralinfra.net;UID=sqlMonDBACalendar;PWD=', 'SELECT DML.DML_Recipients FROM HCITools.[mon].[SMSCalendar] SC INNER JOIN HCITools.[mon].[SMSCalendarDBAMailingListLink] SCDMLL ON SC.SMSCalendarID = SCDMLL.SCDMLLCalendarID AND SC.SCType = 1 -- Critical jobs type INNER JOIN HCITools.dbo.DBA_Mailing_list DML ON DML.DBA_Mailing_list_ID = SCDMLL.SCDMLLDBAMailingListID WHERE GETDATE() BETWEEN SC.SCStartDate AND SC.SCEndDate') as ORS */ END TRY BEGIN CATCH PRINT('ERROR during openrowset on DBACC, skip this') END CATCH BEGIN TRY DECLARE c_Jobs CURSOR LOCAL FORWARD_ONLY STATIC FOR SELECT sjs.step_id,sjc.SJCFormat,sjc.SJCJobName,sjc.SJCJobDescription,sj.job_id FROM HCITools.[mon].SMSJobCheck sjc LEFT JOIN msdb.dbo.sysjobsteps sjs WITH (NOLOCK) ON sjs.step_name like '%Start job %'+ sjc.SJCJobName +'%' INNER JOIN msdb.dbo.sysjobs sj WITH (NOLOCK) ON sjs.job_id = sj.job_id ORDER BY sjc.SJCNextExecution, step_id OPEN c_Jobs FETCH NEXT FROM c_Jobs INTO @StepID,@Format,@JobName,@JobDescription,@BouquetID WHILE @@fetch_status = 0 BEGIN IF @StepID IS NOT NULL BEGIN WHILE (isnull(@LastStepID,0) < @StepID AND @EndBouquetExecution = 0) BEGIN SELECT @StartBouquetExecution = sja.start_execution_date, @EndBouquetExecution = CASE WHEN sja.stop_execution_date IS NULL THEN 0 ELSE 1 END, @LastStepID = sja.last_executed_step_id FROM msdb.dbo.sysjobactivity sja WITH (NOLOCK) INNER JOIN HCITools.[mon].SMSJobCheck sjc ON sja.job_id = @BouquetID AND sjc.SJCJobName = @JobName AND sjc.SJCNextExecution <= sja.start_execution_date WAITFOR DELAY '00:01:00' END -- WHILE (@EndJobExecution = 0 AND @EndBouquetExecution = 0) IF (@LastStepID >= @StepID) BEGIN IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobhistory sjh WITH (NOLOCK) WHERE sjh.job_id = @BouquetID AND sjh.step_id = @StepID AND msdb.dbo.agent_datetime(sjh.run_date,sjh.run_time)>=@StartBouquetExecution) BEGIN WHILE @EndJobExecution = 0 BEGIN IF @Format IN ('SUN','AMA','AAI','RUEG') BEGIN SELECT @JobStatus = CASE WHEN sjh.run_status = 1 THEN 'OK' ELSE 'FAILED' END, @EndJobExecution = CASE WHEN sja.stop_execution_date IS NULL THEN 0 ELSE 1 END FROM msdb.dbo.sysjobs sj WITH (NOLOCK) INNER JOIN msdb.dbo.sysjobactivity sja WITH (NOLOCK) ON sj.name = @JobName AND sj.job_id = sja.job_id AND sja.start_execution_date >= @StartBouquetExecution INNER JOIN msdb.dbo.sysjobhistory sjh WITH (NOLOCK) ON sja.job_history_id = sjh.instance_id IF @JobStatus = 'OK' AND @EndJobExecution = 1 /* Check step even if @jobstatus = OK */ BEGIN SELECT @NbStepFailed = @NbStepFailed + COUNT(*) FROM msdb.dbo.sysjobhistory jh WITH (NOLOCK) INNER JOIN msdb.dbo.sysjobactivity ja WITH (NOLOCK) ON ja.job_id = jh.job_id INNER JOIN msdb.dbo.sysjobs j WITH (NOLOCK) ON j.job_id = ja.job_id WHERE j.name = @JobName AND run_status = 0 --and ja.stop_execution_date is null-- AND ja.session_id = (SELECT TOP 1 session_id FROM msdb.dbo.syssessions WITH (NOLOCK) ORDER BY agent_start_date DESC) AND start_execution_date is not null AND stop_execution_date is not null AND msdb.dbo.agent_datetime(run_date, run_time) >= start_execution_date /* Gestion des Query Timeout Error */ SELECT @NbStepFailed = @NbStepFailed + COUNT(*) FROM msdb.dbo.sysjobhistory jh WITH (NOLOCK) INNER JOIN msdb.dbo.sysjobactivity ja WITH (NOLOCK) ON ja.job_id = jh.job_id INNER JOIN msdb.dbo.sysjobs j WITH (NOLOCK) ON j.job_id = ja.job_id WHERE j.name = @JobName AND run_status = 1 --and ja.stop_execution_date is null-- AND ja.session_id = (SELECT TOP 1 session_id FROM msdb.dbo.syssessions WITH (NOLOCK) ORDER BY agent_start_date DESC) AND start_execution_date is not null AND stop_execution_date is not null AND jh.sql_message_id = 7412 AND msdb.dbo.agent_datetime(run_date, run_time) >= start_execution_date IF @NbStepFailed > 0 BEGIN SET @JobStatus = 'FAILED' END END END ELSE IF @Format = 'AMAR' BEGIN SET @cmd = 'SELECT @JobStatus = CASE WHEN sjh.run_status = 1 THEN ''OK'' ELSE ''FAILED'' END, @EndJobExecution = CASE WHEN sja.stop_execution_date IS NULL THEN 0 ELSE 1 END FROM AMAVITALIVEAPS.msdb.dbo.sysjobs sj WITH (NOLOCK) INNER JOIN AMAVITALIVEAPS.msdb.dbo.sysjobactivity sja WITH (NOLOCK) ON sj.name = @JobName AND sj.job_id = sja.job_id AND sja.start_execution_date >= @StartBouquetExecution INNER JOIN AMAVITALIVEAPS.msdb.dbo.sysjobhistory sjh WITH (NOLOCK) ON sja.job_history_id = sjh.instance_id IF @JobStatus = ''OK'' AND @EndJobExecution = 1 /* Check step even if @jobstatus = OK */ BEGIN SELECT @NbStepFailed = @NbStepFailed + COUNT(*) FROM AMAVITALIVEAPS.msdb.dbo.sysjobhistory jh WITH (NOLOCK) INNER JOIN AMAVITALIVEAPS.msdb.dbo.sysjobactivity ja WITH (NOLOCK) ON ja.job_id = jh.job_id INNER JOIN AMAVITALIVEAPS.msdb.dbo.sysjobs j WITH (NOLOCK) ON j.job_id = ja.job_id WHERE j.name = @JobName AND run_status = 0 --and ja.stop_execution_date is null-- AND ja.session_id = (SELECT TOP 1 session_id FROM AMAVITALIVEAPS.msdb.dbo.syssessions WITH (NOLOCK) ORDER BY agent_start_date DESC) AND start_execution_date is not null AND stop_execution_date is not null AND msdb.dbo.agent_datetime(run_date, run_time) >= start_execution_date /* Gestion des Query Timeout Error */ SELECT @NbStepFailed = @NbStepFailed + COUNT(*) FROM AMAVITALIVEAPS.msdb.dbo.sysjobhistory jh WITH (NOLOCK) INNER JOIN AMAVITALIVEAPS.msdb.dbo.sysjobactivity ja WITH (NOLOCK) ON ja.job_id = jh.job_id INNER JOIN AMAVITALIVEAPS.msdb.dbo.sysjobs j WITH (NOLOCK) ON j.job_id = ja.job_id WHERE j.name = @JobName AND run_status = 1 --and ja.stop_execution_date is null-- AND ja.session_id = (SELECT TOP 1 session_id FROM AMAVITALIVEAPS.msdb.dbo.syssessions WITH (NOLOCK) ORDER BY agent_start_date DESC) AND start_execution_date is not null AND stop_execution_date is not null AND jh.sql_message_id = 7412 AND msdb.dbo.agent_datetime(run_date, run_time) >= start_execution_date IF @NbStepFailed > 0 BEGIN SET @JobStatus = ''FAILED'' END END ' EXEC sp_executesql @cmd, N'@EndJobExecution tinyint OUTPUT,@JobStatus varchar(20) OUTPUT, @JobName varchar(100), @StartBouquetExecution datetime, @NbStepFailed tinyint', @JobStatus=@JobStatus OUTPUT, @EndJobExecution=@EndJobExecution OUTPUT, @JobName=@JobName, @StartBouquetExecution=@StartBouquetExecution, @NbStepFailed=@NbStepFailed END WAITFOR DELAY '00:01:00' END -- WHILE @EndJobExecution IS NULL END -- IF EXISTS ELSE BEGIN SET @JobStatus = 'NO EXECUTION' END SET @Message = isnull(@JobDescription,'no job description') + ' : ' + isnull(@JobStatus,'no job status') END -- IF (@LastStepID >= @StepID) END -- IF @StepID IS NOT NULL ELSE BEGIN SET @Message = isnull(@JobDescription,'no job description') + ' : Le job a changé de nom' END IF @Message <> '' BEGIN DECLARE @machine VARCHAR(255) SET @machine = '' BEGIN TRY EXEC arizona.dbo.aps_Retrieve_info_of_current_system @out_current_system = @machine OUTPUT END TRY BEGIN CATCH SET @machine = '' END CATCH SET @Message = isnull(@machine,'no machine name') + ' - ' + isnull(@Message,'no message') BEGIN TRY DECLARE @AlertID int IF CHARINDEX('Interbase',@JobDescription, 0) > 0 BEGIN SELECT @AlertID = DBA_monitoring_alerts_ID FROM [HCITools].[mon].[DBA_monitoring_alerts] WHERE DBAMA_key = 'SyncI' END IF CHARINDEX('Synchro H',@JobDescription, 0) > 0 BEGIN SELECT @AlertID = DBA_monitoring_alerts_ID FROM [HCITools].[mon].[DBA_monitoring_alerts] WHERE DBAMA_key = 'SyncH' END IF CHARINDEX('Synchro V',@JobDescription, 0) > 0 BEGIN SELECT @AlertID = DBA_monitoring_alerts_ID FROM [HCITools].[mon].[DBA_monitoring_alerts] WHERE DBAMA_key = 'SyncVExtract' END IF CHARINDEX('PharmIndex',@JobDescription, 0) > 0 BEGIN SELECT @AlertID = DBA_monitoring_alerts_ID FROM [HCITools].[mon].[DBA_monitoring_alerts] WHERE DBAMA_key = 'PHIDX' END IF RIGHT(@Message,2) = 'OK' BEGIN INSERT INTO [HCITools].[mon].[DBA_monitoring_alerts_history] (DBAMAH_monitoring_alerts, DBAMAH_criticity_level, DBAMAH_event_date, DBAMAH_long_message) VALUES (@AlertID, 0, getdate(), @message) END ELSE BEGIN INSERT INTO [HCITools].[mon].[DBA_monitoring_alerts_history] (DBAMAH_monitoring_alerts, DBAMAH_criticity_level, DBAMAH_event_date, DBAMAH_long_message) VALUES (@AlertID, 2, getdate(), @message) END END TRY BEGIN CATCH EXEC aps_Send_Mail_with_template @in_param_varchar_2 = @Operator, @in_param_subject = 'Problème avec le check du monitoring', @in_job_type = 4; END CATCH EXEC aps_Send_Mail_with_template @in_param_varchar_2 = @Operator, @in_param_subject = @message, @in_job_type = 4; END FETCH NEXT FROM c_Jobs INTO @StepID,@Format,@JobName,@JobDescription,@BouquetID SET @EndJobExecution = 0 SET @Message = '' SET @NbStepFailed = 0 END -- while @@fetch_status = 0 CLOSE c_Jobs DEALLOCATE c_Jobs SET @EndBouquetExecution = 1 WHILE @EndBouquetExecution <> 0 BEGIN SELECT @EndBouquetExecution = SUM(CASE WHEN sja.stop_execution_date IS NULL THEN 1 ELSE 0 END) FROM HCITools.[mon].SMSJobCheck sjc INNER JOIN msdb.dbo.sysjobsteps sjs WITH (NOLOCK) ON sjs.step_name like '%Start job %'+ sjc.SJCJobName +'%' INNER JOIN msdb.dbo.sysjobs sj WITH (NOLOCK) ON sjs.job_id = sj.job_id INNER JOIN msdb.dbo.sysjobactivity sja WITH (NOLOCK) ON sja.job_id = sj.job_id INNER JOIN msdb.dbo.syssessions AS sse ON sja.session_id = sse.session_id INNER JOIN (SELECT MAX(agent_start_date) as agent_start_date FROM msdb.dbo.syssessions) AS mss ON sse.agent_start_date = mss.agent_start_date WHERE sja.start_execution_date >= SJCNextExecution WAITFOR DELAY '00:02:00' END UPDATE sjc SET SJCNextExecution = sja.next_scheduled_run_date FROM HCITools.[mon].SMSJobCheck sjc INNER JOIN msdb.dbo.sysjobsteps sjs WITH (NOLOCK) ON sjs.step_name like '%Start job %'+ sjc.SJCJobName +'%' INNER JOIN msdb.dbo.sysjobs sj WITH (NOLOCK) ON sjs.job_id = sj.job_id INNER JOIN msdb.dbo.sysjobactivity sja WITH (NOLOCK) ON sja.job_id = sj.job_id INNER JOIN msdb.dbo.syssessions AS sse ON sja.session_id = sse.session_id INNER JOIN (SELECT MAX(agent_start_date) as agent_start_date FROM msdb.dbo.syssessions) AS mss ON sse.agent_start_date = mss.agent_start_date WHERE sja.start_execution_date >= ISNULL(SJCNextExecution,GETDATE()-1) /*---------------------- Traitement des erreurs ----------------------*/ END TRY BEGIN CATCH /* Traitement des erreurs (avec RaiseError) */ EXEC dbo.get_Error_Info @in_RaiseError = 1 END CATCH GO