SCOM Dashboard — unhealthy objects with missing monitor alert
Привет.
Всем администраторам Operations Manager известно, что пользователи системы мониторинга иногда закрывают алерты, которые создаются мониторами. Одно из решений это проблемы — автоматический Reset этого монитора, используя тот же Orchestrator (детали тут). Не хотите поднимать ради этой задачи Orchestrator — используйте аналогичный скрипт и Scheduled Task. Но все это работает с алертами только после того, как вы внедрили одно из этих решений. Как же быть с уже закрытыми алертами? Или если вы приехали к клиенту впервые, как понять что он уже закрыл вручную, например, 90 дней назад?
Еще одна ситуация, которая может возникать, — это мониторы, которые не создают алертов или закрытие алертов вследствие превышения срока:
С этим вопросом я столкнулся достаточно давно. И тогда единственным решением определить unit monitor-ы с закрытыми алертами был sql-запрос к OperationsManager DB. Можно было сделать отчет и потом вручную искать каждый объект и ресетить монитор, или сделать это скриптом. В любом случае решение было корявым. В Operations Manager c выходом UR2 появился Powershell Grid Widget и решение перешло на новый качественный уровень.
Начнем с sql-запроса.
Получаем все объекты, у которых есть unit monitor в состоянии ERROR или WARN.
select UnhealthyState.BaseManagedEntityId, -- object\instance id UnhealthyState.MonitorName -- Monitor Name from dbo.StateView as UnhealthyState WITH (NOLOCK) where UnhealthyState.HealthState in (3,2) --only ERROR и WARN and UnhealthyState.OperationalState is not NULL --not aggregate or dependency monitor and UnhealthyState.MonitorName not in ('Insert MonitorName' -- you can remove some motinor from query ,'Insert MonitorName' ) --and UnhealthyState.MonitorName not like '%SQL%' -- you can use like or not like to show specific monitors --and UnhealthyState.MonitorName not like '%network%'
Для удобства уважаемых читателей приведены варианты фильтров, которые позволят вам исключить определенные мониторы из выборки или, используя like\not like, выбирать мониторы с определенными ключевыми словами. (Это для неопытных в sql-запросах, опытные могут творить, что хотят 🙂 ).
Теперь нам нужно получить все открытые (Resolution State не 255) алерты и связать их с имеющимся запросом.
select UnhealthyState.BaseManagedEntityId, UnhealthyState.MonitorName, OpenAlerts.Id from dbo.StateView as UnhealthyState WITH (NOLOCK) left join dbo.AlertView as OpenAlerts on UnhealthyState.BaseManagedEntityId = OpenAlerts.MonitoringObjectId and OpenAlerts.ResolutionState <> 255 and OpenAlerts.IsMonitorAlert = 1 and LanguageCode = 'ENU' where UnhealthyState.HealthState in (3,2) --only ERROR и WARN and UnhealthyState.OperationalState is not NULL --not aggregate or dependency monitor and UnhealthyState.MonitorName not in ('Insert MonitorName' -- you can remove some motinor from query ,'Insert MonitorName' ) --and UnhealthyState.MonitorName not like '%SQL%' -- you can use like or not like to show specific monitors --and UnhealthyState.MonitorName not like '%network%' and OpenAlerts.Id is NULL -- Alert was closed or did not exist
Последние штрихи — получаем полное имя объекта\инстанса и его класс.
select --top 25 --Uncomment if your dashboard is working too long and get instances by parts PathT.FullName ,ClassT.Name as ClassName ,UnhealthyState.MonitorName from dbo.StateView as UnhealthyState WITH (NOLOCK) left join dbo.AlertView as OpenAlerts on UnhealthyState.BaseManagedEntityId = OpenAlerts.MonitoringObjectId and OpenAlerts.ResolutionState <> 255 and OpenAlerts.IsMonitorAlert = 1 and LanguageCode = 'ENU' inner join dbo.ManagedEntityGenericView PathT on PathT.id = UnhealthyState.BaseManagedEntityId and PathT.MonitoringClassId= UnhealthyState.TargetManagedEntityType inner join [dbo].[ManagedTypeView] As ClassT on ClassT.id = UnhealthyState.TargetManagedEntityType and ClassT.LanguageCode = 'ENU' where UnhealthyState.HealthState in (3,2) --only ERROR и WARN and UnhealthyState.OperationalState is not NULL --not aggregate or dependency monitor and UnhealthyState.MonitorName not in ('Insert MonitorName' -- you can remove some motinor from query ,'Insert MonitorName' ) --and UnhealthyState.MonitorName not like '%SQL%' -- you can use like or not like to show specific monitors --and UnhealthyState.MonitorName not like '%network%' and OpenAlerts.Id is NULL -- Alert was closed or did not exist
А теперь создадим Powershell Grid Widget Dashboard, где используем этот запрос для получения инстансов.
Для начала создайте Dashboard View -> Grid Layout и выберите 1 cell.
Добавляем widget.
В разделе Script
$SqlServer = "SQL Server FQDN" $SqlCatalog = "OperationsManager" $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server = $SqlServer; Database = $SqlCatalog; Integrated Security = True" $SQLQuery_Values = " INSERT YOUR SQL QUERY HERE " $SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.CommandText = $SQLQuery_Values $SqlCmd.Connection = $SqlConnection $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $SqlAdapter.SelectCommand = $SqlCmd $SQLDataSet = New-Object System.Data.DataSet [void]$SqlAdapter.Fill($SQLDataSet) $classname_current = "" $classname_pre = "" if ($?) { $ScriptContext.Clear() if ($SQLDataSet.Tables[0].Rows.Count -gt 0) { foreach ($TableRow in $SQLDataSet.Tables[0].Rows){ $classname_current = "$($TableRow.ClassName)" if($classname_current -ne $classname_pre ) { $class = Get-SCOMClass -Name $TableRow.ClassName } $obj = Get-SCOMClassInstance -Class $class | ?{$_.Fullname -eq "$($TableRow.FullName)"} $dataObject = $ScriptContext.CreateFromObject($obj, "Id=Id,HealthState=HealthState,DisplayName=DisplayName,Path=Path", $null) $classname_pre = $classname_current $ScriptContext.ReturnCollection.Add($dataObject) } } }
Не забудьте вставить FQDN вашего sql сервера и ваш запроса (или для начала мой 🙂 ).
В результате вы должны получить отличный dashboard показывающий все инстансы в состоянии ERROR или WARN у которых нет открытых алетов (их или закрыли или небыло никогда).
Скачать Managment Pack Unhealthy.objects.Dashboard. Не забудьте отредактировать dashboard и вставить FQDN вашего sql-сервера.
И еще, пользователь, который будет открывать этот Dashboard, должен иметь права read на базу OperationsManager. Так как нужна эта информация админам, тут проблем не должно возникнуть.
Буду рад комментариям и вопросам.
Александр Петлевой