I've been working quite a bit lately with the RedGate SQL Monitor tool, and the more I work with it the more I like it. The analysis tab is very useful for monitoring any changes made and what impact they have on the system in total. But one of the things I really like about SQL Monitor is the ability to create custom metrics. Although there's something like 33 alerts you can opt in/out of for monitoring, the ability to create your own really adds value in that you don't have to go down the route of creating SQL Agent jobs to run on each server and to have to email you when an alert could be raised via SQL Monitor.
And so I wrote my first custom metric today. It checks for a change in the recovery model of all the databases on an instance. This is useful as somebody accidentally altered the recovery model of a database to FULL and the log file filled up! I've looked into submitting the alert to RedGate, but the submission form on their site is broken at the moment, so I'm posting the T-SQL here. Once it's submitted, and hopefully approved, I will post a link to the metric here.
I've added comments in detail here, but if any questions please get in touch.
--metric that seaches for any change in recovery model /* start and end time for searching the log file with xp_readerrorlog if alert is configured to run at a different frequency than once an hour then the start time param should be altered to reflect change */ DECLARE @StartTime DATETIME = DATEADD(HOUR, - 1, GETDATE()) DECLARE @EndTime DATETIME = GETDATE() /* some bulk loading/index maintenance jobs alter the recovery model these run between midnight and 6am, so we want to ignore these times to avoid false positives */ DECLARE @IgnoreStart DATETIME DECLARE @IgnoreEnd DATETIME SET @IgnoreStart = CONVERT(DATE, GETDATE(), 108) + CONVERT(DATETIME, '00:00:00') SET @IgnoreEnd = CONVERT(DATE, GETDATE(), 108) + CONVERT(DATETIME, '06:00:00') /* insert results of xp_readerrorlog into a temp table */ IF OBJECT_ID('tempdb..#ReadErrorLog') IS NOT NULL DROP TABLE #ReadErrorLog CREATE TABLE #ReadErrorLog ( LogDate DATETIME ,ProcessInfo NVARCHAR(10) ,TextOutput NVARCHAR(1024) ) INSERT INTO #ReadErrorLog EXEC xp_readerrorlog 0 ,1 ,N'RECOVERY' ,N'OPTION' ,@StartTIme ,@EndTime /* return only those recovery model changes that were made outside of the changes that are intentional */ SELECT COUNT(*) FROM #ReadErrorLog WHERE LogDate NOT BETWEEN @IgnoreStart AND @IgnoreEnd