Ad Widget

Collapse

Список проблем (аварий) из БД с подключенной надстройкой TimescaleDB

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • alibek22
    Member
    • Mar 2022
    • 46

    #1

    Список проблем (аварий) из БД с подключенной надстройкой TimescaleDB

    По некоторым причинам мне не очень подходит API.
    Мне нужно получить из базы данных информацию Zabbix (версия 5.4.2), в частности список аварий за определенный период.
    Если включить режим отладки и запросить список проблем за указанный период, этот список отображается.
    В окне отладки отображаются соответствующие запросы API и SQL-запросы.
    Список проблем запрашивается из таблицы problem. Однако когда я делаю подобный SQL-запрос, то я получаю только недавние проблемы, а проблемы старше определенного возраста в данной таблице отсутствуют. Более того, на следующий день там не будет проблем, которые еще имеются сегодня.
    Вероятно это связано с тем, что у меня установлена надстройка TimescaleDB и исторические данные перемещаются в другое место.
    Подскажите, где их искать?
    Мне нужно доработать данный запрос так, чтобы он стал рабочим:
    Code:
    select p.eventid as "event#"
    , p.objectid as "object#"
    , i.hostid as "host#"
    , h.name as "host"
    , h.status as "status"
    , p.name as "name"
    , p.severity as "lvl"
    , p.acknowledged as "ack"
    , to_timestamp(p.clock) as "started"
    , to_timestamp(p.r_clock) as "finish"
    , p.r_clock - p.clock as "duration"
    , p.r_eventid as "close#"
    , p.ns, p.r_ns
    from "problem" p
    left join "triggers" t on (t.triggerid = p.objectid)
    left join "functions" f on (f.triggerid = t.triggerid and concat('{',f.functionid,'}=0') = t.expression)
    left join "items" i on (i.itemid = f.itemid and i.key_ = 'icmpping')
    left join "hosts" h on (h.hostid = i.hostid)
    where p.source = 0
    and p.object = 0
    and p.severity = 4
    and p.r_clock >= extract(epoch from timestamp '2024-02-01')
    and p.r_clock <  extract(epoch from timestamp '2024-03-01')
    and (p.r_clock - p.clock) > 1200
    order by p.eventid asc
  • Alex_UUU
    Senior Member
    • Dec 2018
    • 541

    #2
    А если в самом заббиксе запросить старые данные? Какой запрос будет в отладке? И будут ли данные?
    Выбери из таблы эвентов любой старый запрос по ID и посмотри, есть ли он там

    Comment

    • alibek22
      Member
      • Mar 2022
      • 46

      #3
      Если в самом Zabbix запросить старые данные, то они отобразятся.
      Но если взять запросы из отладки и запустить их отдельно, то нужных данных в результатах не будет.

      Я посмотрел исходные коды, в файле zabbix/include/classes/db/PostgresqlDbBackend.php есть функция isCompressed.
      Судя по всему, данная функция модифицирует запросы в тех случаях, когда используется TimescaleDB.
      Только не пойму, как именно.

      Comment

      • alibek22
        Member
        • Mar 2022
        • 46

        #4
        Originally posted by Alex_UUU
        Выбери из таблы эвентов любой старый запрос по ID и посмотри, есть ли он там
        В таблице problem есть проблемы за последнее время (примерно сутки).
        Проблемы, которые старше, в таблице problem отсутствуют.
        Но где-то они все таки есть, поскольку Zabbix их может отобразить.

        Comment

        • alibek22
          Member
          • Mar 2022
          • 46

          #5
          В общем, нашел, искать нужно было в таблице events.
          Там по две записи на аварии - начало аварии и завершение аварии.
          Подскажите, как найти завершение (или длительность) аварии?

          Comment

          • Griboed0ff
            Senior Member
            • Sep 2022
            • 153

            #6
            Originally posted by alibek22
            как найти завершение (или длительность) аварии?
            Просто в sql запросе вычти одно из другого и выводи в удобном формате. Делал подобный запрос, который отображал проблемы определенных групп, начало проблемы, конец, а так же подтверждения проблем и комментарии, логин, которые оставили ответственные.

            Comment

            • alibek22
              Member
              • Mar 2022
              • 46

              #7
              Чтобы вычесть — нужно вначале найти.
              Это можно сделать оконной функцией (lead), но у такого способа есть много недостатков.
              Может быть Zabbix уже хранит где-то связь между началом и окончанием аварии?

              Comment

              • alibek22
                Member
                • Mar 2022
                • 46

                #8
                Сейчас у меня сделано так:
                Code:
                select el.*
                , case
                    when el.duration is null then null
                    when el.duration > 60*60*24 then concat(trunc(el.duration/60/60/24),'d', ' ', trunc(mod(el.duration,60*60*24)/60/60),'h')
                    when el.duration > 60*60 then concat(trunc(el.duration/60/60),'h', ' ', trunc(mod(el.duration,60*60)/60),'m')
                    when el.duration > 60 then concat(trunc(el.duration/60),'m', ' ', trunc(mod(el.duration,60)),'s')
                    else concat(trunc(el.duration),'s')
                  end as "length"
                from (
                select e.eventid as "event#"
                , e.objectid as  "object#"
                , i.hostid as "host#"
                , h.name as "host"
                , case h.status when 0 then null else 1 end as "disabled"
                , case e.acknowledged when 1 then 1 else null end as "ack"
                , to_timestamp(e.clock) as "started"
                , case when e.value=1 then to_timestamp(lead(e.clock) over (partition by e.source, e.object, e.objectid order by e.eventid)) end as "finish"
                , case when e.value=1 then (lead(e.clock) over (partition by e.source, e.object, e.objectid order by e.eventid) - e.clock) end as "duration"
                from "events" e
                left join "triggers" t on (t.triggerid = e.objectid)
                left join "functions" f on (f.triggerid = t.triggerid and concat('{',f.functionid,'}=0') = t.expression)
                left join "items" i on (i.itemid = f.itemid and i.key_ = 'icmpping')
                left join "hosts" h on (h.hostid = i.hostid)
                where e.source = 0 and e.object = 0
                and e.clock > extract(epoch from now())::int - 60*24*60*60
                order by e.eventid asc
                ) el
                where el.duration > 3600
                and el.finish >= '2024-02-01'
                and el.finish <  '2024-03-01'
                Работает, но хотелось бы обойтись без оконных функций и вложенных запросов.

                Comment

                • Griboed0ff
                  Senior Member
                  • Sep 2022
                  • 153

                  #9
                  Originally posted by alibek22
                  Может быть Zabbix уже хранит где-то связь между началом и окончанием аварии?
                  Я тоже долго пытался найти готовую цифру длительности проблем, но увы заббикс хранит их так как есть. К сожалению без вложенных запросов никак. У меня не было цели высчитывать длительность проблем и дело было в mysql, но там не много надо переделать для постгри. Прикладываю запрос может наткнет на какие-нибудь мысли.
                  Code:
                  select cast(event2.problem_up as Date) data
                  ,  event2.hostname
                  , event2.problem
                  , event2.problem_up + INTERVAL '3' HOUR problem_up
                  , to_timestamp(ev2.clock) + INTERVAL '3' HOUR problem_down
                  , event2.confirmed
                  from
                  (select
                  distinct e.eventid
                  ,e.objectid
                  ,e.clock
                  ,to_timestamp(e.clock) problem_up
                  ,h.name as hostname
                  ,e.name as problem
                  ,e.acknowledged confirmed
                  from
                  public.events e
                  ,public.functions f
                  ,public.items i
                  ,public.hosts h
                  where
                  e.source='0'
                  and e.object='0'
                  and e.objectid=f.triggerid
                  and f.itemid=i.itemid
                  and i.hostid=h.hostid
                  and i.hostid in (
                  select
                  hosts_groups.hostid
                  from
                  public.hosts_groups
                  ,public.hosts
                  ,public.hstgrp
                  where
                  hosts_groups.groupid in (84, 86, 85, 80, 81, 83, 82, 87, 79, 77)
                  and hosts.status in (0, 1)
                  and hosts_groups.groupid  = hstgrp.groupid
                  and hosts.hostid = hosts_groups.hostid
                  )
                  and not exists (select null from public.event_suppress es where es.eventid=e.eventid)
                  and e.clock>= CAST(EXTRACT(epoch FROM (CURRENT_DATE - INTERVAL '1' DAY)) AS INTEGER)
                  and e.clock<= CAST(EXTRACT(epoch FROM (CURRENT_DATE)) AS INTEGER)
                  and e.value=1
                  and e.name like 'Узел недоступен в рабочее время%'
                  order by e.clock asc) as event2
                  LEFT JOIN public.event_recovery er1 ON er1.eventid=event2.eventid
                  LEFT JOIN public.events ev2 on er1.r_eventid = ev2.eventid
                  И деление по временным чанкам там не причем. Попробуйте решить вопрос через апи, такие запросы в базу, если заббикс имеет хотя бы средний размер, будет подгружать базу.
                  Last edited by Griboed0ff; 27-03-2024, 08:55.

                  Comment

                  Working...