Wednesday, 29 July 2015
Stored Procedure that disables failing Server Agent Jobs
I had a problem, I had a lot of development jobs that ran overnight, when they failed I got an email advising me of this. Then they failed again and again as they kept trying to run, this stored procedure monitors for failing jobs, using a user set limit and emails out a VERY bright red email to advise on what it's done.
CREATE Proc [UspMonitor_DisableFailingJobs]
(@NumberToDisable int)
As
-- ==========================================================================================
-- Author:
-- Requestor:
-- Create date: 20.02.2014
-- Description: Procedure that queries job history and disables queries that have failed 10 times in one day
--
-- Modifications:
--
-- ==========================================================================================
Set NoCount On
Create Table #Fails
(
[Failure Date] Date
, [Job Name] Varchar(500)
, [JobID] Varchar(100)
, [Step_id] Int
, [Step Name] Varchar(1000)
, [Error Message] Varchar(Max)
, [Start_Time] DateTime
)
Insert #Fails
( [Failure Date]
, [Job Name]
, [JobID]
, Step_id
, [Step Name]
, [Error Message]
, Start_Time
)
Select Distinct
[Failure Date] = Convert(Date , Cast(JH.run_date As Char(8)))
, [Job Name] = Substring(JB.name , 1 , 40)
, [JobID] = Cast(JB.job_id As Varchar(100))
, [Step_id] = JH.step_id
, [Step Name] = JH.step_name
, [Error Message] = Left(JH.[message] , 500)
, [Start_Time] = Left(Cast(JH.run_date As Char(10)) , 4) + '-'
+ Substring(Cast(JH.run_date As Char(10)) , 5 , 2) + '-'
+ Substring(Cast(JH.run_date As Char(10)) , 7 , 2) + ' '
+ Substring(Right(Stuff(' ' , 1 , 1 , '000000')
+ Convert(Varchar(6) , JH.run_time) , 6) , 1 ,
2) + ':' + Substring(Right(Stuff(' ' , 1 , 1 ,
'000000')
+ Convert(Varchar(6) , JH.run_time) ,
6) , 3 , 2) + ':'
+ Substring(Right(Stuff(' ' , 1 , 1 , '000000')
+ Convert(Varchar(6) , JH.run_time) , 6) , 5 ,
2)
From
msdb.dbo.sysjobhistory JH
Inner Join msdb.dbo.sysjobs JB
On JH.job_id = JB.job_id
Where
JH.run_status Not In ( 1 , 4 )
And JH.step_id <> 0
And JB.enabled=1
/*Get Latest status of Job*/
CREATE TABLE #RunInfo
(
[Job Name] Varchar(150)
, [Job Description] Varchar(500)
, [LastRunDate] Char(8)
, [LastRunTime] Char(6)
, [JobStatus] Varchar(15)
,[OrderOfRun] Int
)
Insert #RunInfo
( [Job Name]
, [Job Description]
, LastRunDate
, LastRunTime
, JobStatus
, OrderOfRun
)
Select
[Job Name] = j.name
, [Job Description] = j.description
, [LastRunDate] = h.run_date
, [LastRunTime] = h.run_time
, [JobStatus] = Case h.run_status
When 0 Then 'Failed'
When 1 Then 'Successful'
When 3 Then 'Cancelled'
When 4 Then 'In Progress'
End
,[OrderOfRun] = Rank() Over(Partition By j.job_id Order By h.run_date Desc,h.run_time Desc)
From
msdb.dbo.sysjobhistory h
Left join msdb.dbo.sysjobs j On j.job_id = h.job_id
Where h.step_id=0 --only look @ Job Outcome step
Order By [Job Name] desc,Rank() Over(Partition By j.job_id Order By h.run_date Desc,h.run_time Desc) Asc
/*Jobs that have failed 10 times today and the last run was not successful*/
Create Table #JobsToCancel
(
CancelID Int Identity(1 , 1)
, [Job Name] Varchar(150)
)
Insert #JobsToCancel
( [Job Name]
)
Select
F.[Job Name]
From
#Fails F
Left Join #RunInfo R On R.[Job Name] = F.[Job Name]
Where
F.[Failure Date] = Cast(GetDate() As Date)
And R.JobStatus Not In ('Successful','In Progress')
And R.OrderOfRun=1
Group By
F.[Job Name]
, JobID
, [Failure Date]
Having Count(1) >=@NumberToDisable
Declare
@TotalJobsToCancel Int
, @CurrentJob Int = 1
Select
@TotalJobsToCancel = Max(CancelID)
From
#JobsToCancel
If @TotalJobsToCancel > 0
Begin
While @CurrentJob <= @TotalJobsToCancel
Begin
Declare @SQL Varchar(Max)
Select
@SQL = 'EXEC msdb.dbo.sp_update_job @job_name='''
+ JC.[Job Name] + ''',@enabled = 0'
From
#JobsToCancel JC
Where
JC.CancelID = @CurrentJob
Exec (@SQL)
Set @CurrentJob = @CurrentJob + 1
End
Declare
@To Varchar(Max)= 'TEAM@TEAM.com'
, @font Varchar(150) = 'Calibri'
, @BorderColour Varchar(20) = '#000000'
, @EmailColour Varchar(20) = '#FE2E2E'
Select
[Job Name]
From
#JobsToCancel
Declare
@body Varchar(Max)
, @SubjectLine Varchar(250)
Set @body = Cast((
Select
td = Cast(Coalesce([d].[Job Name] , '') As Varchar(50))
From
(
Select
LL.[Job Name]
From
#JobsToCancel As LL
) As d
For
Xml Path('tr')
, Type
) As Varchar(Max))
Set @body = '<table cellpadding="2" cellspacing="2" border="1" BORDERCOLOR="'
+ @BorderColour + '">' + '<tr>
<th><font face="' + @font + '"> Job Name </font></th>
</tr>' + '<font face="' + @font + '" size="2">'
+ Replace(Replace(@body , '<' , '<') , '>' , '>')
+ '</font>' + '</table>'
Set @body = '<body bgcolor="' + @EmailColour + '"><font face="'
+ @font
+ '"> Dear Team, <br><br><br> WARNING: THE BELOW JOBS HAVE BEEN AUTO CANCELLED AFTER FAILING '+Cast(@NumberToDisable As Varchar(4))+' TIMES IN ONE DAY </font><br><br><br>'
+ @body
Select
@SubjectLine = '****' + @@ServerName + ' '
+ ' - Jobs Auto Cancelled ' + '*****'
Exec msdb.dbo.sp_send_dbmail @profile_name = 'Mail Account' ,
@recipients = @To
--, @copy_recipients = @CC,
--,@blind_copy_recipients = @BC
, @subject = @SubjectLine , @importance = 'High' ,
@body_format = 'HTML' , @body = @body
End
Drop Table #Fails
Drop Table #JobsToCancel
Labels:
admin,
email,
SQL,
stored procedure,
temp tables
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment