Zabbix: LLD monitoring of disks without UserParameter and agent scripts
The idea is simple: the Zabbix server will receive everything from smartmontools through external processing and zabbix_get, parse it and pass it on to dependent elements (appeared in Zabbix 3.4). Thus, not only the number of accesses to the monitored server is reduced, but its resources are not spent, since parsing occurs on the side of the Zabbix server.
One limitation at the moment: only monitoring drives in / dev / sd * format. The format / dev / csmi *, * (Intel Matrix RAID) is not supported due to the fact that zabbix_get considers the comma as the second argument. Correct me if I am wrong.
What will be needed for implementation:
- Template
- Script
- zabbix_get on the server
- smartmontools on agents
Agent setup
The only thing that deserves attention here is the need to uncomment the EnableRemoteCommands = 1 line , otherwise the agent will not be able to accept commands.
Smartmontools
The installation is trivial and will not be considered, however, for Linux there is one need: in order to start without sudo , you need to set the SUID bit to the smartctl file. For Ubuntu, this is sudo chmod u + s / usr / sbin / smartctl .
Script
Depending on your zabbix_server.conf configuration file, you need to put this script in the appropriate directory on the Zabbix server. The default for Ubuntu is / usr / lib / zabbix / externalscripts . Do not forget to give the file permission to execute - sudo chmod 775 /usr/lib/zabbix/externalscripts/smartctl.sh .
| #! / bin / bash | |
| # 2017/12/07 AcidVenom v1.0 | |
| # Скрипт мониторинга HDD с LLD для Zabbix (серверный вариант) | |
| # Автообнаружение дисков | |
| # Ключ: discovery | |
| IFS=$'\n' | |
| JSON="{\"data\":[" | |
| SEP="" | |
| if [[ $2="discovery" ]] | |
| then | |
| get=`zabbix_get -s $1 -k system.run["smartctl --scan-open"] | grep "/dev/sd"` | |
| forhddin$get | |
| do | |
| DISKID=`echo $hdd| grep "/dev/sd"| sed "s/\/dev\///"| cut -c 1-3` | |
| if [[ `zabbix_get -s $1 -k system.run["smartctl -i /dev/$DISKID"] | grep "SMART support is: Enabled"`!="" ]] | |
| then | |
| JSON=$JSON"$SEP{\"{#DISKID}\":\"$DISKID\"}" | |
| SEP=", " | |
| fi | |
| done | |
| JSON=$JSON"]}" | |
| echo$JSON | |
| # Получение информации о дисках | |
| # Ключи: info и attr | |
| else | |
| if [[ $3="info" ]] | |
| then | |
| get=`zabbix_get -s $1 -k system.run["smartctl -x /dev/$2"]` | |
| foroutin$get | |
| do | |
| echo$out | |
| done | |
| elif [[ $3="attr" ]] | |
| then | |
| get=`zabbix_get -s $1 -k system.run["smartctl -A /dev/$2"]` | |
| foroutin$get | |
| do | |
| echo$out | |
| done | |
| fi | |
| fi |
Template
Template exported from version 3.4.4.
The following elements are already present in the template: model, family, serial number, disk size, SMART status; as well as SMART values 3, 5, 7, 9, 10, 190 (194), 196, 197, 198, 199. There are 3 triggers: two indicate high temperatures and one more about bad SMART.
| <?xml version="1.0" encoding="UTF-8"?> | |
| <zabbix_export> | |
| <version>3.4</version> | |
| <date>2017-12-27T05:26:57Z</date> | |
| <groups> | |
| <group> | |
| <name>Templates</name> | |
| </group> | |
| </groups> | |
| <templates> | |
| <template> | |
| <template>Hardware - HDD</template> | |
| <name>Hardware - HDD</name> | |
| <description>Шаблон мониторинга HDD c LLD. | |
| Серверный вариант | |
| | |
| Необходимые компоненты: | |
| smartctl.sh -> /usr/lib/zabbix/externalscripts/ | |
| smartmontools</description> | |
| <groups> | |
| <group> | |
| <name>Templates</name> | |
| </group> | |
| </groups> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <items/> | |
| <discovery_rules> | |
| <discovery_rule> | |
| <name>Обнаружение дисков</name> | |
| <type>10</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.sh[{HOST.CONN},discovery]</key> | |
| <delay>1h</delay> | |
| <status>0</status> | |
| <allowed_hosts/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <filter> | |
| <evaltype>0</evaltype> | |
| <formula/> | |
| <conditions/> | |
| </filter> | |
| <lifetime>1d</lifetime> | |
| <description>Обнаружение подключенных дисков.</description> | |
| <item_prototypes> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - Номинальная емкость</name> | |
| <type>18</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.capacity.[{#DISKID}]</key> | |
| <delay>0</delay> | |
| <history>90d</history> | |
| <trends>0</trends> | |
| <status>0</status> | |
| <value_type>1</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
| <logtimefmt/> | |
| <preprocessing> | |
| <step> | |
| <type>5</type> | |
| <params>User Capacity: .*\[(.*)\] | |
| \1</params> | |
| </step> | |
| </preprocessing> | |
| <jmx_endpoint/> | |
| <application_prototypes/> | |
| <master_item_prototype> | |
| <key>smartctl.sh[{HOST.CONN},{#DISKID},info]</key> | |
| </master_item_prototype> | |
| </item_prototype> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - Семейство</name> | |
| <type>18</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.family.[{#DISKID}]</key> | |
| <delay>0</delay> | |
| <history>90d</history> | |
| <trends>0</trends> | |
| <status>0</status> | |
| <value_type>1</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
| <logtimefmt/> | |
| <preprocessing> | |
| <step> | |
| <type>5</type> | |
| <params>Model Family: (.*) | |
| \1</params> | |
| </step> | |
| </preprocessing> | |
| <jmx_endpoint/> | |
| <application_prototypes/> | |
| <master_item_prototype> | |
| <key>smartctl.sh[{HOST.CONN},{#DISKID},info]</key> | |
| </master_item_prototype> | |
| </item_prototype> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - Версия FW</name> | |
| <type>18</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.fw.[{#DISKID}]</key> | |
| <delay>0</delay> | |
| <history>90d</history> | |
| <trends>0</trends> | |
| <status>0</status> | |
| <value_type>1</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
| <logtimefmt/> | |
| <preprocessing> | |
| <step> | |
| <type>5</type> | |
| <params>Firmware Version: (.*) | |
| \1</params> | |
| </step> | |
| </preprocessing> | |
| <jmx_endpoint/> | |
| <application_prototypes/> | |
| <master_item_prototype> | |
| <key>smartctl.sh[{HOST.CONN},{#DISKID},info]</key> | |
| </master_item_prototype> | |
| </item_prototype> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - Модель</name> | |
| <type>18</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.model.[{#DISKID}]</key> | |
| <delay>0</delay> | |
| <history>90d</history> | |
| <trends>0</trends> | |
| <status>0</status> | |
| <value_type>1</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
| <logtimefmt/> | |
| <preprocessing> | |
| <step> | |
| <type>5</type> | |
| <params>Device Model: (.*) | |
| \1</params> | |
| </step> | |
| </preprocessing> | |
| <jmx_endpoint/> | |
| <application_prototypes/> | |
| <master_item_prototype> | |
| <key>smartctl.sh[{HOST.CONN},{#DISKID},info]</key> | |
| </master_item_prototype> | |
| </item_prototype> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - Серийный номер</name> | |
| <type>18</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.serial.[{#DISKID}]</key> | |
| <delay>0</delay> | |
| <history>90d</history> | |
| <trends>0</trends> | |
| <status>0</status> | |
| <value_type>1</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
| <logtimefmt/> | |
| <preprocessing> | |
| <step> | |
| <type>5</type> | |
| <params>Serial Number: (.*) | |
| \1</params> | |
| </step> | |
| </preprocessing> | |
| <jmx_endpoint/> | |
| <application_prototypes/> | |
| <master_item_prototype> | |
| <key>smartctl.sh[{HOST.CONN},{#DISKID},info]</key> | |
| </master_item_prototype> | |
| </item_prototype> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - SMARTCTL Attr</name> | |
| <type>10</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.sh[{HOST.CONN},{#DISKID},attr]</key> | |
| <delay>10m</delay> | |
| <history>1h</history> | |
| <trends>0</trends> | |
| <status>0</status> | |
| <value_type>4</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
| <logtimefmt/> | |
| <preprocessing/> | |
| <jmx_endpoint/> | |
| <application_prototypes/> | |
| <master_item_prototype/> | |
| </item_prototype> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - SMARTCTL Info</name> | |
| <type>10</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.sh[{HOST.CONN},{#DISKID},info]</key> | |
| <delay>10m</delay> | |
| <history>1h</history> | |
| <trends>0</trends> | |
| <status>0</status> | |
| <value_type>4</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
| <logtimefmt/> | |
| <preprocessing/> | |
| <jmx_endpoint/> | |
| <application_prototypes/> | |
| <master_item_prototype/> | |
| </item_prototype> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - SMART - Spin-Up Time [3]</name> | |
| <type>18</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.smart.3.[{#DISKID}]</key> | |
| <delay>0</delay> | |
| <history>90d</history> | |
| <trends>365d</trends> | |
| <status>0</status> | |
| <value_type>3</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
| <logtimefmt/> | |
| <preprocessing> | |
| <step> | |
| <type>5</type> | |
| <params>3 Spin_Up_Time.* - (.*) | |
| \1</params> | |
| </step> | |
| </preprocessing> | |
| <jmx_endpoint/> | |
| <application_prototypes/> | |
| <master_item_prototype> | |
| <key>smartctl.sh[{HOST.CONN},{#DISKID},attr]</key> | |
| </master_item_prototype> | |
| </item_prototype> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - SMART - Reallocated Sector Count [5]</name> | |
| <type>18</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.smart.5.[{#DISKID}]</key> | |
| <delay>0</delay> | |
| <history>90d</history> | |
| <trends>365d</trends> | |
| <status>0</status> | |
| <value_type>3</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
| <logtimefmt/> | |
| <preprocessing> | |
| <step> | |
| <type>5</type> | |
| <params>5 Reallocated_Sector.* - (.*) | |
| \1</params> | |
| </step> | |
| </preprocessing> | |
| <jmx_endpoint/> | |
| <application_prototypes/> | |
| <master_item_prototype> | |
| <key>smartctl.sh[{HOST.CONN},{#DISKID},attr]</key> | |
| </master_item_prototype> | |
| </item_prototype> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - SMART - Seek Error Rate [7]</name> | |
| <type>18</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.smart.7.[{#DISKID}]</key> | |
| <delay>0</delay> | |
| <history>90d</history> | |
| <trends>365d</trends> | |
| <status>0</status> | |
| <value_type>3</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
| <logtimefmt/> | |
| <preprocessing> | |
| <step> | |
| <type>5</type> | |
| <params>7 Seek_Error_Rate.* - (.*) | |
| \1</params> | |
| </step> | |
| </preprocessing> | |
| <jmx_endpoint/> | |
| <application_prototypes/> | |
| <master_item_prototype> | |
| <key>smartctl.sh[{HOST.CONN},{#DISKID},attr]</key> | |
| </master_item_prototype> | |
| </item_prototype> | |
| <item_prototype> | |
| <name>Диск {#DISKID} - SMART - Power-on Time Count [9]</name> | |
| <type>18</type> | |
| <snmp_community/> | |
| <snmp_oid/> | |
| <key>smartctl.smart.9.[{#DISKID}]</key> | |
| <delay>0</delay> | |
| <history>90d</history> | |
| <trends>365d</trends> | |
| <status>0</status> | |
| <value_type>3</value_type> | |
| <allowed_hosts/> | |
| <units/> | |
| <snmpv3_contextname/> | |
| <snmpv3_securityname/> | |
| <snmpv3_securitylevel>0</snmpv3_securitylevel> | |
| <snmpv3_authprotocol>0</snmpv3_authprotocol> | |
| <snmpv3_authpassphrase/> | |
| <snmpv3_privprotocol>0</snmpv3_privprotocol> | |
| <snmpv3_privpassphrase/> | |
| <params/> | |
| <ipmi_sensor/> | |
| <authtype>0</authtype> | |
| <username/> | |
| <password/> | |
| <publickey/> | |
| <privatekey/> | |
| <port/> | |
| <description/> | |
| <inventory_link>0</inventory_link> | |
| <applications> | |
| <application> | |
| <name>Жесткие диски</name> | |
| </application> | |
| </applications> | |
| <valuemap/> | |
Read Next UART-CLI for debugging MCU firmwareUART-CLI simplifies diagnostics of embedded systems: GPIO, logs, tests without JTAG. Instructions for middle/senior dev. Master it for quick bug fixes. Xbuild MCU for VSCode and STM32Configuring Xbuild MCU in VSCode for embedded development on STM32: auto-generation, CubeMX import, Xmake build. Instructions for middle/senior dev. Start migration from CubeIDE. AI Text Problems and Their Editing for ITBreaking down why AI-generated texts annoy developers: templates, fluff, empty confidence. Strategies for deep editing for dense content. Learn how to refine drafts. SMBHs in dwarf galaxies: JWST at z=0.7JWST Discoveries: supermassive black holes in Pelia and Nelei with M_BH up to 60% M_gal. SED analysis, super-Eddington accretion. Explore contradictions with local models. Detailed breakdown for astrophysicists. DreamService and Compose in Android 4.2+Learn how to integrate Jetpack Compose into DreamService for UI in Android sleep mode. Step-by-step guide with code, lifecycle implementation. For middle/senior dev. Manticore Hybrid Search: BM25 + KNNLearn how hybrid search in Manticore Search combines BM25 and KNN for exact matches and semantics. Code examples, RRF, settings. Boost recall in RAG and e-commerce. Type-safe PHP arrays: +4x speedAccelerating sbwerewolf/language-specific library by 4 times. Benchmarks against wplake/typed, code examples of chainable API. For PHP developers: readability vs performance. Study the optimizations. CSS Doom: rendering the game without CanvasLearn how to implement Doom using pure CSS with 3D div elements. Technical details on transform, custom properties, and WAD file adaptation. For middle/senior developers. Neural networks for aviation control: tests by the State Research Institute of Aviation Systems (GosNIIAS) in RussiaGosNIIAS tests neural networks to replace the co-pilot. Learn about the SPO program, digital twins, and forecasts for aviation until 2030. Read the analysis. AI GPS Predicts Drugs for Liver CancerGPS Platform Analyzes Molecules to Find Treatments for HCC and IPF. Tests on Mice and Tissues Confirmed Efficacy. Open the Code and Apply to Your Tasks in drug discovery. Recently ViewedShare this article |