📜 ⬆️ ⬇️

Monitoring the exchange of a distributed database 1C by means of Zabbix

Greetings habrosoobschestvo! The use of the yellow program is very popular in Russia. Unfortunately, the stability of work leaves much to be desired. Many system administrators (who are part-time administrators / programmers of 1C) solve the problems of monitoring daily processing and constantly working 1C downloads — they set up an email alert. If something bad happens, an email is sent, the administrator logs on to the server, looks for an error, fixes a profit. But this is not an option for the lazy correct administrators!
On the Internet for monitoring 1C there are only templates for monitoring the 1C service. Let's try to expand the monitoring area.
In this article we will try to tell you how to solve the following problems:



In large organizations, 1C programmers / administrators are involved in monitoring 1C. The system administrator (if there is such a separate position, but we have) monitors only his hardware / programs and 1C does not really like it. We have overcome this barrier, we offer to overcome it and you :)

About organization


A large retail network, we use as STU 1C. Many objects, everywhere there must be an exchange with the central base. On servers of objects constantly running 1C are spinning (exchange with cash registers and scales).
Additional conditions:


Solution Architecture


We give the general scheme of work, then we will analyze each part.

Zabbix

Template
<?xml version="1.0" encoding="UTF-8"?> <zabbix_export> <version>2.0</version> <date>2015-06-05T11:21:26Z</date> <groups> <group> <name>My Templates</name> </group> </groups> <templates> <template> <template>1C Habr template</template> <name>1C Habr template</name> <groups> <group> <name>My Templates</name> </group> </groups> <applications> <application> <name>1 </name> </application> </applications> <items> <item> <name>1  </name> <type>2</type> <snmp_community/> <multiplier>0</multiplier> <snmp_oid/> <key>exchange.status</key> <delay>0</delay> <history>90</history> <trends>365</trends> <status>0</status> <value_type>3</value_type> <allowed_hosts/> <units/> <delta>0</delta> <snmpv3_contextname/> <snmpv3_securityname/> <snmpv3_securitylevel>0</snmpv3_securitylevel> <snmpv3_authprotocol>0</snmpv3_authprotocol> <snmpv3_authpassphrase/> <snmpv3_privprotocol>0</snmpv3_privprotocol> <snmpv3_privpassphrase/> <formula>1</formula> <delay_flex/> <params/> <ipmi_sensor/> <data_type>0</data_type> <authtype>0</authtype> <username/> <password/> <publickey/> <privatekey/> <port/> <description/> <inventory_link>0</inventory_link> <applications> <application> <name>1 </name> </application> </applications> <valuemap> <name>1Ok / 0Fail</name> </valuemap> </item> <item> <name> 1   </name> <type>2</type> <snmp_community/> <multiplier>0</multiplier> <snmp_oid/> <key>exchange.restart</key> <delay>0</delay> <history>90</history> <trends>365</trends> <status>0</status> <value_type>3</value_type> <allowed_hosts/> <units/> <delta>0</delta> <snmpv3_contextname/> <snmpv3_securityname/> <snmpv3_securitylevel>0</snmpv3_securitylevel> <snmpv3_authprotocol>0</snmpv3_authprotocol> <snmpv3_authpassphrase/> <snmpv3_privprotocol>0</snmpv3_privprotocol> <snmpv3_privpassphrase/> <formula>1</formula> <delay_flex/> <params/> <ipmi_sensor/> <data_type>0</data_type> <authtype>0</authtype> <username/> <password/> <publickey/> <privatekey/> <port/> <description/> <inventory_link>0</inventory_link> <applications> <application> <name>1 </name> </application> </applications> <valuemap> <name>1C Restart</name> </valuemap> </item> </items> <discovery_rules/> <macros/> <templates/> <screens/> </template> </templates> <triggers> <trigger> <expression>{1C Habr template:exchange.status.nodata(30m)}=1&{1C Habr template:exchange.status.time()}>084500&{1C Habr template:exchange.status.time()}<200000</expression> <name>{HOST.NAME} 1C     30 </name> <url/> <status>0</status> <priority>1</priority> <description/> <type>0</type> <dependencies/> </trigger> <trigger> <expression>{1C Habr template:exchange.restart.count(1h,100)}>2</expression> <name>{HOST.NAME} 1C      3   1 </name> <url/> <status>0</status> <priority>1</priority> <description/> <type>0</type> <dependencies/> </trigger> <trigger> <expression>{1C Habr template:exchange.restart.last(0)}=2</expression> <name>{HOST.NAME} 1C     !</name> <url/> <status>0</status> <priority>2</priority> <description/> <type>0</type> <dependencies/> </trigger> </triggers> </zabbix_export> 


There are two items in the template:
  1. 1C Exchange status (exchange.status) - here 1C sends data about what works. Triggers:
    • {HOST.NAME} 1C The exchange was not more than 30 minutes - the trigger on which the restart action 1C starts. Limited in time, set up this part in the trigger expression for yourself
      & {1C Habr template: exchange.status.time ()}> 084500 & {1C Habr template: exchange.status.time ()} <200000

  2. Restart 1C Exchange with the Center (exchange.restart) - only the script sends the value here
    • {HOST.NAME} 1C restart Exchange with the Center Error! - the trigger is triggered, the script could not work correctly (there are no necessary tasks or other errors when completing 1C)
    • {HOST.NAME} 1C restart Exchange with the Center more than 3 times in 1 hour - it is necessary to determine the number of restarts, too frequent restarts indicate incorrect operation of the system


Action

Create an action (and when in zabbix will export all settings ...):



As you can see, the launch occurs 3 times (immediately after the trigger, after 30 and 40 minutes), if the trigger does not disappear. For confidence.
Enable command execution

On each server you need to add a line in zabbix_agentd.conf
EnableRemoteCommands = 1

1C

1C sends data to Zabbix using zabbix_sender over HTTP . You can do it through zabbix_sender.exe. In 8.1 there are problems with http requests with several GET parameters, therefore we give our working code. In 8.2 they say everything is good, you can use standard methods.
In 1C constantly working, the request should be sent once in N-minutes, in periodic launches - on completion (if they are short-lived). 1C tells Zabbix that it works and do not touch it. As soon as it stops reporting, we kill all the processes and launch a new one.
CODE 1C 8.1
  (, )   = (());  = "http://zabbix.example.com/zabbix_sender/index.php?server=" +  + "&key=" +  + "&value=" + ;  WinHttp =  COM("WinHttp.WinHttpRequest.5.1"); WinHttp.Option(2,"Windows-1251"); WinHttp.Open("GET", , 0); WinHttp.SetRequestHeader("Accept-Language", "ru"); WinHttp.SetRequestHeader("Accept-Charset","Windows-1251"); WinHttp.setRequestHeader("Content-Language", "ru"); WinHttp.setRequestHeader("Content-Charset", "Windows-1251"); WinHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=Windows-1251"); WinHttp.Send();  = WinHttp.ResponseText();   ; ;   = "OK"   ;   ; ;  


Windows

Create a file C: \ ZBX \ restart-1c.ps1 with the following contents:
restart-1c.ps1
 param([string]$programm_name="nul") Try{ $servername=$env:computername $zabbixhost="zabbix.example.com" $zabbix_key=$programm_name+".restart" switch ($programm_name) { "exchange" { $window_name="1: - :  " $schedule_name="" } default { throw "No param" } } ###################  ,   ################### Get-Process | Where-Object {$_.MainWindowTitle -eq $window_name} | Stop-Process -Force Sleep 10; schtasks /end /TN $schedule_name Sleep 10; schtasks /run /TN $schedule_name if ($LastExitCode -ne 0){ throw "LastExitCode -ne 0" } #Send to Zabbix $get_str1="https://$zabbixhost/zabbix_sender/index.php?server=$servername&key=$zabbix_key$vm_name&value=100" $wc = New-Object system.Net.WebClient; $Result = $wc.downloadString("$get_str1") } Catch { #Send to Zabbix Error $get_str2="https://$zabbixhost/zabbix_sender/index.php?server=$servername&key=$zabbix_key$vm_name&value=2" $wc = New-Object system.Net.WebClient; $Result = $wc.downloadString("$get_str2") } 


And import the task to the server. It runs the powershell script (unfortunately, commands with a length of 255 characters are limited in zabbix_action, so it is impossible to transfer the script right away):
Scheduler
 <?xml version="1.0" encoding="UTF-16"?> <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Author>example/username</Author> </RegistrationInfo> <Triggers /> <Principals> <Principal id="Author"> <UserId>Server\username</UserId> <LogonType>InteractiveToken</LogonType> <RunLevel>HighestAvailable</RunLevel> </Principal> </Principals> <Settings> <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>false</StartWhenAvailable> <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> <IdleSettings> <Duration>PT10M</Duration> <WaitTimeout>PT1H</WaitTimeout> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <AllowStartOnDemand>true</AllowStartOnDemand> <Enabled>true</Enabled> <Hidden>false</Hidden> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>P3D</ExecutionTimeLimit> <Priority>7</Priority> </Settings> <Actions Context="Author"> <Exec> <Command>powershell.exe</Command> <Arguments>-windowstyle hidden -nologo -NonInteractive -File "C:\ZBX\restart-1c.ps1" exchange</Arguments> </Exec> </Actions> </Task> 


A prerequisite is that the task in the scheduler must be created under the user, under which 1C runs. We have a dedicated user who is logged in to the system.
Excuses

We had to resort to such a mechanism (it was impossible to simply make Stop-Process 1cv8.exe ), because On the server, many running 1Cs are running, which work and should not be restarted just like that, unnecessarily.
If you have done everything correctly (and I described it correctly), then now the program will restart if it suddenly stops working (with the completion of all tasks and .exe).
')
Perhaps you have any questions (to describe the technical solution is not my strong point) - I will be glad to answer, write in a personal. We also implemented an exchange control mechanism with each cash desk and with each scale (using Low-Level Detection and non-dynamic updating of the 1C configuration with one button, maybe it would be useful for someone to write an article about this)
Constructive criticism, advice :)
My self-esteem. I am interested to know when decisions help someone, so if it’s not difficult and if you use part or complete solution, click the button in the survey, thanks!

Source: https://habr.com/ru/post/259601/


All Articles