?

Log in

No account? Create an account
ma2dy
Решил написать свою первую статью про Zabbix. На работе для внутренней сети попросили поставить и настроить систему мониторинга. Сначала был Nagios, но хотелось разобраться и поставить что-то более серьезное. Поставил, настроил.
Версия zabbix-frontend-php
# dpkg -l zabbix-frontend-php
ii zabbix-frontend-php 1:1.4.2-4ubuntu3
Версия zabbix-server-mysql
# dpkg -l zabbix-server-mysql
ii zabbix-server-mysql 1:1.4.2-4ubuntu3

Пример на рисунке.  



 

 

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

 


После прочтения следующих веток форума на www.zabbix.com

http://www.zabbix.com/forum/showthread.php?t=12227
http://www.zabbix.com/forum/showthread.php?p=46659

Я понял, что проблема еще не решена и решил взяться за это дело самостоятельно.
Сразу выявил ряд проблем.





  1. необходимо указать серверу mysql правильную кодировку символов, а именно UTF8 (для справки http://www.opennet.ru/openforum/vsluhforumID8/3783.html)

     

    Для решения данной проблемы есть два пути решения.

Первый: прописать в файле my.cnf след строки
[code]
[mysqld]
init-connect='SET NAMES UTF8'
[/code]

     

    Второй: добавить в файл /usr/share/zabbix/include/db.inc.php следующую строку:

[code]
mysql_query("SET NAMES UTF8");
[/code]

Чтобы в результате получился следующий код:

[code]
case "MYSQL":
$mysql_server = $DB_SERVER.( !empty($DB_PORT) ? ':'.$DB_PORT : '');

if ( !($DB = mysql_connect($mysql_server,$DB_USER,$DB_PASSWORD)))

` {
$error = "Error connecting to database [".mysql_error()."]";
$result = false;
}
else
{
if ( !mysql_select_db($DB_DATABASE) )
{
$error = 'Error database selection ['.mysql_error().']';
$result = false;
}
mysql_query("SET NAMES UTF8");
}
break;

    [/code]

  1. Второй шаг.
Поменять сравнение (COLLATE) для полей :


поле host таблицы hosts

[code]
ALTER TABLE `hosts` CHANGE `host` `host` VARCHAR( 64 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
[/code]

поле name таблицы sysmaps

[code]
ALTER TABLE `sysmaps` CHANGE `name` `name` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
[code]

поле label таблицы sysmap_elements

[code]
ALTER TABLE `sysmaps_elements` CHANGE `label` `label` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
[code]

поле name таблицы groups
[code]
ALTER TABLE `groups` CHANGE `name` `name` VARCHAR( 64 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
[/code]


    Вроде ничего не забыл.


  1. Третий шаг.

 

Исправление написания русских букв на графиках и картах.
Как странице http://www.zabbix.com/forum/showpost.php?p=44909&postcount=4 сказано следующее:
«Ответ от Алексея Владышева: "Сейчас при отрисовке карт используются набор символов ASCII, в который не входят русскоязычные буквы. В будущей версии можно будет ожидать замену этого набора на стандартные шрифты TrueType и корректную работу с русским языком."»

Рассмотрим данную проблему более подробно.
Откроем файл /usr/share/zabbix/map.php
Находим фрагмент:
[code]
if($label_line!="")
{
ImageFilledRectangle($im,
$x_label-2, $y_label,
$x_label ImageFontWidth(2)*strlen($label_line), $y_label ImageFontHeight(2),
$white);
ImageString($im, 2, $x_label, $y_label, $label_line,$label_color);
}
[/code]

Видим что строка метки на графике рисуется стандартной функцией библиотеки GD ImageString.
Идем на сайт www.php.net - http://ru.php.net/manual/ru/function.imagestring.php

Читаем про второй параметр функции imagestring

[code]
Can be 1, 2, 3, 4, 5 for built-in fonts in latin2 encoding (where higher numbers corresponding to larger fonts) or any of your own font identifiers registered with imageloadfont().
[/code]

Шрифты под номером 1-5 это шрифты в кодировке latin2, а другие пользовательские шрифты могут быть добавлены с помощью функции imageloadfont ()

На странице описания функции imageloadfont http://ru.php.net/manual/ru/function.imageloadfont.php выложен код примера загрузки пользовательского шрифта
[code]
<?php
// Create a new image instance
$im = imagecreatetruecolor(50, 20);
$black = imagecolorallocate($im, 0, 0, 0);
$white = imagecolorallocate($im, 255, 255, 255);

// Make the background white
imagefilledrectangle($im, 0, 0, 49, 19, $white);

// Load the gd font and write 'Hello'
$font = imageloadfont('./04b.gdf');
imagestring($im, $font, 0, 0, 'Hello', $black);

// Output to browser
header('Content-type: image/png');

imagepng($im);
imagedestroy($im);
?>
[/code]

Шрифты формата gdf прекрасно конвертируются из формата ttf утилитой ttf2gdf (http://depositfiles.com/ru/files/vo51uf3w6 или в поиск по гуглю http://www.google.com/search?hl=ru&client=opera&rls=ru&hs=fqX&q=ttf2gdf&btnG=Поиск&lr=)

Скачиваем, запускаем в Windows (под wine в линукс программа почему-то конвертирует битые шрифты.)

 















Подгружаем в файле map.php сделанный нами шрифт
[code]
$USERFONT_arial6= imageloadfont("fonts/arial12_6.gdf");
[/code]

И применяем его для рисования нашей метки

[code]
$USERFONT_arial6= imageloadfont("fonts/arial12_6.gdf");
.....
......
.....

if($label_line!="")
{
ImageFilledRectangle($im,
$x_label-2, $y_label,
$x_label ImageFontWidth(2)*strlen($label_line), $y_label ImageFontHeight(2),
$white);
$label_line= iconv("UTF-8","windows-1251", $label_line);
ImageString($im, $USERFONT_arial6, $x_label, $y_label, $label_line,$label_color);
}


[/code]

обратите внимание на след строку в скрипте
[code]
$label_line= iconv("UTF-8","windows-1251", $label_line);
[/code]


 

Данное преобразование необходимо для того чтобы правильно отображать нашу строку.
В базе данных строка хранится в формате UTF-8, а шрифт использует кодировку window-1251.
На следующем рисунке название карты выводится без применения функции iconv.

Проделываем операции замены шрифта пользовательским в трех местах файла map.php.
  1. Вывод заголовка карты объектов.
было
[code]
if(($db_image = get_image_by_imageid($backgroundid)))
{
$back = ImageCreateFromString($db_image["image"]);
ImageCopy($im,$back,0,0,0,0,imagesx($back),imagesy($back));
}
else
{
$x=imagesx($im)/2-ImageFontWidth(4)*strlen($name)/2;
ImageString($im, 3,$x,1, $name , $darkred);
}
[/code]

стало
[code]
if(($db_image = get_image_by_imageid($backgroundid)))
{
$back = ImageCreateFromString($db_image["image"]);
ImageCopy($im,$back,0,0,0,0,imagesx($back),imagesy($back));
}
else
{
$name= iconv("UTF-8","windows-1251", $name);
$x=imagesx($im)/2-ImageFontWidth(4)*strlen($name)/2;
ImageString($im, $USERFONT_arial6,$x,1, $name , $darkred);
}
[/code]
  1. Вывод метки объекта на карте.
было

    [code]

if($label_line!="")
{
ImageFilledRectangle($im,
$x_label-2, $y_label,
$x_label ImageFontWidth(2)*strlen($label_line), $y_label ImageFontHeight(2),
$white);
ImageString($im, 2, $x_label, $y_label, $label_line,$label_color);

    }

    [/code]

     

    стало

     

    [code]

if($label_line!="")
{
$label_line= iconv("UTF-8","windows-1251", $label_line);
ImageFilledRectangle($im,
$x_label-2, $y_label,
$x_label ImageFontWidth(2)*strlen($label_line), $y_label ImageFontHeight(2),
$white);
ImageString($im, $USERFONT_arial6, $x_label, $y_label, $label_line,$label_color);
}
[/code]
  1. Вывод поля информации об объекте.
было

    [code]

if($info_line!="")
{

ImageFilledRectangle($im,
$x_info-2, $y_info,
$x_info ImageFontWidth(2)*strlen($info_line), $y_info ImageFontHeight(2),
$white);
ImageString($im,2 , $x_info, $y_info, $info_line,$color);
}

    [/code]

    стало

    [code]

if($info_line!="")
{
$info_line= iconv("UTF-8","windows-1251", $info_line);
ImageFilledRectangle($im,
$x_info-2, $y_info,
$x_info ImageFontWidth(2)*strlen($info_line), $y_info ImageFontHeight(2),
$white);

ImageString($im,$USERFONT_arial6 , $x_info, $y_info, $info_line,$color);

}

    [/code]




Итог наших исправлений.