SQL Server has multiple active traces which can impact performance
http://go.microsoft.com/fwlink/?LinkId=262802
Target | Microsoft.KnowledgeServices.SQLServer.DBEngine | ||
Parent Monitor | System.Health.ConfigurationState | ||
Category | Alert | ||
Enabled | True | ||
Alert Generate | True | ||
Alert Severity | Warning | ||
Alert Priority | Normal | ||
Alert Auto Resolve | True | ||
Monitor Type | Microsoft.KnowledgeServices.Library.PowerShellMonitorEx | ||
Remotable | True | ||
Accessibility | Public | ||
Alert Message |
| ||
RunAs | Default | ||
Comment | SupportTopic=TBD;VersionNumber=1.0.0.0; |
<UnitMonitor ID="Monitor_AKN418746" Comment="SupportTopic=TBD;VersionNumber=1.0.0.0;" Accessibility="Public" Enabled="true" Target="KnowledgeServicesSQLServerLibrary!Microsoft.KnowledgeServices.SQLServer.DBEngine" ParentMonitorID="Health!System.Health.ConfigurationState" Remotable="true" Priority="Normal" TypeID="KnowledgeServicesLibrary!Microsoft.KnowledgeServices.Library.PowerShellMonitorEx" ConfirmDelivery="true">
<Category>Alert</Category>
<AlertSettings AlertMessage="MonitorMessage67c553a54a484d7499aa3269116e130f">
<AlertOnState>Error</AlertOnState>
<AutoResolve>true</AutoResolve>
<AlertPriority>Normal</AlertPriority>
<AlertSeverity>Warning</AlertSeverity>
<AlertParameters>
<AlertParameter1>$Data/Context/Property[@Name='Num_Traces']$</AlertParameter1>
<AlertParameter2>$Data/Context/Property[@Name='Trace_Locations']$</AlertParameter2>
<AlertParameter3>$Data/Context/Property[@Name='Num_Traces_UNC']$</AlertParameter3>
<AlertParameter4>$Data/Context/Property[@Name='Trace_Locations_UNC']$</AlertParameter4>
<AlertParameter5>$Data/Context/Property[@Name='Num_Expensive_Trace_Events']$</AlertParameter5>
<AlertParameter6>$Data/Context/Property[@Name='Expensive_Trace_Path']$</AlertParameter6>
</AlertParameters>
</AlertSettings>
<OperationalStates>
<OperationalState ID="Success" MonitorTypeStateID="Success" HealthState="Success"/>
<OperationalState ID="Error" MonitorTypeStateID="Error" HealthState="Error"/>
</OperationalStates>
<Configuration>
<ScriptName>AKN418746.ps1</ScriptName>
<Parameters>
<Parameter>
<Name>ConnectionString</Name>
<Value>$Target/Property[Type="MicrosoftSQLServerLibrary!Microsoft.SQLServer.DBEngine"]/ConnectionString$</Value>
</Parameter>
</Parameters>
<ScriptBody>
param($ConnectionString)
$ErrorActionPreference = "Stop"
# Set up the arguments
$scriptargs = new-object psobject
$scriptargs | add-member NoteProperty "ConnectionString" $ConnectionString
# Set up the output
$global:scriptoutput = new-object psobject
$scriptoutput | add-member NoteProperty "HasIssue" $false
$scriptoutput | add-member NoteProperty "Num_Traces" 0
$scriptoutput | add-member NoteProperty "Trace_Locations" ""
$scriptoutput | add-member NoteProperty "Num_Traces_UNC" 0
$scriptoutput | add-member NoteProperty "Trace_Locations_UNC" ""
$scriptoutput | add-member NoteProperty "Num_Expensive_Trace_Events" 0
$scriptoutput | add-member NoteProperty "Expensive_Trace_Path" ""
#-----------------------------------------------------
# MAIN CODE SECTION
#-----------------------------------------------------
# Environment
$scriptenv = New-Object psobject
$scriptenv | Add-Member NoteProperty "ClientSide_Trace_Check" $false
$scriptenv | Add-Member NoteProperty "Num_Traces" 0
$scriptenv | Add-Member NoteProperty "Trace_Locations" $null
$scriptenv | Add-Member NoteProperty "Num_Traces_UNC" 0
$scriptenv | Add-Member NoteProperty "Trace_Locations_UNC" $null
$scriptenv | Add-Member NoteProperty "Num_Expensive_Trace_Events" 0
$scriptenv | Add-Member NoteProperty "Expensive_Trace_Path" $null
$scriptenv | Add-Member NoteProperty "Expensive_Trace_PresentCheck" $false
$scriptenv | Add-Member NoteProperty "RuntimeError" $false
# Helper functions
function GetActiveTraces()
{
#Get active traces
$num_Traces = 0
$trace_Locations = ""
$num_Traces_UNC = 0
$trace_Locations_UNC = ""
$queryString = "SELECT traceid, property, CONVERT (varchar(1024), value) AS value FROM sys.traces b CROSS APPLY :: fn_trace_getinfo(b.id) AS a WHERE a.traceid > 1 AND b.status<> 0 AND a.property = 2"
$oConnection = New-Object System.Data.SqlClient.SqlConnection
$oConnection.ConnectionString = "Server=" + $scriptargs.ConnectionString + ";" + "Database=master;Integrated Security=true"
$oConnection.Open()
$oSQLCommand = New-Object System.Data.SqlClient.SqlCommand
$oSQLCommand.CommandText = $queryString
$oSQLCommand.Connection = $oConnection
$oReader = $oSQLCommand.ExecuteReader()
while ($oReader.Read())
{
$num_Traces = $num_Traces + 1
if($oReader["value"] -eq [System.DBNull]::Value)
{
if($scriptenv.ClientSide_Trace_Check -eq $false)
{
$scriptenv.ClientSide_Trace_Check = $true
}
}
else
{
if($oReader["value"].SubString(0,2) -eq "\\")
{
#UNC Location List
$trace_Locations_UNC += [string]::Format("<row><TraceId>{0}</TraceId><TraceFileName>{1}</TraceFileName></row>",$oReader["traceid"],$oReader["value"])
$num_Traces_UNC = $num_Traces_UNC + 1
}
else
{
#None UNC Locations
$trace_Locations += [string]::Format("<row><TraceId>{0}</TraceId><TraceFileName>{1}</TraceFileName></row>",$oReader["traceid"],$oReader["value"])
}
}
}
$oReader.Close()
#Check for expensive events
$countExpensiveEvents = 0
$expensive_Trace_Path = ""
$expensive_Trace_PresentCheck = $false
$queryString2 = @"
select DISTINCT trace_id,
status,
path,
trace_event_id,
trace_event_name,
expensive_event
from
(SELECT t.id AS trace_id,
row_number() over (partition by t.id order by te.trace_event_id, tc.trace_column_id) as row_number,
t.status,
t.path,
t.is_default,
te.trace_event_id,
te.name AS trace_event_name,
case when te.trace_event_id in (23, 24, 40, 41, 44, 45, 51, 52, 54, 68, 96, 97, 98, 113, 114, 122, 146, 180) then cast(1 as bit) else cast(0 as bit) end as expensive_event
FROM sys.traces t
CROSS apply ::fn_trace_geteventinfo(t .id) AS e
JOIN sys.trace_events te ON te.trace_event_id = e.eventid
JOIN sys.trace_columns tc ON e.columnid = trace_column_id) as x
where trace_id>1 and expensive_event=1 and Status <>0
"@
$oSQLCommand2 = New-Object System.Data.SqlClient.SqlCommand
$oSQLCommand2.CommandText = $queryString2
$oSQLCommand2.Connection = $oConnection
$oReader2 = $oSQLCommand2.ExecuteReader()
$isUniquePath = @()
while ($oReader2.Read())
{
if(!($isUniquePath -contains $oReader2["trace_id"]))
{
if($oReader2["path"] -eq [System.DBNull]::Value)
{
$expensive_Trace_Path += [string]::Format("<row><TraceId>{0}</TraceId><TraceFileName>{1}</TraceFileName></row>",$oReader2["trace_id"],"NULL")
}
else
{
$expensive_Trace_Path += [string]::Format("<row><TraceId>{0}</TraceId><TraceFileName>{1}</TraceFileName></row>",$oReader2["trace_id"],$oReader2["path"])
}
$isUniquePath += $oReader2["trace_id"]
}
$countExpensiveEvents = $countExpensiveEvents + 1
}
if($countExpensiveEvents -gt 0)
{
$expensive_Trace_PresentCheck = $true
}
$oReader2.Close()
$oConnection.Close()
$scriptenv.Num_Traces = $num_Traces
$scriptenv.Trace_Locations = $trace_Locations
$scriptenv.Num_Traces_UNC = $num_Traces_UNC
$scriptenv.Trace_Locations_UNC = $trace_Locations_UNC
$scriptenv.Expensive_Trace_Path = $expensive_Trace_Path
$scriptenv.Num_Expensive_Trace_Events = $countExpensiveEvents
$scriptenv.Expensive_Trace_PresentCheck = $expensive_Trace_PresentCheck
}
# Main function
function AdvisorRule($scriptargs, $scriptoutput)
{
trap [System.Exception] {
$scriptenv.RuntimeError = $true
continue;
}
# Initialize parameters
$scriptoutput.HasIssue = $false
# Set parameter values
GetActiveTraces
if($scriptenv.RuntimeError -eq $false)
{
if(($scriptenv.Expensive_Trace_PresentCheck -eq $true) -or ($scriptenv.Num_Traces_UNC -gt 0) -or ($scriptenv.Num_Traces -gt 3) -or ($scriptenv.ClientSide_Trace_Check -eq $true))
{
$scriptoutput.HasIssue = $true
$scriptoutput.Num_Traces = $scriptenv.Num_Traces
$scriptoutput.Trace_Locations = $scriptenv.Trace_Locations;
$scriptoutput.Num_Traces_UNC = $scriptenv.Num_Traces_UNC
$scriptoutput.Trace_Locations_UNC = $scriptenv.Trace_Locations_UNC
$scriptoutput.Num_Expensive_Trace_Events = $scriptenv.Num_Expensive_Trace_Events
$scriptoutput.Expensive_Trace_Path = $scriptenv.Expensive_Trace_Path
}
}
}
AdvisorRule $scriptargs $scriptoutput
# set the output
$mom = new-object -comobject "MOM.ScriptAPI"
$bag = $mom.CreatePropertyBag()
if ($scriptoutput.HasIssue -ne $null)
{
$bag.AddValue("HasIssue", $scriptoutput.HasIssue)
}
if ($scriptoutput.Num_Traces -ne $null)
{
$bag.AddValue("Num_Traces", $scriptoutput.Num_Traces)
}
if ($scriptoutput.Trace_Locations -ne $null)
{
$bag.AddValue("Trace_Locations", $scriptoutput.Trace_Locations)
}
if ($scriptoutput.Num_Traces_UNC -ne $null)
{
$bag.AddValue("Num_Traces_UNC", $scriptoutput.Num_Traces_UNC)
}
if ($scriptoutput.Trace_Locations_UNC -ne $null)
{
$bag.AddValue("Trace_Locations_UNC", $scriptoutput.Trace_Locations_UNC)
}
if ($scriptoutput.Num_Expensive_Trace_Events -ne $null)
{
$bag.AddValue("Num_Expensive_Trace_Events", $scriptoutput.Num_Expensive_Trace_Events)
}
if ($scriptoutput.Expensive_Trace_Path -ne $null)
{
$bag.AddValue("Expensive_Trace_Path", $scriptoutput.Expensive_Trace_Path)
}
$bag
</ScriptBody>
<SnapIns/>
<TimeoutSeconds>300</TimeoutSeconds>
<Schedule>86397</Schedule>
<ErrorExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Boolean">Property[@Name='HasIssue']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">true</Value>
</ValueExpression>
</SimpleExpression>
</ErrorExpression>
<SuccessExpression>
<Not>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Boolean">Property[@Name='HasIssue']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">true</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</Not>
</SuccessExpression>
</Configuration>
</UnitMonitor>