Ad Widget

Collapse

Периодические отчеты. IT Services

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • BlackJaguar1982
    Junior Member
    • Jun 2014
    • 3

    #1

    Периодические отчеты. IT Services

    Итак, руководство поставило задачу:
    - Твоя система мониторинга - это хорошо, но нужны отчеты, красивые, с блэк-джеком и ... кхм.
    - Ок, какой отчет нужен?
    - Ну, мы, эээ...
    - IT Services?
    - Да.

    Отлично, теперь осталось понять, как это достать из zabbix.
    Есть два варианта: через прямое обращение к БД MySQL (этот путь предлагает нам JasperReports) и через Zabbix API - это тот путь, которым пошел я.
    После долгого раскуривания zabbix api (не очень внятно документированного, не хватает реально боевых примеров) был написан следующий скрипт (ниже по тексту). Я не программист Perl, моя стихия -VBScript, поэтому прошу не пинать за говнокод.
    Для отправки на почту буду использовать ssmtp. Пример настройки ssmtp найдете в гугле.
    Вызывать этого дьявола с помощью perl myscript.pl | ssmtp [email protected]

    Удачного всем дня!

    Code:
    #!/usr/bin/perl
    use 5.010;
    use strict;
    #use warnings;
    use utf8;
    use JSON::RPC::Client;
    use Data::Dumper;
    
    binmode(STDOUT,':utf8');
    
    my $client = new JSON::RPC::Client;
    my $url = 'http://192.168.1.180/zabbix/api_jsonrpc.php';
    my $authID;
    my $response;
    my $result;
    my $gsbid;
    my $gsb_response;
    my $serviceup;
    my $gsla;
    my $dt;
    my $srv_id;
    my $get_sla;
    my $sla;
    my $dt2;
    my $okTime;
    my $problemTime;
    my $downTime;
    my $val;
    my $num;
    my $goodsla_color;
    my $badsla_color;
    my $sla_color;
    my $font_color;
    
    $goodsla_color="#00c000";
    $badsla_color="red";
    $num=0;
    $dt=time();
    $val=86400;
    $dt2=int($dt-$val);
    login();
    getservices();
    print "Content-Type: text/html; charset=\"UTF-8\"\n";
    print "Content-Transfer-Encoding: 8bit\n";
    print "Subject: Daily Avaiability Report of IT Services\n";
    print "<html lang='en'><head><title>Daily Availability Report of IT Services</title></head>";
    print "<body bgcolor='#ffffff'>\n";
    print "<center>Daily Availability Report of IT Services<br>\n";
    print "<font color=white><br>";
    print "<table bgcolor=#00c000 border=1><tr bgcolor=blue align=center><td>Number</td><td>Service Name</td><td>Subservice</td><td>Target SLA</td><td>Current SLA</td><td>OK Time</td><td>Problem Time</td><td>Down Time</td></tr>\n";
    foreach my $service (@{$response->content->{'result'}}) {
        $serviceup=0;
        if (ref(@{$service->{'dependencies'}}), 'ARRAY') {
            foreach my $depend (@{$service->{'dependencies'}}) {
                $serviceup = $depend->{'serviceupid'};
            }
            if ($serviceup > 0) {
                $srv_id = $service->{'serviceid'};
                getslaofservice();
                $num +=1;
                if ($sla >= ($service->{'goodsla'})) { $sla_color=$goodsla_color; $font_color="black"; } else { $sla_color = $badsla_color; $font_color="white";}
                print "<font color=" .$font_color ."><tr bgcolor=" . $sla_color ."><td align=center>" .$num ."</td>";
                print "<td>" . $service->{'name'} ."</td><td>&nbsp</td>";
                print "<td>" . $service->{'goodsla'} ."</td><td>";
                printf "%03.4f",$sla;
                print "</td><td>" .$okTime ."</td><td>" .$problemTime ."</td><td>" .$downTime ."</td></tr></font>\n";
            }
            foreach my $depend (@{$service->{'dependencies'}}) {
                if ($depend->{'servicedownid'} > 0) {
                    $gsbid = $depend->{'servicedownid'};
                    getservicebyid ();
                    foreach my $gsb_service (@{$gsb_response->content->{'result'}}) {
                        $num +=1;
                        $srv_id=$gsb_service->{'serviceid'};
                        getslaofservice();
                        if ($sla >= ($service->{'goodsla'})) { $sla_color=$goodsla_color; $font_color="black"; } else { $sla_color = $badsla_color; $font_color="white";}
                        print "<font color=" .$font_color ."><tr bgcolor=" .$sla_color ."><td align=center>" . $num ."</td><td>&nbsp</td><td>" . $gsb_service->{'name'} . "</td><td>" . $gsb_service->{'goodsla'} ."</td><td>";
                        printf "%03.4f",$sla;
                        print "</td><td>" .$okTime ."</td><td>" .$problemTime ."</td><td>" .$downTime ."</td></tr>\n";
                    }
                }
            }
        }
    }
    print "</font></table></body></html>\n";
    logout();
    
    sub login{
        my $login = {
            jsonrpc => "2.0",
            method => "user.login",
            params => {
                user => "admin",
                password => "zabbix"
            },
            id => 1
        };
    $response = $client->call($url, $login);
    die "Authentication failure\n" unless $response->content->{'result'};
    $authID = $response->content->{'result'};
    }
    sub logout{
            my $logout = {
            jsonrpc => "2.0",
            method => "user.logout",
            params => { },
            id => 1,
            auth => $authID
            };
            $response = $client->call($url, $logout);
            die "Cann't logout" unless $response->content->{'result'};
            $result = $response->content->{'result'};
            #print "Logout " . $result . "\n";
    }
    sub getservices{
            my $get_services = {
                    jsonrpc => "2.0",
                    method => "service.get",
                    params => {
                            output => "extend",
                            selectDependencies => "extend",
                            },
                    auth => $authID,
                    id => 1
                    };
            $response = $client->call($url, $get_services);
            die "Error get_services" unless $response->content->{'result'};
    }
    sub getservicebyid{
            my $get_service_by_id = {
                    jsonrpc => "2.0",
                    method => "service.get",
                    params => {
                            serviceids => $gsbid,
                            output => "extend",
                            selectDependencies => "extend",
                            },
                    auth => $authID,
                    id => 1
                    };
            $gsb_response = $client->call($url, $get_service_by_id);
            die "Error" unless $gsb_response->content->{'result'};
    }
    sub getslaofservice{
            $sla=0;
            $okTime=0;
            $problemTime=0;
            $downTime=0;
            my $get_sla = {
                    jsonrpc => "2.0",
                    method => "service.getsla",
                    params => {
                            serviceids => $srv_id,
                            intervals => {
                                    from => $dt2,
                                    to => $dt
                                    }
                            },
                    auth => $authID,
                    id => 1
                    };
            $gsla = $client->call($url, $get_sla);
            die "Error getting sla" unless $gsla->content->{'result'};
            foreach my $item (@{$gsla->content->{'result'}->{$srv_id}->{'sla'}}) {
                $sla= $item->{'sla'};
                $okTime= $item->{'okTime'};
                $problemTime= $item->{'problemTime'};
                $downTime= $item->{'downTime'};
            }
  • root
    Junior Member
    • Nov 2013
    • 3

    #2
    Шикарно, спасибо за скрипт.
    Внизу скобки одной не хватает.

    Comment

    • DRVTiny
      Senior Member
      • Sep 2011
      • 162

      #3
      Я специально написал простой и тупой, как консервный нож API. Zabipi называется. Специально написал, чтобы вы этого не делали.
      Можно писать запросы к Zabbix хоть в стиле BASH-скриптов, никаких специфических знаний Perl'а не требуется.
      Ссылка на этот API есть в официальном Zabbix wiki.
      Но изобретение вами велосипеда, безусловно, полезно для общего развития

      Comment

      • BlackJaguar1982
        Junior Member
        • Jun 2014
        • 3

        #4
        Originally posted by DRVTiny
        Я специально написал простой и тупой, как консервный нож API. Zabipi называется. Специально написал, чтобы вы этого не делали.
        Можно писать запросы к Zabbix хоть в стиле BASH-скриптов, никаких специфических знаний Perl'а не требуется.
        Ссылка на этот API есть в официальном Zabbix wiki.
        Но изобретение вами велосипеда, безусловно, полезно для общего развития
        Отлично. Вашей обертке чуть больше 3 месяцев, как я должен был о ней узнать?
        Гугл по запросу zabbix api perl первой выдает вот эту ссылку - http://blog.zabbix.com/getting-start...bbix-api/1381/
        и оно работает.
        Люди не любят много думать - от этого похудеть можно. Вот и я не исключение - зачем продолжать искать код, если есть рабочий образец? Его и взял за основу.

        Comment

        • tuban
          Senior Member
          Zabbix Certified Specialist
          • Sep 2012
          • 286

          #5
          У меня ругается Can't call method "content" on an undefined value at ./report line 99.
          Проблема с
          Code:
          die "Authentication failure\n" unless $response->content->{'result'};
          zabbix 2.2.5

          Originally posted by BlackJaguar1982
          Итак, руководство поставило задачу:
          - Твоя система мониторинга - это хорошо, но нужны отчеты, красивые, с блэк-джеком и ... кхм.
          - Ок, какой отчет нужен?
          - Ну, мы, эээ...
          - IT Services?
          - Да.

          Отлично, теперь осталось понять, как это достать из zabbix.
          Есть два варианта: через прямое обращение к БД MySQL (этот путь предлагает нам JasperReports) и через Zabbix API - это тот путь, которым пошел я.
          После долгого раскуривания zabbix api (не очень внятно документированного, не хватает реально боевых примеров) был написан следующий скрипт (ниже по тексту). Я не программист Perl, моя стихия -VBScript, поэтому прошу не пинать за говнокод.
          Для отправки на почту буду использовать ssmtp. Пример настройки ssmtp найдете в гугле.
          Вызывать этого дьявола с помощью perl myscript.pl | ssmtp [email protected]

          Удачного всем дня!

          Code:
          #!/usr/bin/perl
          use 5.010;
          use strict;
          #use warnings;
          use utf8;
          use JSON::RPC::Client;
          use Data::Dumper;
          
          binmode(STDOUT,':utf8');
          
          my $client = new JSON::RPC::Client;
          my $url = 'http://192.168.1.180/zabbix/api_jsonrpc.php';
          my $authID;
          my $response;
          my $result;
          my $gsbid;
          my $gsb_response;
          my $serviceup;
          my $gsla;
          my $dt;
          my $srv_id;
          my $get_sla;
          my $sla;
          my $dt2;
          my $okTime;
          my $problemTime;
          my $downTime;
          my $val;
          my $num;
          my $goodsla_color;
          my $badsla_color;
          my $sla_color;
          my $font_color;
          
          $goodsla_color="#00c000";
          $badsla_color="red";
          $num=0;
          $dt=time();
          $val=86400;
          $dt2=int($dt-$val);
          login();
          getservices();
          print "Content-Type: text/html; charset=\"UTF-8\"\n";
          print "Content-Transfer-Encoding: 8bit\n";
          print "Subject: Daily Avaiability Report of IT Services\n";
          print "<html lang='en'><head><title>Daily Availability Report of IT Services</title></head>";
          print "<body bgcolor='#ffffff'>\n";
          print "<center>Daily Availability Report of IT Services<br>\n";
          print "<font color=white><br>";
          print "<table bgcolor=#00c000 border=1><tr bgcolor=blue align=center><td>Number</td><td>Service Name</td><td>Subservice</td><td>Target SLA</td><td>Current SLA</td><td>OK Time</td><td>Problem Time</td><td>Down Time</td></tr>\n";
          foreach my $service (@{$response->content->{'result'}}) {
              $serviceup=0;
              if (ref(@{$service->{'dependencies'}}), 'ARRAY') {
                  foreach my $depend (@{$service->{'dependencies'}}) {
                      $serviceup = $depend->{'serviceupid'};
                  }
                  if ($serviceup > 0) {
                      $srv_id = $service->{'serviceid'};
                      getslaofservice();
                      $num +=1;
                      if ($sla >= ($service->{'goodsla'})) { $sla_color=$goodsla_color; $font_color="black"; } else { $sla_color = $badsla_color; $font_color="white";}
                      print "<font color=" .$font_color ."><tr bgcolor=" . $sla_color ."><td align=center>" .$num ."</td>";
                      print "<td>" . $service->{'name'} ."</td><td>&nbsp</td>";
                      print "<td>" . $service->{'goodsla'} ."</td><td>";
                      printf "%03.4f",$sla;
                      print "</td><td>" .$okTime ."</td><td>" .$problemTime ."</td><td>" .$downTime ."</td></tr></font>\n";
                  }
                  foreach my $depend (@{$service->{'dependencies'}}) {
                      if ($depend->{'servicedownid'} > 0) {
                          $gsbid = $depend->{'servicedownid'};
                          getservicebyid ();
                          foreach my $gsb_service (@{$gsb_response->content->{'result'}}) {
                              $num +=1;
                              $srv_id=$gsb_service->{'serviceid'};
                              getslaofservice();
                              if ($sla >= ($service->{'goodsla'})) { $sla_color=$goodsla_color; $font_color="black"; } else { $sla_color = $badsla_color; $font_color="white";}
                              print "<font color=" .$font_color ."><tr bgcolor=" .$sla_color ."><td align=center>" . $num ."</td><td>&nbsp</td><td>" . $gsb_service->{'name'} . "</td><td>" . $gsb_service->{'goodsla'} ."</td><td>";
                              printf "%03.4f",$sla;
                              print "</td><td>" .$okTime ."</td><td>" .$problemTime ."</td><td>" .$downTime ."</td></tr>\n";
                          }
                      }
                  }
              }
          }
          print "</font></table></body></html>\n";
          logout();
          
          sub login{
              my $login = {
                  jsonrpc => "2.0",
                  method => "user.login",
                  params => {
                      user => "admin",
                      password => "zabbix"
                  },
                  id => 1
              };
          $response = $client->call($url, $login);
          die "Authentication failure\n" unless $response->content->{'result'};
          $authID = $response->content->{'result'};
          }
          sub logout{
                  my $logout = {
                  jsonrpc => "2.0",
                  method => "user.logout",
                  params => { },
                  id => 1,
                  auth => $authID
                  };
                  $response = $client->call($url, $logout);
                  die "Cann't logout" unless $response->content->{'result'};
                  $result = $response->content->{'result'};
                  #print "Logout " . $result . "\n";
          }
          sub getservices{
                  my $get_services = {
                          jsonrpc => "2.0",
                          method => "service.get",
                          params => {
                                  output => "extend",
                                  selectDependencies => "extend",
                                  },
                          auth => $authID,
                          id => 1
                          };
                  $response = $client->call($url, $get_services);
                  die "Error get_services" unless $response->content->{'result'};
          }
          sub getservicebyid{
                  my $get_service_by_id = {
                          jsonrpc => "2.0",
                          method => "service.get",
                          params => {
                                  serviceids => $gsbid,
                                  output => "extend",
                                  selectDependencies => "extend",
                                  },
                          auth => $authID,
                          id => 1
                          };
                  $gsb_response = $client->call($url, $get_service_by_id);
                  die "Error" unless $gsb_response->content->{'result'};
          }
          sub getslaofservice{
                  $sla=0;
                  $okTime=0;
                  $problemTime=0;
                  $downTime=0;
                  my $get_sla = {
                          jsonrpc => "2.0",
                          method => "service.getsla",
                          params => {
                                  serviceids => $srv_id,
                                  intervals => {
                                          from => $dt2,
                                          to => $dt
                                          }
                                  },
                          auth => $authID,
                          id => 1
                          };
                  $gsla = $client->call($url, $get_sla);
                  die "Error getting sla" unless $gsla->content->{'result'};
                  foreach my $item (@{$gsla->content->{'result'}->{$srv_id}->{'sla'}}) {
                      $sla= $item->{'sla'};
                      $okTime= $item->{'okTime'};
                      $problemTime= $item->{'problemTime'};
                      $downTime= $item->{'downTime'};
                  }

          Comment

          • Jimson
            Senior Member
            • Jan 2008
            • 1327

            #6
            Originally posted by tuban
            У меня ругается Can't call method "content" on an undefined value at ./report line 99.
            Проблема с
            Code:
            die "Authentication failure\n" unless $response->content->{'result'};
            zabbix 2.2.5
            В $response undefined значение, не создался объект, возможно сервер не отвечает. Прежде чем обращаться к $response->content надо как то верифицировать $response, можно было бы написать "unless $response and $response->content....", но если по нормальному, то надо ошибку показать.
            А вообще для Zabbix API использовать JSON::RPC это даже не "из пушки по воробьям", скорее водородной бомбой. LWP::UserAgent за глаза хватило бы.

            Comment

            • tuban
              Senior Member
              Zabbix Certified Specialist
              • Sep 2012
              • 286

              #7
              Originally posted by Jimson
              В $response undefined значение, не создался объект, возможно сервер не отвечает. Прежде чем обращаться к $response->content надо как то верифицировать $response, можно было бы написать "unless $response and $response->content....", но если по нормальному, то надо ошибку показать.
              А вообще для Zabbix API использовать JSON::RPC это даже не "из пушки по воробьям", скорее водородной бомбой. LWP::UserAgent за глаза хватило бы.
              Authentication failed, хотя логин/пароль верны.
              Может ли это быть связано с тем, что используется https?

              Comment

              • Jimson
                Senior Member
                • Jan 2008
                • 1327

                #8
                Да нет там никакого "Authentication failure", это перловый скрипт хочет вывести такую диагностику в случае если в объекте $response->content нет данных "result". Проблема в том что объекта нет вообще, и не только content, но и responce. Вот тут
                $response = $client->call($url, $login);
                получаем undef как результат функции call().

                Я не знаю почему, как я написал выше я изначально для себя решил не использовать JSON::RPC. Возьмите вариант обертки от DRVTiny.

                P.S. Если используется https, то желательно озаботится верификацей сертификата сервера, если у вас там self signed, то не известно будет ли это вообще работать, зависит от реализации модуля и его настроек, наверное. Лучше завести свой простейший CA: сгенерить сертификат "CA" и им подписывать сертификаты серверов, а сертификат своего CA засунуть в trusted, в /etc/ssl/certs/ в случае linux/etc.

                Comment

                Working...