Мониторинг кластера 1С 8.3 в Zabbix

04.04.22

Администрирование - Мониторинг

На Инфостарте достаточно большое количество статей по мониторингу 1С с помощью Zabbix, однако все, которые мне попались, описывали настройку сбора данных средствами 1С (http-сервисы, регламентные задания и пр.), поэтому в данной статье поделюсь своим опытом мониторинга с точки зрения системного администратора. Для сбора данных было решено использовать скрипт на Powershell.

Скачать исходный код

Наименование Файл Версия Размер
Мониторинг кластера 1С 8.3 в Zabbix:
.7z 11,44Kb
147
.7z 11,44Kb 147 Скачать

Проверено на:  Операционная система Windows 2016/2019  Сервер приложений 1С 8.3.16/8.3.17  Windows PowerShell 5.1  На более младших версиях не проверялось, возможно потребуется доработать напильником

В качестве параметра/аргумента скрипта передаётся строка формата "Имя_сервера[:Порт]". Параметр не является обязательным и по умолчанию задает значение текущего сервера:

param (
    [System.String]$WorkBaseServer="$($env:COMPUTERNAME):1540"
)

В качестве способа получения данных с кластера 1С решил использовать "V83.COMConnector"

function Get-AgentConnection {
    param(
        [Parameter(Position=0)]
        [System.String]$WorkBaseServer=$WorkBaseServer
    )
 
    $Connector = new-object -comobject "V83.COMConnector"
    $AgentConnection = $Connector.ConnectAgent($WorkBaseServer)
    $Clusters = $AgentConnection.GetClusters()
    $Cluster = $Clusters.GetValue(0)
    $AgentConnection.Authenticate($Cluster,"","")
     
    return $Cluster, $AgentConnection
}
 
$Cluster, $AgentConnection = Get-AgentConnection

После успешного подключения к кластеру, стал актуален вопрос что именно мы хотим собрать с кластера:

  1. Сбор параметров сервера и кластера
  2. Обнаружение всех рабочих сервер в кластере и сбор их параметров
  3. Обнаружение всех рабочих процессов кластера и сбор их параметров
  4. Обнаружение информационных баз кластера 1С и сбор их параметров

Далее о каждом из блоков подробнее

 Изначально пробовал собирать данные разными скриптами и с заданной периодичностью, однако после не продолжительной эксплуатации пришел к выводу что проще осуществлять сбор сразу всех данных в JSON-формате в одном файле.

 

1. Сбор параметров сервера и кластера

1.1. Общие сведения о сервере

  • Статус службы сервера 1С

Выясняем статус службы Агента сервера.

Название службы агента сервера 1С задаем как макрос в шаблоне "{$CLUSTER1C.SERVICE.NAME}", значение по умолчанию "1C:Enterprise 8.3 Server Agent (x86-64)". Статус получаем стандартным методом Zabbix агента

service_state["{$CLUSTER1C.SERVICE.NAME}"]
  • Запущен технологический журнал

    (далее ТЖ)

Не однократно возникала ситуация, особенно со стороны не опытных специалистов, что в порыве решить задачу производительности или неизвестной ошибки запускали ТЖ по инструкции из интернет и без дополнительных настроек со сбором всего и вся, на всякий случай ("... данных много не бывает ..."  ). В таких ситуациях важно не пропустить момент и вовремя скорректировать порыв в нужном направлении.

Поскольку ТЖ запускается с пользовательскими параметрами путем помещения файла "logcfg.xml" в каталоге конфигурационных файлов системы «1С:Предприятие», мониторим его наличие через Zabbix агент:

vfs.dir.count["C:\\Program Files\\1cv8",".*logcfg.xml$",,file]
  • Мониторинг процессов настроен

По умолчанию если процессов ОС с одним и тем же именем несколько, то Performance monitor добавляет к каждому такому процессу порядковый номер (например, rphost#1). Для того, чтобы в имени счетчика отображался PID процесса необходимо отредактировать реестр, добавив в ветку HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PerfProc\Performance ключ ProcessNameFormat типа DWORD 32 бит со значением 2 (более детально на Infostart или Microsoft Docs).

Проверяем наличие ключа и его значение средствами агента запуская команду PowerShell для корректной работы мониторинга:

system.run[powershell -Command "try {Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PerfProc\Performance | Select-Object -ExpandProperty ProcessNameFormat -ErrorAction Stop}catch {0}"]
  • Скрипт сборщика данных существует

Проверяем наличие файла скрипта на сервере. Папку задаем как макрос в шаблоне "{$CLUSTER1C.SERVICE.NAME}", значение по умолчанию "C:\Program Files\Zabbix Agent\scripts". Проверка осуществляется стандартным методом Zabbix агента:

vfs.file.exists["{$CLUSTER1C.SCRIPTPATH}\get_cluster_data.ps1"]
  • Версия службы и Архитектура

Определяем версию службы, архитектуру (разрядность), а так-же путь к файлу настроек кластера.

В общих чертах последовательность: через WMI получаем путь из службы где находятся все интересующие нас данные

function Get-Service1C-Info {
    param(
        [Parameter(Position=0)]
        [System.String]$WorkBaseServer="$($env:COMPUTERNAME):1540"
    )
     
        function Filter-Service1C{
            param(
                [Parameter(Position=0)]
                [System.Array]$split_array=@(),
                [Parameter(Position=1)]
                [System.String]$filter=""
            )
            $element = $split_array | where {$_ -like "$filter *"} | Select -First 1
            $element.remove(0,$filter.length).replace('"','').Trim()
        }
     
    $WorkBaseServerName, $WorkBaseServerPort = $WorkBaseServer.Split(":")
    if(-not $WorkBaseServerPort){$WorkBaseServerPort = 1540}
    $SERVICE_1C = Get-WmiObject win32_service -ComputerName $WorkBaseServerName | Where-Object {$_.PathName -like '*\ragent.exe*' -and $_.PathName -match "-port $WorkBaseServerPort"} | Select -First 1
    $Server_Arch = (Get-WmiObject Win32_OperatingSystem -ComputerName $WorkBaseServerName).OSArchitecture
     
    $PathName_split = $SERVICE_1C.PathName.split('-')
 
    $Path_d = Filter-Service1C $PathName_split "d"
    $WorkBaseServerRegPort = Filter-Service1C $PathName_split "regport"
     
    $path = $null
    if ($PathName_split[0] -like "*\1cv82\*"){
        $path =  Join-Path -Path $Path_d -ChildPath "reg_$WorkBaseServerRegPort\1CV8Reg.lst"
    } elseif($PathName_split[0] -like "*\1cv8\*"){
        $path = Join-Path -Path $Path_d -ChildPath "reg_$WorkBaseServerRegPort\1CV8Clst.lst"
    }
     
    $bin_path = $PathName_split[0].split('\')
    $1c_arch = "32-bit"
    if($Server_Arch -match "64-\w+"){
        if($bin_path[1] -eq "Program Files"){
            $1c_arch = "64-bit"
        }
    }
     
    $1c_ver = $bin_path | Where{$_ -Match "\d+.\d+.\d+.\d+"} | Select -First 1
 
    return $1c_arch, $1c_ver, $path
}
 
$1c_arch, $1c_ver, $path_lst = Get-Service1C-Info $WorkBaseServer

$path_lst - понадобится позже (путь к файлу конфигурации кластера 1С)

 

1.2. Параметры кластера

Ранее мы уже получили объект $Cluster, содержащий требуемые нам параметры.

Однако помимо стандартных параметров кластера в систему мониторинга нам потребуется передавать сведения о сеансах кластера. Объект $Cluster соответствует типу System.__ComObject, нам потребуется конвертировать его в PSCustomObject, для этого используем командлеты ConvertTo-Json и ConvertFrom-Json:

$cluster_json = $Cluster | ConvertTo-Json | ConvertFrom-Json

Добавим параметры, соответствующие ранее полученным: Версию службы и Архитектуру

$cluster_json | Add-Member -MemberType NoteProperty -Name 'architecture' -Value $1c_arch
$cluster_json | Add-Member -MemberType NoteProperty -Name 'version' -Value $1c_ver

Отслеживаем следующие параметры кластера, которые уже присутствуют с в объекте $Cluster

  • Допустимый объем памяти

$cluster_json.MaxMemorySize
  • Записывать дамп процесса при превышении критического объема памяти

$cluster_json.KillByMemoryWithDump
  • Режим распределения нагрузки

$cluster_json.LoadBalancingMode
  • Уровень отказоустойчивости

$cluster_json.SessionFaultToleranceLevel
  • Проблемные процессы завершать через

$cluster_json.ExpirationTimeout
  • Интервал перезапуска

$cluster_json.LifeTimeLimit
  • Защищенное соединение

$cluster_json.SecurityLevel
  • IP порт

$cluster_json.MainPort
  • Принудительно завершать проблемные процессы

$cluster_json.KillProblemProcesses
  • Количество рабочих серверов

Получение данных о рабочих серверах кластера рассмотрим ниже, здесь-же просто опишу созданный элемент данных:

 

 

1.3. Сведения о сеансах кластера

Получаем сеансы кластера:

function Get-Sessions {
    param(
        $Cluster = $null,
        $AgentConnection = $null
    )
    if($AgentConnection -ne $null){
        $Sessions = $AgentConnection.GetSessions($Cluster)
        return $Sessions
    }
    return $null
}
 
$sessions = Get-Sessions $Cluster $AgentConnection

Получаем список сессий и пользователей кластера 1С:

$sessions_all = $sessions | Select-Object @{Label='infoBase'; Expression={$_.infoBase.Name}}, SessionID, AppID | Sort-Object -Property infoBase, SessionID -Unique
$users_all = $sessions | Where-Object{$_.License.LicenseType -ne $null} | Select-Object @{Label='infoBase'; Expression={$_.infoBase.Name}}, SessionID | Sort-Object -Property infoBase, SessionID -Unique
  • Количество сессий кластера

$cluster_json | Add-Member -MemberType NoteProperty -Name 'sessions_count' -Value $sessions_all.Count
  • Количество пользователей кластера

$cluster_json | Add-Member -MemberType NoteProperty -Name 'users_count' -Value $users_all.Count
  • Количество клиентов кластера

Собираем количество подключений через толстых и тонких клиентов, для нас не критичен вариант клиента.

$cluster_json | Add-Member -MemberType NoteProperty -Name 'clients_count' -Value ($sessions_all | Where-Object{$_.AppID -like "1CV8" -or $_.AppID -like "1CV8C"} | Measure | Select -Expand Count)
  • Количество WEB-сервисов кластера

$cluster_json | Add-Member -MemberType NoteProperty -Name 'ws_count' -Value ($sessions_all | Where-Object{$_.AppID -like "WSConnection"} | Measure | Select -Expand Count)
  • Количество HTTP-сервисов кластера

$cluster_json | Add-Member -MemberType NoteProperty -Name 'http_count' -Value ($sessions_all | Where-Object{$_.AppID -like "HTTPServiceConnection"} | Measure | Select -Expand Count)
  • Количество фоновых заданий кластера

$cluster_json | Add-Member -MemberType NoteProperty -Name 'jobs_count' -Value ($sessions_all | Where-Object{$_.AppID -like "BackgroundJob"} | Measure | Select -Expand Count)
  • Количество COM+ подключений кластера

$cluster_json | Add-Member -MemberType NoteProperty -Name 'com_count' -Value ($sessions_all | Where-Object{$_.AppID -like "COMConnection"} | Measure | Select -Expand Count)
  • Количество веб-клиент кластера

$cluster_json | Add-Member -MemberType NoteProperty -Name 'web_count' -Value ($sessions_all | Where-Object{$_.AppID -like "WebServerExtension"} | Measure | Select -Expand Count)

 Отдельно хочется отметить проблему, возникшую после перехода с ПРОФ редакции на КОРП - это подключение пользователей к КОРП кластеру с клиентскими ПРОФ ключами. Ситуация такова, что часть клиентских ключей находилось в серверной, а часть на рабочих местах, либо "серверах" отделов. В результате при подключении более 10 таких пользователей, функциональность КОРП пропадала. На это необходимо было реагировать как можно быстрее и желательно до того, как кластер начнет деградировать.

В нашем случае ситуация упрощалась тем, что все КОРП ключи были на 500 пользователей, все прочие - ПРОФ.

  • Пользователи ПРО

Получаем список всех пользователей с ПРОФ лицензией:

$pro_license = $sessions | Select-Object @{Label='infoBase'; Expression={$_.infoBase.Name}}, userName, Host, AppID, @{Label='License'; Expression={$_.License.ShortPresentation}} | Where-Object{$_.License -ne $null -and $_.License -notmatch "ORG8B .{3} 500" -and $_.License -notmatch "ORGL8 .{3} 1"}
$cluster_json | Add-Member -MemberType NoteProperty -Name 'prolicense_users' -Value $pro_license
  • Количество лицензий ПРОФ

$cluster_json | Add-Member -MemberType NoteProperty -Name 'prolicense_count' -Value $pro_license.Count

 

2. Обнаружение всех рабочих серверов в кластере и сбор их параметров

Обнаружение всех рабочих серверов кластера:

function Get-WorkingServers {
    param(
        $Cluster = $null,
        $AgentConnection = $null
    )
    if($AgentConnection -ne $null){
        $WorkingServers = $AgentConnection.GetWorkingServers($Cluster)
         
        return $WorkingServers
    }
    return $null
}
 
$WorkingServers = Get-WorkingServers $Cluster $AgentConnection

Данные с рабочих серверов поместим в переменную:

$workingservers_json = @()

Сохраним количество ядер для каждого из рабочих серверов кластера в отдельную переменную:

$NumberOfCores = @{}

Ниже код, каким образом получаем данные со всех серверов:

Foreach($workingserver in $WorkingServers){
 
    $NumberOfCores[$workingserver.HostName] = (Get-WmiObject -Class Win32_Processor -ComputerName $workingserver.HostName | Measure-Object NumberOfCores -Sum).Sum
    $counter_processor_total = (Get-Counter "\\$($workingserver.HostName)\238(_Total)\6").CounterSamples.CookedValue
    $counter_processor_12 = 0
    foreach($i in @(0..12)){
        $counter_processor_12 += (Get-Counter "\\$($workingserver.HostName)\238($i)\6").CounterSamples.CookedValue / 12
    }
    $workingserver | Add-Member -MemberType NoteProperty -Name 'counter_processor_total' -Value ([math]::Round($counter_processor_total,2))
    $workingserver | Add-Member -MemberType NoteProperty -Name 'counter_processor_12' -Value ([math]::Round($counter_processor_12,2))
    $workingservers_json += $workingserver | ConvertTo-Json | ConvertFrom-Json
}

$counter_processor_total - общая нагрузка на процессор

$counter_processor_12 - нагрузка на первые 12 ядер процессора

Поскольку запрос значений счетчиков монитора ресурсов требует времени на выполнение, а именно по 1 секунде на каждый счетчик. Вроде не много для одного счетчика, но по 13 секунд на каждый из серверов в кластере, в нашем случае блок выше выполнялся 40 секунд. Следовательно надо оптимизировать:

$block = {
    Param([string] $Counter)
    (Get-Counter $Counter).CounterSamples.CookedValue
}
 
Foreach($workingserver in $WorkingServers){
 
    $NumberOfCores[$workingserver.HostName] = (Get-CimInstance Win32_ComputerSystem -ComputerName $workingserver.HostName).NumberOfLogicalProcessors
    $counter_processor_total = (Get-Counter "\\$($workingserver.HostName)\238(_Total)\6").CounterSamples.CookedValue
    $counter_processor_12 = 0
 
    #Remove all jobs
    Get-Job | Remove-Job
    $MaxThreads = 12
    #Start the jobs. Max 12 jobs running simultaneously.
    foreach($i in @(0..11)){
        While ($(Get-Job -state running).count -ge $MaxThreads){
            Start-Sleep -Milliseconds 10
        }
 
        Start-Job -Scriptblock $Block -ArgumentList "\\$($workingserver.HostName)\238($i)\6"
    }
    #Wait for all jobs to finish.
    While ($(Get-Job -State Running).count -gt 0){
        start-sleep 1
    }
    #Get information from each job.
    foreach($job in Get-Job){
        $counter_processor_12 += Receive-Job -Id ($job.Id)
    }
    #Remove all jobs created.
    Get-Job | Remove-Job
 
    $workingserver | Add-Member -MemberType NoteProperty -Name 'counter_processor_total' -Value $counter_processor_total
    $workingserver | Add-Member -MemberType NoteProperty -Name 'counter_processor_12' -Value ($counter_processor_12 / 12)
    $workingservers_json += $workingserver | ConvertTo-Json | ConvertFrom-Json
}

Оптимизация времени выполнения была выполнена за счет параллельного опроса всех счетчиков (комментарии оставил из исходного кода, взял https://code-examples.net/ru/q/29a9692). После оптимизации данный блок стал выполняться не более 10 секунд.

Почему мы не использовали стандартные счетчики Zabbix для получения загрузки процессора? Потому что требовалось создать универсальный шаблон. В этом шаблоне используются данные о загрузке первых 12 ядер и общая нагрузка на процессор, для создания триггера, который проверяет не пропал-ли функционал КОРП-лицензий кластера. На этапе старта проекта - данная проблема была очень актуальна.

 

3. Обнаружение всех рабочих процессов кластера и сбор их параметров

Обнаружение всех рабочих процессов кластера:

function Get-Processes {
    param(
        $Cluster = $null,
        $AgentConnection = $null
    )
    if($AgentConnection -ne $null){
        $WorkingProcesses = $AgentConnection.GetWorkingProcesses($Cluster)
        return $WorkingProcesses
    }
    return $null
}
 
$processes = Get-Processes $Cluster $AgentConnection

Поскольку лишние параметра рабочих процессов нам не нужны, оставим только то что собираемся мониторить:

[System.Array]$processes_clone = $processes | Select PID, MainPort, StartedAt, HostName, MemorySize, connections, Enable, Running, Use, IsEnable

Дополняем каждый из процессов интересующими нас данными:

$process_id = 0
foreach($process in $processes_clone){
    $sessions_PID = $sessions | Where-Object{$_.process.PID -eq $process.PID}
    $session_mem = $sessions_PID | Sort-Object MemoryCurrent -Descending | Select @{Label='infoBase'; Expression={$_.infoBase.Name}},SessionID, AppID, userName, MemoryCurrent, cpuTimeCurrent, dbProcInfo, dbProcTook -First 1
    $session_proc_took = $sessions_PID | Sort-Object dbProcTook -Descending | Select @{Label='infoBase'; Expression={$_.infoBase.Name}},SessionID, AppID, userName, MemoryCurrent, cpuTimeCurrent, dbProcInfo, dbProcTook -First 1
    $session_CPU = $sessions_PID | Sort-Object cpuTimeCurrent -Descending | Select @{Label='infoBase'; Expression={$_.infoBase.Name}},SessionID, AppID, userName, MemoryCurrent, cpuTimeCurrent, dbProcInfo, dbProcTook -First 1
    $counter_process = (Get-Counter "\\$($process.HostName)\230(rphost_$($process.PID))\6").CounterSamples.CookedValue
 
    $processes_clone[$process_id] | Add-Member -MemberType NoteProperty -Name 'session_mem' -Value $session_mem
    $processes_clone[$process_id] | Add-Member -MemberType NoteProperty -Name 'session_proc_took' -Value $session_proc_took
    $processes_clone[$process_id] | Add-Member -MemberType NoteProperty -Name 'session_CPU' -Value $session_CPU
    $processes_clone[$process_id] | Add-Member -MemberType NoteProperty -Name 'CPU_Usage' -Value ([math]::Round($counter_process / $NumberOfCores[$process.HostName],2))
    $process_users = $sessions_PID | Where-Object{$_.License.LicenseType -ne $null} | Select-Object @{Label='infoBase'; Expression={$_.infoBase.Name}}, SessionID | Sort-Object -Property infoBase, SessionID -Unique
    $process_sessions = $sessions_PID | Select-Object @{Label='infoBase'; Expression={$_.infoBase.Name}}, SessionID | Sort-Object -Property infoBase, SessionID -Unique
 
    $processes_clone[$process_id] | Add-Member -MemberType NoteProperty -Name 'users' -Value $process_users.Count
    $processes_clone[$process_id] | Add-Member -MemberType NoteProperty -Name 'sessions' -Value $process_sessions.Count
     
    $process_id += 1
}

$sessions_PID - PID процесса в операционной системе

$session_mem - Значения параметров сеанса, потребляющего максимальный объем оперативной памяти на данном рабочем процессе

$session_proc_took - Значения параметров сеанса, у которого максимальное время соединения с СУБД с момента захвата на данном рабочем процессе

$session_CPU - Значения параметров сеанса, потребляющего максимальные процессорные мощности на данном рабочем процессе

$counter_process / $NumberOfCores[$process.HostName] - % нагрузки  на процессор вызванный данным рабочим процессом

$process_users.Count - Количество сеансов пользователей  на данном рабочем процессе

$process_sessions.Count - Количество сессий на данном рабочем процессе

 

4. Обнаружение информационных баз кластера 1С и сбор их параметров

Поскольку даже у администратора кластера 1С может не быть прав на получение параметров информационной базы, значения параметров информационных баз мы получали отличным способом от описанного выше.

Нам понадобится значение переменной $path_lst, полученной ранее. Это путь к файлу конфигурации кластера 1С, содержащий в себе информацию обо всех информационных базах кластера. Получаем интересующие нас данные через регулярное выражение:

$content = Get-Content $path_lst | Select-String "^{\w{8}-\w{4}-\w{4}-\w{4}-\w{12},.*,.*,.*,.*,.*,.*,.*,"".+SQL.*"",\d*," -Context 0,1

Теперь данные об информационных базах надо структурировать:

$BasesInfo_content = @()
 
foreach($content_info in $content){
    $info = $content_info.Line.Split(',')[0,1,2,4,5,8] | %{$_ -replace ('"','') -replace ('{','')}
 
    $BaseInfo_content = @{
    "Path" = $info[0];
    "InfoBase" = $info[1];
    "Description" = $info[2];
    "DBServerName" = $info[3];
    "DBBaseName" = $info[4]
    }
    $BaseInfo_content += ($info[5] -replace (";","`n")) | ConvertFrom-StringData
 
    $info = $content_info.Context.PostContext[0].remove(0,1).Split(',')[0,1,2]
 
    $BaseInfo_content += @{
    "Blocked" = $info[0];
    "StartBlocking" = $info[1];
    "EndBlocking" = $info[2]
    }
     
    $BasesInfo_content += $BaseInfo_content
     
}

"Path" - Идентификатор
"InfoBase" - Информационная база
"Description" - Описание
"DBServerName" - Сервер баз данных
"DBBaseName" - База данных
"Blocked" - Блокировка начала сеансов включена
"StartBlocking" - Время до начала блокировки
"EndBlocking" - Время до окончания блокировки

Остальные данные получаем через "V83.COMConnector":

function Get-InfoBases {
    param(
        $Cluster = $null,
        $AgentConnection = $null
    )
    if($AgentConnection -ne $null){
        $InfoBases = $AgentConnection.GetInfoBases($Cluster)
        return $InfoBases
    }
    return $null
}
 
$InfoBases = Get-InfoBases $Cluster $AgentConnection

Объединяем информацию о всех ИБ:

$connections_json = @()
 
foreach($InfoBase in $InfoBases){
    $connection_json = @{}
    $connection_json.Add('BaseName',$InfoBase.Name)
    $connection_json.Add('sessions',($sessions_all | Where-Object{$_.infoBase -eq $InfoBase.Name} | Measure | Select -Expand Count) )
    $connection_json.Add('users',($users_all | Where-Object{$_.infoBase -eq $InfoBase.Name} | Measure | Select -Expand Count) )
     
    $RegCount_users = $sessions | Select @{Label='infoBase'; Expression={$_.infoBase.Name}}, SessionID, userName | Where-Object{$_.infoBase -eq $InfoBase.Name -and $_.userName -match "^reg[\d]{3}"} | Group-Object userName | Select-Object Name, Count
 
    $regList = @()
 
    foreach($RegCount_user in $RegCount_users){
    $regList+=@{"username" = $RegCount_user.Name;"count" = $RegCount_user.Count}
    }
    foreach($i in (1..8)){
        if(($RegCount_users -match "reg$($i.ToString(""000""))").count -eq 0){
            $regList += @{"username" = "reg$($i.ToString(""000""))";"count" = 0}
        }
    }
    $connection_json.Add('reglaments',$regList)
     
    $connection_json += $BasesInfo_content | Where-Object{$_.infoBase -eq $InfoBase.Name}
     
    $connections_json += $connection_json
}
 
$cluster_bases_json = @{}
$cluster_bases_json.Add('list',$connections_json)

"BaseName" - Название информационной базы

"Sessions" - Количество сессий на данной информационной базе

"Users" - Количество сеансов пользователей на данной информационной базе

"reglaments" - Количество сеансов пользователей регламентных заданий на данной информационной базе

Поскольку все регламентные задания выполняются под соответствующими пользователями, имя которых задано в формате "reg000", мы собираем количество сеансов регламентных заданий и создали триггеры для тех, которые не должны запускать пользователи в рабочее время.

Объединяем все полученные данные в блоках 1-4:

$cluster_data_json = @{}
$cluster_data_json.Add('cluster',$cluster_json)
$cluster_data_json.Add('workingservers',$workingservers_json)
$cluster_data_json.Add('bases',$cluster_bases_json)
$cluster_data_json.Add('processes',$processes_clone)

Результат сохраняем в файл, который в дальнейшем будет парсить сервер Zabbix:

$cluster_data_json | ConvertTo-Json -Depth 7 -Compress | Out-File -FilePath "C:\Program Files\Zabbix Agent\Scripts\1c_server_data.json" -Force -Encoding UTF8

Детально описывать создание каждого элемента данных не будем, просто приложим "Zabbix template" и готовый скрипт PowerShell.

 

Описание шаблона

 

 

У шаблона 2 макроса с заданными значениями по умолчанию

 

 

Вся информация о кластере и его параметрах отнесена в группе элементов данных "Кластер 1С":


 

Созданы соответствующие триггеры:


 

В шаблоне создано 3 правила обнаружения для информационных баз, рабочих серверов и рабочих процессов:

 

 

Для сопровождения созданы дашборды в Zabbix. Примеры:


 

Для визуализации состояния КИС создан дашборд на Grafana:


 

Дашборд выводится на один из экранов обслуживающего подразделения. Так это выглядит у нас:


 

Планы по развитию

Наша система мониторинга продолжает развиваться, ровно, как и специалисты, ее развивающие и сопровождающие. В связи с этим в ближайшем будущем мы планируем перевод системы мониторинга с COM+ на RAS/RAC.

Zabbix Powershell Мониторинг

См. также

Конфигурация Session Monitor

Мониторинг Инструменты администратора БД Платформа 1С v8.3 Россия Платные (руб)

Конфигурация Session Monitor предназначена для мониторинга сервера 1С с целью отслеживания чрезмерной нагрузки от конкретных сеансов и скорости реакции рабочих процессов.

1500 руб.

01.12.2020    14456    35    0    

50

Мониторинг баз и серверов 1С

Журнал регистрации Мониторинг Платформа 1С v8.3 Платные (руб)

В сферу обязанностей при работе с клиентами входит контроль работы баз данных и серверов 1С. Нужно понимать что происходит в базах, есть ли ошибки, зависания у пользователей и фоновых задач, блокировки или какое-то необычное поведение системы, получение информации о причинах возникновения проблем и их оперативное устранение и т.д. В качестве источников информации использую консоль кластеров 1С, технологический журнал 1С, журналы регистрации базы 1С. Для автоматизации части операций мониторинга и анализа создал инструмент на основе 1С.

9000 руб.

28.08.2019    31229    14    21    

66

Yellow Watcher - Жёлтый наблюдатель за информационными базами

Мониторинг Платформа 1С v8.3 Абонемент ($m)

Программный комплекс мониторинга качества работы информационных баз. Статистика возникновения управляемых блокировок (тип, последняя строка контекста, контекст). Анализ длительных запросов по данным из технологического журнала. Анализ потребления ресурсов СУБД запросами и статистика ожиданий по данным из Query Store. Монитор информационной базы - получение плана запроса для сеанса 1С. Блокировки СУБД по данным block_report Extented Events, длительные запросы по данным из query_post_execution_showplan Extented Events.

1 стартмани

12.02.2024    3297    27    sdf1979    11    

53

Проверка доступа к интернет на сервере 1С

Мониторинг Платформа 1С v8.3 Конфигурации 1cv8 1С:Бухгалтерия 3.0 Абонемент ($m)

Инструмент для проверки интернет - соединения на сервере 1С

3 стартмани

23.11.2023    1948    6    1395969    4    

2

Магия преобразований Vector, часть 3: журнал регистрации + прямой экспорт ошибок в Sentry

Журнал регистрации Мониторинг Абонемент ($m)

Как легко и быстро с помощью специализированных решений собирать, парсить и передавать логи и метрики.

1 стартмани

19.11.2023    806    3    AlexSTAL    0    

6

Магия преобразований Vector, часть 2: технологический журнал

Технологический журнал Мониторинг Абонемент ($m)

Как легко и быстро с помощью специализированных решений собирать, парсить и передавать логи и метрики.

1 стартмани

15.11.2023    861    4    AlexSTAL    0    

8

Магия преобразований: ЖР, ТЖ, RAS/RAC, логи - универсальное решение Vector

Мониторинг Журнал регистрации Технологический журнал Абонемент ($m)

Как легко и быстро с помощью специализированных решений собирать, парсить и передавать логи и метрики.

1 стартмани

13.11.2023    3232    4    AlexSTAL    0    

43

Чем Service Discovery поможет 1С-нику и его клиентам?

Тестирование QA Мониторинг Бесплатно (free)

Если развернуть слепок рабочей среды в окружении для тестирования, тесты могут начать взаимодействовать с рабочим окружением. Расскажем о том, как автоматически перенастраивать базы 1С под окружение разработки или тестирования с помощью концепции Service Discovery.

08.11.2023    2998    ktb    0    

18
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. quazare 3610 04.04.22 12:28 Сейчас в теме
хороший труд. почитаю на досуге)
2. ivanov660 4347 04.04.22 15:56 Сейчас в теме
Выгляди конечно здорово, но вопросы:
1. Как ответственный реагирует на инциденты? На мониторе 200 квадратиков (не много-ли) + еще и графики воткнули.
2. Как обрабатывают критические ситуации (какой-то скрипт)?
3. vitall924 82 04.04.22 19:52 Сейчас в теме
(2)
1. Дашборд настроен по системе светофор, т.е. Зеленый - все ОК, Желтый - Предупреждение, Красный - Тревога.
Ответственный увидев что какой-то из квадратиков пожелтел или покраснел - должен отреагировать.

2. Порядок отработки стандартно таков: открывает Zabbix и смотрит значения и историю изменений, после этого отправляет запрос в поддержку, чтобы отработали с пользователем, параллельно открывает в консоль кластера 1С.
Дальнейшие шаги зависят от конкретного случая: если проблема в пользователе/отчете - либо закрываем сеанс, либо ждем и просим пользователей потерпеть; если проблема требует расследования, то подключаем ТЖ, разработчиков и пр.
4. ivanov660 4347 04.04.22 21:11 Сейчас в теме
(3) по. п1, тогда достаточно 3х квадратиков. Именно светофора из трех квадратов, которые зажигаются по нарастающей проблематике. Зеленый горит пьешь кофе. Желтый напрягся. А если видишь красный, то нажал кнопку расшифровки и начал анализировать?
Четко видна проблема, не отвлекаешься на кучу разных ситуаций, не пропустишь новое событие, эмоциональное напряжение на минимуме и человек не устает. Или список активных инцидентов, видел и такую реализацию.

В АСУ ТП, к примеру (очень похожа идея реализации диспетчерской), стараются делать меньше и только основные параметры, делать надписи крупными. Если хочешь смотреть детально, кликаешь и переходишь на детализацию. Или мониторы - это так для руководства?
5. vitall924 82 05.04.22 07:03 Сейчас в теме
(4) По количеству квадратиков - личное предпочтение каждого.
Поскольку дашборд перед глазами всегда (висит на стене телевизор), быстро привыкаешь какой сегмент отвечает за ту или иную проблему, соответственно при изменении цвета на отличный от зеленого - специалисты идут смотреть подсистему, вызвавшую проблему. Это не первый и не последний вариант дашборда: выводили именно те параметры, которые пригождались при разборе инцидентов в предыдущие периоды.
Графики не интересны пока система работает стабильно, однако если происходит какой-то сбой, часто на них можно увидеть всплеск потребления ресурсов.
Список инцидентов также есть - правый верхний угол на дашборде.

Или мониторы - это так для руководства?

Поскольку я и есть руководство, то отчасти да, для меня в том числе.
6. user612295_death4321 05.04.22 16:42 Сейчас в теме
Почему COM, а не RAS?
IT_GG; Glebis; JohnyDeath; mip128; cosmo2004; +5 Ответить
8. vitall924 82 06.04.22 13:14 Сейчас в теме
(6)
На момент старта проекта первостепенной задачей было в максимально сжатые сроки запустить отказоустойчивый кластер высокой доступности VMWare vCenter, и произвести миграцию всех виртуальных машин с Microsoft Hyper-V.
В связи с тем, что данный проект совпал в внедрением системы мониторинга Zabbix, использовались имеющиеся наработки для мониторинга Кластера 1С
7. cdiamond 233 06.04.22 11:42 Сейчас в теме
Труд хороший, но COM категорически не одобряю. Клиентам на Linux всё поднимаю. Ну пусть бухгалтер не может привыкнуть, но всю серверную часть давно уже пора переводить. А как там народ собрался с Windows жить дальше я не понимаю.
9. vitall924 82 06.04.22 13:22 Сейчас в теме
(7)
COM категорически не одобряю

Все это понимали изначально, но причину COM написал чуть выше.
А как там народ собрался с Windows жить дальше я не понимаю.

Жить можно и с Windows (Debian, CentOS и и́же с ними не сильно лучше), однака по этой причине и написал, что есть "Планы по развитию"
10. cdiamond 233 06.04.22 14:04 Сейчас в теме
(9) Вы даже суть проблемы Windows до сих пор не осознали. Вопрос не в том что лучше или хуже, а на чём можно. У меня один клиент уже пытается через Казахстан мухлевать с лицензиями, но знаю что придет сдаваться.
11. vitall924 82 06.04.22 15:36 Сейчас в теме
(10)
Проблемы лицензирования в текущих реалиях - общая проблема, а не только Windows. Я говорю не только про покупку, поддержку, но и про доступ к репозиториям.
12. cdiamond 233 06.04.22 16:14 Сейчас в теме
(11) OSS репозитарии не закрывал никто еще, но согласен, в нынешней ситуации возможно всё. Но репы Астры и прочих отечественных остаются. Не хотелось бы до этого дойти конечно, но тот кто переходит на Дебиан сейчас потом на 100% будет готов и к такому исходу.
Кстати Grafana OSS из вашего решения всё ещё доступна, но энтерпрайз версия уже нет и не берусь прогнозировать, закроют они и OSS-версию или нет. И Ubuntu то же самое
vitall924; +1 Ответить
13. mixsture 07.04.22 14:40 Сейчас в теме
(12)
Но репы Астры и прочих отечественных остаются

Имхо. Debian-based дистрибутив. Закроют доступ к дебиан => перестанет обновляться и Астра. Сомневаюсь, что ребята из Астры смогут проводить параллельно такой же объем работ, как и в дебиане. Зачем будет нужен дистрибутив без обновлений и сколько он проживет?
14. cdiamond 233 07.04.22 17:16 Сейчас в теме
(13) Астра это и есть Дебиан 10 со своими дополнительными пакетами, даже репа дебиановская напрямую подключается и никак не конфликтует. Они свой штат в 10 раз увеличивают, видимо попёр бизнес
15. user1777367 25.04.22 11:09 Сейчас в теме
Спасибо большое. Очень информативно.
16. user1777367 05.05.22 13:55 Сейчас в теме
Попробовал взять ваш скрип и темплейт. На нескольких серверах отрабатывает с ошибкой
Хэш-таблицу можно добавить только к другой хэш-таблице.
get_cluster_data.ps1:297 знак:5
17. user1777367 05.05.22 14:41 Сейчас в теме
(16)так же для vfs.file.contents ругается на "File is too large for this check."
19. vitall924 82 06.05.22 08:39 Сейчас в теме
(17)
File is too large for this check.

у данного параметра есть ограничения на размер данных 64 Kbytes.
Если не хватает этого объема, потребуется переписать на сбор данных в разные файлы, либо через регулярные выражения собирать часть файла в промежуточные переменные
20. user1777367 06.05.22 09:10 Сейчас в теме
(19)через userparameter решил собирать, там ограничение 512 кб
vitall924; +1 Ответить
18. vitall924 82 06.05.22 08:28 Сейчас в теме
Добрый день!
Какая версия ОС и Powershell?

Я так понимаю, что проблема в одной из строк формата "$cluster_data_json.Add"
Можно к добавляемому в этой строке объекту попробовать механизм, который применяли к объекту $Cluster - "$Cluster | ConvertTo-Json | ConvertFrom-Json"
21. user1777367 06.05.22 13:28 Сейчас в теме
(18)можно еще узнать, почему не выгружаются все пользователи висящие на рабочем процессе, а только один?
22. vitall924 82 11.05.22 07:19 Сейчас в теме
(21)
Доброе утро!
Выгружаются данные пользователей - потребителей определенных ресурсов, например, памяти:
 $session_mem = $sessions_PID | Sort-Object MemoryCurrent -Descending | Select @{Label='infoBase'; Expression={$_.infoBase.Name}},SessionID, AppID, userName, MemoryCurrent, cpuTimeCurrent, dbProcInfo, dbProcTook -First 1

Если необходим не предполагаемый виновник деградации производительности, а 2-3, можно сметить ограничение в отборе на "-First N" и переделать правило обнаружения.
Всё будет зависеть от задачи, которую Вы хотите решить.
23. user1777367 11.05.22 13:48 Сейчас в теме
(22) Круто. Спасибо. Последний вопрос. JSON дашборда не поделитесь?)
24. vitall924 82 12.05.22 07:36 Сейчас в теме
(23)
От него большого толку не будет, поскольку присутствуют метрики не только, указанные в данной статье.
Если отдавать модель дашборда - необходимо полностью обезличить ее, т.е. удалить все отсылки к реальным серверам/адресам, а после этого совсем не реально запустить его.
25. user1777367 12.05.22 07:40 Сейчас в теме
(24)
Не совсем понятно просто как по рабочим процессам выборка идет, они постоянно меняются и старые удаляются.
Раз привязка идет к заббиксу, там идет привязка по айтемам, что вроде как не раскрывает ничего. В любом случае спасибо.
26. vitall924 82 12.05.22 15:06 Сейчас в теме
(25)

Выбираем визуализацию "Graph (old)"

Указываем Group и Host
Application: "/Рабочий процесс .*/"
Item: "/Захвачено СУБД .*/"

Включаем легенду как таблицу, отображаем Max, Avg и Current.
Непосредственно в визуализации сортируем по Current

Дополнительно настроил Алерты, срабатывает при превышении значения 1800.
Показать


Но тут все индивидуально. Большой вопрос надо это выносить на дашборд или нет.

Пример одной визуализации:
Захвачено СУБД
27. IT_GG 43 17.05.22 12:25 Сейчас в теме
Сделал по инструкции, все работает, очень нравится, вам большое спасибо за это))
НО есть вопрос по рабочим процессам. Если в наименование рабочего процесса использовать его pid то после перезапуска процесса появляется новый Элемент данных, как их в графике указывать, если они каждый раз новые? ))) Надеюсь понятен вопрос
28. vitall924 82 17.05.22 15:50 Сейчас в теме
(27)
На примере количества соединений на рабочих процессах
В классическом графике не получится, а в "современном":
Шаблон узла сети - Имя сервера с которого выполняется сбор данных (центральный сервер)
Шаблон элемента данных - "Рабочий процесс ServerName:*/*: Соединения", где ServerName - имя рабочего сервера. Если серверов несколько я разделяю на несколько графиков.

Если сервер один, то можно и так: "Рабочий процесс *:*/*: Соединения"
29. maksa2005 534 11.05.23 14:17 Сейчас в теме
Помогите решить проблему. Что значит эта ошибка?
Cannot open file: [2] No such file or directory
Прикрепленные файлы:
31. vitall924 82 23.05.23 13:13 Сейчас в теме
(29) Добрый день, Максим.
Видимо не может найти результирующий JSON файл со значениями

Результат сохраняем в файл, который в дальнейшем будет парсить сервер Zabbix:
$cluster_data_json | ConvertTo-Json -Depth 7 -Compress | Out-File -FilePath "C:\Program Files\Zabbix Agent\Scripts\1c_server_data.json" -Force -Encoding UTF8


Путь к папке с файлом данных 1c_server_data.json указывается на вкладке "Макросы" шаблона

В моём случае:
Макрос: "{$CLUSTER1C.SCRIPTPATH}"
Значение: "C:\Program Files\Zabbix Agent\scripts"
30. maksa2005 534 11.05.23 14:18 Сейчас в теме
И подскажите как вывести 1 в 1 как у Вас график? или надо самостоятельно добавлять его в панель zabbix?
32. vitall924 82 23.05.23 13:25 Сейчас в теме
(30) Графики и панели я не включал в шаблон, поэтому делать на свой вкус.
Я делал для панели у дежурных администраторов в Grafana, а для сопровождения различные дашборды в Zabbix

Для примера приложил настройки графика "PRHOST % загруженности процессора"

Набор данных - имя центрального сервера кластера, на котором вы осуществляете сбор.
шаблон элемента данных - метрика, значения которой надо вывести. я вывожу все метрики по шаблону "Рабочий процесс {SERVERNAME}:*/*: % загруженности процессора"
Прикрепленные файлы:
33. maksa2005 534 23.05.23 14:51 Сейчас в теме
(32)Долго ждал ответ, пришлось данные брать по api с разных баз, но где- то средствами zabbix)
Но путь по созданию графиков Вы мне дали, конечно не grafna, но можно увидеть то что хочу видеть + тригеры в телегу. Спасибо Вам, за статью и толчок) Много чего увидел, оптимизировал, усовершенствовал.
Прикрепленные файлы:
vitall924; +1 Ответить
34. Tiotimolin 27.03.24 12:46 Сейчас в теме
Добрый день, Виталий.
А как быть в случае, когда кластер требует авторизации?
Есть ли макросы, с помощью которых можно передать из Заббикса?
Эта ошибка говорит именно об этом?

Ошибка при сборе данных:
new-object : Не удалось получить фабрику класса COM для компонента с CLSID {181E893D-73A4-4722-B61D-D604B3D67D47} из-за следующей ошибки: 8000401a Процесс сервера не мож
ет быть запущен, так как указана неправильная идентификация. Проверьте правильность указания имени пользователя и пароля. (Исключение из HRESULT: 0x8000401A).
C:\Program Files\Zabbix Agent\scripts\get_cluster_data.ps1:17 знак:15
Прикрепленные файлы:
35. Tiotimolin 27.03.24 12:51 Сейчас в теме
Настраивал на сервере 1с без авторизации и столкнулся с ошибкой
ConvertFrom-StringData - Unrecognized escape sequence \C.
Пришлось немного изменить скрипт, экранировав "\"
Строка 263
$BaseInfo_content += ($info[5] -replace ";","`n" -replace "\\","\\\\") | ConvertFrom-StringData
После этого данные стали парситься правильно.
36. vitall924 82 28.03.24 07:20 Сейчас в теме
(34)
Доброе утро, Фёдор.
Есть 2 варианта:
1. Настроить запуск службы Заббикса от доменного/локального пользователя с правами администратора кластера.
2. Запускать скрипт Планировщиком Windows от имени доменного/локального пользователя с правами администратора кластера.

Мы пошли по 2 пути.
37. nick_salander 18.04.24 09:50 Сейчас в теме
 $NumberOfCores[$workingserver.HostName] = (Get-CimInstance Win32_ComputerSystem -ComputerName $workingserver.HostName).NumberOfLogicalProcessors


Данная конструкция при указании параметра -ComputerName организует сессию ws-managment, если у вас не настроен winrm то конструкция не сработает, далее по коду
$processes_clone[$process_id] | Add-Member -MemberType NoteProperty -Name 'CPU_Usage' -Value ([math]::Round($counter_process / $NumberOfCores[$process.HostName],2))
произойдет деление на непонятно что и итоговый JSON будет кривым, в результате не отработает LLD.
38. vechiy 35 26.04.24 12:33 Сейчас в теме
можно ли с помощью данного мониторинга смотреть (и оповещать) по условию - например, захваченоСУБД на одном из сеансов превысило 100.000?
Оставьте свое сообщение