Ad Widget

Collapse

Lld и русский язык

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • akel
    Junior Member
    • May 2014
    • 1

    #1

    Lld и русский язык

    Здравствуйте.
    Возникла следующая проблема.

    Установлен zabbix 2.2.0. По инструкции был создан шаблон и настроен zabbix-agent.

    Introduction When monitoring Windows servers and services it would be really handy to have a check to see if all the services that are registered with the system to automatically start up during boot, are also started. You can use the item services[automatic] and compare its results with the output of the item services[automatic,started] using […]


    Но все русские буквы отображаются знаками вопроса или иероглифами.
    При указании в скрипте параметра:

    [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("utf-8")

    zabbix начинает ругаться на неверный JSON (value should be a json object)
    хотя если запрашивать данные через zabbix_get, то данные приходят в нормальном виде и русские буквы отображаются корректно.
  • skokhanovskiy
    Junior Member
    • Apr 2015
    • 3

    #2
    akel, приветствую.

    Столкнулся с аналогичной проблемой. Нашлось какое-то решение?

    Comment

    • skokhanovskiy
      Junior Member
      • Apr 2015
      • 3

      #3
      В общем, вкратце резюмирую свои двухдневные изыскания. На текущий момент в zabbix нельзя добавить свое собственное низкоуровневое обнаружение элементов, если в этом обнаружении есть элементы с non-ASCII символами. Кириллические, к сожалению, входят в их число.

      При выводе powershell даже в случае использования

      Code:
      [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($False) # Или $True, не важно
      будет добавлять в начало вашего потока BOM, который не нравится zabbix. В результате, вы получите

      Code:
      Value should be a JSON object
      Вызов принят. Я перепробовал много различных вариантов, которые не привели к желаемому результату. Напоследок, в качестве проверки, я направил вывод моего powershell скрипта в UTF8 файл без BOM (это powershell, так он может), a правило обнаружения изменил на

      Code:
      vfs.file.contents["Path\To\MyFile",utf8]
      Аналогично поступку топик-стартера, я проверил вывод элемента данных с помощью zabbix_get - все элементы в консоли отображались корректно. Но на сервере я получил элементы данных, содержащие ??????????? (вопросительные знаки) вместо кириллических символов.

      На этом, я думаю, в принципе, можно остановиться.

      Zabbix Server: v2.4.3 (revision 51175) (15 December 2014)
      Zabbix Agent: v2.4.2
      OS: Windows 6.1.7601 Microsoft Windows Server 2008 R2 Enterprise Edition Service Pack 1 x64

      Comment

      • cardinal83
        Junior Member
        • Apr 2015
        • 18

        #4
        Тоже убил кучу времени чтобы победить вопросики, но они победили меня.

        Comment

        • skokhanovskiy
          Junior Member
          • Apr 2015
          • 3

          #5
          Путь к успеху

          База данных

          Для начала, необходимо убедиться, что кириллические значения не испортятся непосредственно в базе данных. Для этого, в запущенной консоли mysql выполняем следующие проверки.

          Сначала проверяем кодировку по-умолчанию для базы данных. Она должны быть равна utf8.

          Code:
          SELECT default_character_set_name FROM information_schema.SCHEMATA 
          WHERE schema_name = "zabbix";
          Code:
          +----------------------------+
          | default_character_set_name |
          +----------------------------+
          | utf8                       |
          +----------------------------+
          Далее, проверяем кодировку таблиц и полей. Кодировка везде должна быть utf8.

          Code:
          USE zabbix;
          SELECT TABLE_SCHEMA,
                 TABLE_NAME,
                 CCSA.CHARACTER_SET_NAME AS DEFAULT_CHAR_SET,
                 COLUMN_NAME,
                 COLUMN_TYPE,
                 C.CHARACTER_SET_NAME
            FROM information_schema.TABLES AS T
            JOIN information_schema.COLUMNS AS C USING (TABLE_SCHEMA, TABLE_NAME)
            JOIN information_schema.COLLATION_CHARACTER_SET_APPLICABILITY AS CCSA
                 ON (T.TABLE_COLLATION = CCSA.COLLATION_NAME)
           WHERE TABLE_SCHEMA=SCHEMA()
             AND C.DATA_TYPE IN ('enum', 'varchar', 'char', 'text', 'mediumtext', 'longtext')
           ORDER BY TABLE_SCHEMA,
                    TABLE_NAME,
                    COLUMN_NAME;
          Code:
          +--------------+-----------------------+------------------+------------------------+---------------+--------------------+
          | TABLE_SCHEMA | TABLE_NAME            | DEFAULT_CHAR_SET | COLUMN_NAME            | COLUMN_TYPE   | CHARACTER_SET_NAME |
          +--------------+-----------------------+------------------+------------------------+---------------+--------------------+
          | zabbix       | acknowledges          | utf8             | message                | varchar(255)  | utf8               |
          | zabbix       | actions               | utf8             | def_longdata           | text          | utf8               |
          | zabbix       | actions               | utf8             | def_shortdata          | varchar(255)  | utf8               |
          | ...          | ...                   | ...              | ...                    | ...           | ...
          | zabbix       | usrgrp                | utf8             | name                   | varchar(64)   | utf8               |
          | zabbix       | valuemaps             | utf8             | name                   | varchar(64)   | utf8               |
          +--------------+-----------------------+------------------+------------------------+---------------+--------------------+
          Также, необходимо убедиться, что для всех таблиц указан правильный collation - utf8_general_ci.

          Code:
          USE zabbix;
          SHOW TABLE STATUS;
          Code:
          +-----------------------+--------+---------+------------+-----------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
          | Name                  | Engine | Version | Row_format | Rows      | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time | Check_time | Collation       | Checksum | Create_options | Comment |
          +-----------------------+--------+---------+------------+-----------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
          | acknowledges          | InnoDB |      10 | Compact    |        18 |          12743 |      229376 |               0 |       917504 |         0 |           NULL | NULL                | NULL        | NULL       | utf8_general_ci |     NULL | partitioned    |         |
          | actions               | InnoDB |      10 | Compact    |        22 |            744 |       16384 |               0 |        32768 |         0 |           NULL | 2015-09-11 13:49:01 | NULL        | NULL       | utf8_general_ci |     NULL |                |         |
          | alerts                | InnoDB |      10 | Compact    |     90317 |            616 |    55721984 |               0 |     28360704 |  17825792 |           NULL | NULL                | NULL        | NULL       | utf8_general_ci |     NULL | partitioned    |         |
          | ...                   | ...    |     ... | ...        |       ... |            ... |         ... |             ... |          ... |       ... |            ... | ...                 | ...         | ...        | ...             |      ... | ...            | ...     |
          | usrgrp                | InnoDB |      10 | Compact    |        18 |            910 |       16384 |               0 |        16384 |         0 |           NULL | 2015-07-23 12:26:45 | NULL        | NULL       | utf8_general_ci |     NULL |                |         |
          | valuemaps             | InnoDB |      10 | Compact    |        16 |           1024 |       16384 |               0 |        16384 |         0 |           NULL | 2015-07-23 12:26:45 | NULL        | NULL       | utf8_general_ci |     NULL |                |         |
          +-----------------------+--------+---------+------------+-----------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
          Внимание!
          Если между наблюдаемым хостом и сервером zabbix есть zabbix-proxy, все вышеописанные проверки по аналогии необходимо проделать с базой данных zabbix-proxy.

          Powershell

          Если с базой данных все в порядке, переходим к powershell. Кодировка по умолчанию в powershell - ASCII. Убедиться в этом можно, просмотрев содержимое переменной $OutputEncoding

          Code:
          PS> [Console]::OutputEncoding
          Code:
          IsSingleByte      : True
          BodyName          : us-ascii
          EncodingName      : US-ASCII
          HeaderName        : us-ascii
          WebName           : us-ascii
          WindowsCodePage   : 1252
          IsBrowserDisplay  : False
          IsBrowserSave     : False
          IsMailNewsDisplay : True
          IsMailNewsSave    : True
          EncoderFallback   : System.Text.EncoderReplacementFallback
          DecoderFallback   : System.Text.DecoderReplacementFallback
          IsReadOnly        : True
          CodePage          : 20127
          Как я уже упоминал выше, если просто переключить кодировку консоли в UTF-8,

          Code:
          PS> [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false)
          то на выходе вы всегда получите BOM (byte order mark) в первых 3-х байтах, вне зависимости от значения аргумента в конструкторе. Zabbix не умеет работать с BOM, поэтому даже если zabbix_get будет возвращать на вид правильный JSON, в интерфейсе будет отображаться ошибка

          Code:
          Value should be a JSON object
          Решение этой проблемы нашлось в соседней ветке, где предлагается вместо изменения кодировки консоли, перекодировать непосредственно текстовый вывод. Исходный код немного доработанного командлета для этого.

          Code:
          function Convert-Encoding
          {
              [CmdletBinding()]
              param
              (
                  [Parameter(ValueFromPipeline = $true)]
                  $InputObject,
          
                  [Parameter(Position = 0)]
                  [String]
                  $From,
          
                  [Parameter(Position = 1)]
                  [String]
                  $To
              )
          
              begin
              {
                  if ($From)
                  {
                      $EncodingFrom = [System.Text.Encoding]::GetEncoding($From)
                  }
                  else
                  {
                      $EncodingFrom = $OutputEncoding
                  }
          
                  if ($To)
                  {
                      $EncodingTo = [System.Text.Encoding]::GetEncoding($To)
                  }
                  else
                  {
                      $EncodingTo = $OutputEncoding
                  }
          
                  $Content = @()
              }
          
              process
              {
                  $Content += $InputObject
              }
          
              end
              {
                  $Content = $Content | Out-String
                  $Bytes = $EncodingTo.GetBytes($Content)
                  $Bytes = [System.Text.Encoding]::Convert($EncodingFrom, $EncodingTo, $Bytes)
                  $Content = $EncodingTo.GetString($Bytes)
          
                  return $Content
              }
          }
          Такой вариант "портит" вывод в текущую консоль, из-за несовпадения кодировок текста и консоли.

          Code:
          PS> '{"data":[{"{#NAME}":"Русские буквы"}]}' | Convert-Encoding CP866 UTF-8
          Code:
          {"data":[{"{#NAME}":"╨а╤Г╤Б╤Б╨║╨╕╨╡ ╨▒╤Г╨║╨▓╤Л"}]}
          Но в zabbix_get все должно отображаться нормально.

          Code:
          # zabbix_get -s host -k key
          Code:
          {"data":[{"{#NAME}":"Русские буквы"}]}
          Второй вариант решения этой проблемы заключается в использовании промежуточного файла: данные JSON помещаются во временный файл, который zabbix agent потом читает с помощью элемента данных vfs.file.contents. Файл, опять же, должен быть в кодировке UTF-8 и не содержать BOM. Т.к. штатные командлеты так не умеют, для реализации этого сценария понадобится следующая функция.

          Code:
          function Out-UnicodeFileWithoutBom
          {
              [CmdletBinding()]
              param
              (
                  [Parameter(ValueFromPipeline = $true)]
                  $InputObject,
          
                  [Parameter(Position = 0)]
                  [String]
                  $FilePath
              )
          
              begin
              {
                  $Content = @()
              }
          
              process
              {
                  $Content += $InputObject
              }
          
              end
              {
                  $Content = $Content | Out-String
                  $Utf8NoBomEncoding = New-Object -TypeName System.Text.UTF8Encoding -ArgumentList $false
                  [System.IO.File]::WriteAllLines($FilePath, $Content, $Utf8NoBomEncoding)
              }
          }
          Используем, например, следующим образом

          Code:
          PS> '{"data":[{"{#NAME}":"Русские буквы"}]}' | Out-UnicodeFileWithoutBom -FilePath 'C:\Windows\Temp\filename.json'
          В zabbix добавляем правило для низкоуровнего обнаружения с элементом данных

          Code:
          vfs.file.contents["C:\Windows\Temp\filename.json",utf8]

          Comment

          • perlestius
            Junior Member
            • May 2020
            • 8

            #6
            Хоть и прошло много времени, оставлю здесь вариант решения, который мне помог (проверено за Zabbix 2.2.2):
            Code:
            [Console]::OutputEncoding = [System.Text.Encoding]::UTF8  
            $services = Get-WmiObject Win32_Service | where-object { $_.StartMode -eq 'Auto' } | Select-Object -Property @{Name="{#SERVICESTATE}"; Expression = {$_.State}},@{Name="{#SERVICEDISPLAY}"; Expression = {$_.DisplayName}},@{Name="{#SERVICENAME}"; Expression = {$_.Name} },@{Name = "{#SERVICEDESC}"; Expression = {$_.Description}},@{Name = "{#SERVICEDIR}"; Expression = {$_.PathName}}  
            $zabbixLLD = @{data=$services} | ConvertTo-Json -Compress  
            [Console]::WriteLine( $zabbixLLD )
            Источник

            Comment

            Working...