PerfMon: Script Powershell para adicionar contadores automaticamente
O Performance Monitor (PerfMon), uma ferramenta integrada ao Windows, desempenha um papel crucial na análise e aprimoramento do desempenho de sistemas e aplicativos. Com seu sistema de contadores, o PerfMon possibilita a monitorização em tempo real e a organização eficaz dos dados, permitindo aos administradores identificar gargalos, tendências e problemas de desempenho.
Esse artigo explora a possibilidade de adicionar os contadores do PerfMon de forma automática utilizando o Powershell.
Este artigo se baseia no trabalho de referência do autor Joseph Herlant, que oferece insights valiosos sobre o uso do Powershell para a geração de um arquivo BLG porém no script inicial da versão (1.0.0, 2014-09-16) é necessário informar o nome do serviço da instância SQL Server no qual deseja adicionar ao arquivo BLG.
Neste contexto, é relevante ressaltar que o presente artigo incorpora modificações significativas ao script original baseado no trabalho de referência do autor Joseph Herlant. As alterações realizadas visam a introdução de novas funcionalidades e adaptações específicas ao cenário em questão. Ao customizar o conteúdo original, o artigo agora aborda aspectos mais alinhados às necessidades e peculiaridades do ambiente em que será implementado, enriquecendo a abordagem e proporcionando uma perspectiva mais personalizada sobre a utilização do Performance Monitor (PerfMon).
Tive a necessidade de alteração do script devido a correria do dia a dia para que fosse mais ágil adicionar automaticamente os contadores básicos ao Perfmon.
Os contadores que serão adicionados ao arquivo BLG são eles:
- \Process(sqlservr)\% Processor Time
- \Process(_Total)\% Processor Time
- \Processor(_Total)\% Privileged Time
- \Processor(_Total)\% Processor Time
- \LogicalDisk(*)\Current Disk Queue Length
- \LogicalDisk(*)\Avg. Disk sec/Read
- \LogicalDisk(*)\Avg. Disk sec/Write
- \LogicalDisk(*)\Disk Reads/sec
- \LogicalDisk(*)\Disk Writes/sec
- \Buffer Manager\Lazy writes/sec
- \Buffer Manager\Page reads/s
- \Buffer Manager\Page writes/sec
- \Buffer Manager\Page life expectancy
- \Latches\Total Latch Wait Time (ms)
- \Locks(_Total)\Lock Wait Time (ms)
- \Memory Manager\Free Memory (KB)
- \Memory Manager\Memory Grants Pending
- \SQL Statistics\Batch Requests/sec
- \SQL Statistics\SQL Compilations/sec
Caso tenha a necessidade de adicionar outros contadores, pode ser feito alterando o script ou até mesmo na tela do Perfmon porém não será salvo no script.
As melhorias adicionadas ao script são elas:
- Informações ao executar o script
- O arquivo de saída BLG será gerado em um diretório C:\DBA-COLETA
- Rotina de expurgo dos arquivos BLG antigo do diretório \DBA-COLETA
- Para os contadores de SQL Server, foi efetuado a alteração para que o script adicione os contadores da instância automaticamente, sem a necessidade de intervenção do DBA.
- O script irá abrir o arquivo BLG assim que finalizado a coleta inicial
#! powershell
# **********************************************************************************************************************************************************************************#
# HISTÓRIA : #
# Data : 07/08/2023 #
# Script Base: Utilizei como referência o código do ator Joseph Herlant na versão inicial: 1.0.0, 2014-09-16 #
# Script com base no artigo "Automatically setting SQL Server perf counters using Powershell" #
# Link do script base : http://aerostitch.github.io/databases/sqlserver/generate_perfcounters_sql_server.html #
# #
# Alterado por : Wesley Cardoso - Versão: 2.0 #
# #
# O script inicial do autor Joseph Herlant tem a necessidade de informar o nome da instância no contadores de SQL Server. #
# Melhorias apresentadas nessa versão 2.0, foram para agilizar a configuração do PERFMON sem a necessidade de adicionar cada contador separadamente e manualmente. #
# #
# 1 - Informações ao executar o Script #
# 2 - O arquivo de saída BLG será gerado em um diretório C:\DBA-COLETA #
# 3 - Rotina de expurgo dos arquivos BLG antigo do diretório \DBA-COLETA #
# 4 - Para os contadores de SQL Server, foi efetuado a alteração para que o script adicione os contadores da instância automaticamente, sem a necessidade de intervenção do DBA. #
# 5 - O script irá abrir o arquivo BLG assim que finalizado a coleta inicial. #
# 6 - O arquivo BLG pode ser utilizado para coletar a atividade atual do host, basta efetuar a configuração em PROPERTIES > SOURCE > CURRENT ACTIVITY #
# 7 - E geração de apenas um arquivo BLG contendo todos os contadores básicos. #
# **********************************************************************************************************************************************************************************#
Write-Host ''
Write-Host 'Esse script tem como base o artigo '"Automatically setting SQL Server perf counters using Powershell"' do autor Joseph Herlant '
Write-Host ''
Write-Host 'Alterado por : Wesley Cardoso - Versão: 2.0'
Write-Host ''
Write-Host 'O script inicial do autor Joseph Herlant tem a necessidade de informar o nome da instância no contadores de SQL Server.'
Write-Host 'Melhorias apresentadas, foram para agilizar a configuração do PERFMON sem a necessidade de adicionar cada contador separadamente e manualmente.'
Write-Host 'Segue as alterações:'
Write-Host ''
Write-Host '1 - Informações ao executar o Script'
Write-Host '2 - O arquivo de saída BLG será gerado em um diretório C:\DBA-COLETA'
Write-Host '3 - Rotina de expurgo dos arquivos BLG antigo do diretório \DBA-COLETA'
Write-Host '4 - Para os contadores de SQL Server, foi efetuado a alteração para que o script adicione os contadores da instância automaticamente, sem a necessidade de intervenção do DBA.'
Write-Host '5 - O script irá abrir o arquivo BLG assim que finalizado a coleta inicial.'
Write-Host '6 - O arquivo BLG pode ser utilizado para coletar a atividade atual do host, basta efetuar a configuração em PROPERTIES > SOURCE > CURRENT ACTIVITY'
# Criando o diretório onde será salvo o arquivo .blg no C:\DBA-COLETA
Write-Host ''
Write-Host 'SERÁ GERADO O ARQUIVO BLG COM OS CONTADORES DE PERFORMANCE ABAIXO:'
Write-Host ''
Write-Host "Contadores de CPU"
Write-Host "========================================================="
Write-Host "'\Process(sqlservr)\% Processor Time'"
Write-Host "'\Process(_Total)\% Processor Time'"
Write-Host "'\Processor(_Total)\% Privileged Time'"
Write-Host "'\Processor(_Total)\% Processor Time'"
Write-Host ''
Write-Host "Contadores de disco"
Write-Host "========================================================="
Write-Host "'\LogicalDisk(*)\Current Disk Queue Length'"
Write-Host "'\LogicalDisk(*)\Avg. Disk sec/Read'"
Write-Host "'\LogicalDisk(*)\Avg. Disk sec/Write'"
Write-Host "'\LogicalDisk(*)\Disk Reads/sec'"
Write-Host "'\LogicalDisk(*)\Disk Writes/sec'"
Write-Host ''
Write-Host "Contadores de SQL Server"
Write-Host "========================================================="
Write-Host "'Buffer Manager\Lazy writes/sec'"
Write-Host "'Buffer Manager\Page reads/se'"
Write-Host "'Buffer Manager\Page writes/sec'"
Write-Host "'Buffer Manager\Page life expectancy'"
Write-Host "'Latches\Total Latch Wait Time (ms)'"
Write-Host "'Locks(_Total)\Lock Wait Time (ms)'"
Write-Host "'Memory Manager\Free Memory (KB)'"
Write-Host "'Memory Manager\Memory Grants Pending'"
Write-Host "'SQL Statistics\Batch Requests/sec'"
Write-Host "'SQL Statistics\SQL Compilations/sec'"
Write-Host ''
$folderPath = "C:\DBA-COLETA"
if (Test-Path $folderPath -PathType Container) {
Write-Host "Folder '$folderPath' already exists."
} else {
New-Item -Path $folderPath -ItemType Directory
Write-Host "Folder '$folderPath' created."
}
$dic = $folderPath
Write-Host ''
# Deletando arquivos antigo do diretório C:\DBA-COLETA
$partialFileName = "DBA_PerfMon_counters"
$directoryPath = "$dic"
$filesToDelete = Get-ChildItem -Path $directoryPath | Where-Object { $_.Name -like "*$partialFileName*" }
if ($filesToDelete.Count -gt 0) {
foreach ($file in $filesToDelete) {
Remove-Item $file.FullName -Force
Write-Host "File '$($file.FullName)' deleted."
}
} else {
Write-Host "No files with '$partialFileName' in the name were found."
}
# Inicio do Script para iniciar uma nova coleta
$outfiles_directory = "$dic" # Where to put result files
# What to prefix result files names with
$outfile_prefix = (Get-Date -f 'yyyyMMdd_HHmmss').ToString() +"_"
$outfiles_format = 'BLG' # Output wanted format. Valid values are CSV, TSV, and BLG
$sample_interval = 2 # Sample interval time (s)
$max_samples = 10 # Number of samples value to catch
Function export_counters ()
{
Param ([string]$file_name="unknown_counters", [string[]]$counters)
$sb = {
Param ([int]$sample_interval, [int]$max_samples, [string]$outfiles_format, [string]$outfiles_directory,
[string]$outfile_prefix, [string]$file_name, [string[]]$counters)
Get-Counter -Counter $counters `
-SampleInterval $sample_interval -MaxSamples $max_samples `
| Export-Counter -FileFormat $outfiles_format `
-Path "$outfiles_directory\$($outfile_prefix)$($file_name).$($outfiles_format.ToLower())"
}
Start-Job -Name "DBA-COLETA" -ScriptBlock $sb -ArgumentList @($sample_interval, $max_samples, $outfiles_format,
$outfiles_directory, $outfile_prefix, $file_name, $counters) | Out-Null
}
# OS memory and Paging Performance counters
$os_mem_counters = @(
'\Memory\Available MBytes'
)
# OS CPU and Processor counters
$os_proc_counters = @(
'\Process(sqlservr)\% Processor Time',
'\Processor(_Total)\% Privileged Time',
'\Processor(_Total)\% Processor Time'
)
#OS DISKS
$os_logicaldisk_counters = @(
'\LogicalDisk(*)\Current Disk Queue Length',
'\LogicalDisk(*)\Avg. Disk sec/Read',
'\LogicalDisk(*)\Avg. Disk sec/Write',
'\LogicalDisk(*)\Disk Reads/sec',
'\LogicalDisk(*)\Disk Writes/sec'
)
#SQL Server
$sql = @(
$CounterSets = Get-Counter -ListSet *
$SQLCounterSets = $CounterSets | Where-Object { $_.CounterSetName -like "*SQL*" }
$FilteredPaths = $SQLCounterSets |
Select-Object -ExpandProperty Paths |
Where-Object { $_ -like "*Buffer Manager\Lazy writes/sec" -or
$_ -like "*Buffer Manager\Page reads/sec*" -or
$_ -like "*Buffer Manager\Page writes/sec" -or
$_ -like "*Buffer Manager\Page life expectancy" -or
$_ -like "*Latches\Total Latch Wait Time (ms)" -or
$_ -like "*Locks(_Total)\Lock Wait Time (ms)" -or
$_ -like "*Memory Manager\Free Memory (KB)" -or
$_ -like "*Memory Manager\Memory Grants Pending" -or
$_ -like "*SQL Statistics\Batch Requests/sec" -or
$_ -like "*SQL Statistics\SQL Compilations/sec"
}
$FilteredPaths
)
export_counters "DBA_PerfMon_counters" $($os_mem_counters + $os_proc_counters + $os_logicaldisk_counters + $sql)
#Write-Host "Para acompanhar sua coleção de monitores de desempenho, use o comando Get-Job:"
#Get-Job -State Running
#Write-Host "#################################################################################################"
#Write-Host "To clean up the jobs when done, use the 'Remove-Job -State Completed' command."
#Get-Job
#Write-Host "#################################################################################################"
#Write-Host "Limpando a fila de jobs referente ao job DBA-COLETA e completados com sucesso"
# Time de 10 segundo para limpar a fila de job completed.
Start-Sleep -Seconds 10
Get-Job | Where-Object { $_.Name -eq 'DBA-COLETA' -and $_.State -eq 'Completed' } | Remove-Job
Write-Host ''
Write-Host "#################################################################################################"
Write-Host ''
Write-Host "AGUARDE"
Write-Host ''
Write-Host "O PERFMON SERÁ ABERTO EM 30 SEGUNDOS"
Start-Sleep -Seconds 30
# Replace 'contadores' with the appropriate filename if needed
$filename = "$outfiles_directory\$($outfile_prefix)$partialFileName.$($outfiles_format.ToLower())"
if (Test-Path $filename) {
Invoke-Item $filename
} else {
Write-Host "The file '$filename' does not exist."
}
Write-Host ''
Write-Host 'Arquivo gerado no diretório' $folderPath
Write-Host ''
Write-Host 'Faça alteração das propriedades do PERFMON para que seja iniciado a coleta em tempo real'
Write-Host ''
Write-Host 'FAÇA A ALTERAÇÃO EM "PROPERTIES > SOURCE > CURRENT ACTIVITY'
Write-Host "#################################################################################################"
Write-Host ''
# Aguardar entrada do usuário antes de encerrar
Read-Host "Pressione Enter para encerrar o script..."
É necessário clicar com o botão direito sobre o arquivo e executar como : PowerShell

Ao executar o arquivo como PowerShell será aberto a tela do script com algumas informações.
Também adicionei ao script a abertura do arquivo gerado, para que fosse possível efetuar a configuração para ler em tempo real.
É exibido também a informação de como efetuar a configuração de “Current Activity”

Será aberto o “Perfomonace Monitor”, porém com os dados estáticos.

Botão direito do mouse sobre a tela “Perfomance Monitor” navegue até a opção “Properties…”

Na aba “Source” selecione a opção “Current activity” e clique em “Apply > OK” para iniciar a coleta em tempo real.

Após realizar essa configuração, o Performance Monitor iniciará a coleta de dados em tempo real, permitindo que você realize a análise necessária e também é possível remover ou adicionar novos contadores. Nesse ponto, você estará prontamente equipado para explorar e compreender os insights que esses dados podem proporcionar.
Agradeço também ao autor Joseph Herlant do script base por compartilhar o conhecimento, script no qual utilizei como base para a as alterações.
Agradeço sinceramente por dedicar seu tempo à leitura deste artigo. Espero que as informações apresentadas tenham sido úteis e esclarecedoras.