Гость
Map
Форумы / Informix [игнор отключен] [закрыт для гостей] / Поиск "открывающих" и "закрывающих" событий в логах / 17 сообщений из 17, страница 1 из 1
03.03.2015, 11:07
    #38893252
sir.ilgiz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск "открывающих" и "закрывающих" событий в логах
Имеется таблица в БД, в которую пишутся последовательно различные события некоторого сервиса, в том числе "парные" типа "Ошибка" - "Нет ошибки".
Необходимо выполнить поиск всех ошибок и продолжительности их существования. Задача усложняется тем, что событие "Ошибка" может появляться несколько раз по факту обращения к сервису.
service_idtimestampstatus12015-01-01 00:00:00Error22015-01-02 00:00:14Error12015-01-01 00:01:50Error12015-01-01 00:03:20Ok22015-01-02 00:05:00Ok
В приведенной выше таблице для сервиса с service_id = "1" в 2015-01-01 00:00:00 произошло событие Error, далее в 2015-01-01 00:01:50 было обращение к тому же сервису, и так как ошибка еще не устранена, в таблицу вновь внесена запись об ошибке. В 2015-01-01 00:03:20 ошибка была устранена. Итого мы имеем по сервису с service_id = "1" одну проблему, которая возникла в 2015-01-01 00:00:00 и была устранена в 2015-01-01 00:03:20. Простой, соответственно 3 минуты 20 секунд.

Я задался целью написать универсальный алгоритм, так как ничего готового не нашел.
Возможно,я плохо искал, и кто-то знает где велосипед "зарыт"?
...
Рейтинг: 0 / 0
03.03.2015, 12:21
    #38893366
Поиск "открывающих" и "закрывающих" событий в логах
версия сервера какая? так-то с 12-й можно и всякие там LEAD/LAG/ROW_NUMBER-а прикрутить...
если же сильно древнее, то только старомодными not exists + first
...
Рейтинг: 0 / 0
03.03.2015, 12:50
    #38893405
Поиск "открывающих" и "закрывающих" событий в логах
если сервер не поддерживает OLAP-функции, то решение (схематично, ибо сервера и данных под рукой нет) будет примерно таким (с возможными "вариациями на тему"):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
select v_beg.service_id, v_beg.timestamp as t_beg, min(v_end.timestamp) as t_end, v_beg.status
  from ( -- все начала событий:
         select *
           from t t0
          where not exists 
                (
                   select first 1 null
                     from t t1
                     where t0.service_id = t1.service_id
                       and t0.timestamp > t1.timestamp
                       and t0.status = t1.status
                     order by t1.timestamp desc
                )
       ) v_beg
  join 
       ( -- все кончала событий:
         select *
           from t t0
          where not exists 
                (
                   select first 1 null
                     from t t1
                     where t0.service_id = t1.service_id
                      and t0.timestamp < t1.timestamp
                       and t0.status = t1.status
                       order by t1.timestamp
                )
       ) v_end
    on v_beg.service_id = v_end.service_id
   and v_beg.status = v_end.status
   and v_beg.timestamp <= v_end.timestamp
 group by v_beg.service_id, v_beg.status, v_beg.timestamp 
order by service_id, t_beg




если же сервер вполне себе современнен, то решение будет сильно проще:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select service_id, MIN(timestamp) as t_beg, max(timestamp) as t_end, status
  from (
         select t.*
              , ROW_NUMBER() over(PARTITION BY service_id, status order by timestamp) - 
                ROW_NUMBER() over(PARTITION BY service_id order by timestamp) as grp_id
           from t
       ) v
 group by service_id, status, grp_id
...
Рейтинг: 0 / 0
03.03.2015, 12:58
    #38893415
Поиск "открывающих" и "закрывающих" событий в логах
оу, кажись даты кончал немного неправильно будут считаться... нужно же брать первую дату после смены статуса, а не последнюю дату текущего статуса... но, думаю, сам исправить сможешь при желании. :)
...
Рейтинг: 0 / 0
03.03.2015, 13:01
    #38893420
sir.ilgiz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск "открывающих" и "закрывающих" событий в логах
Добрый Э - Эх,

Да я потому версию и не приводил, чтобы алгоритм написать универсальный. У меня live-система на Oracle, архивные данные сливаются на Informix 11. В зависимости от ситуации, приходится выбирать данные либо из боевой системы, либо с архива.

Пока получилось написать только с помощью вложенного запроса и связывать таблицу саму с собой.
Бился долго, но есть сомнения, что можно написать более удачный алгоритм.
Хотя этот тоже работает, может кому и пригодится..


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
--Создаем таблицу логов
create temp table t_log (service_id int, timestamp date,status char(20));

--Заполняем данными
insert into t_log values (1,today-5,'Error');
insert into t_log values (1,today-4,'Error');
insert into t_log values (2,today-3,'Error');
insert into t_log values (1,today-1,'Ok');
insert into t_log values (2,today,'Ok');

--Содержимое таблицы
select * from t_log


Содержимое таблицы
service_idtimestampstatus126/02/2015Error127/02/2015Error228/02/2015Error102/03/2015Ok203/03/2015Ok

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
--Поиск для service_id=1
select 
 a.service_id,
 min(a.start_time) as start_time, 
 a.finish_time
from
 (
 select 
  a.service_id,
  a.timestamp as start_time,
  min(b.timestamp) as finish_time
 from 
  t_log a left join t_log b on a.service_id=b.service_id
 where
  b.timestamp>=a.timestamp
  and a.status='Error'
  and b.status='Ok'
 group by a.service_id,a.timestamp--,b.status
 ) as a
where 
 a.service_id=1
group by a.service_id,a.finish_time



Результат
service_idstart_timefinish_time126/02/201502/03/2015
...
Рейтинг: 0 / 0
03.03.2015, 13:22
    #38893466
sir.ilgiz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск "открывающих" и "закрывающих" событий в логах
Добрый Э - Эхоу, кажись даты кончал немного неправильно будут считаться... нужно же брать первую дату после смены статуса, а не последнюю дату текущего статуса... но, думаю, сам исправить сможешь при желании. :)

Насколько я понимаю, ваш вариант ищет начала и кончала как первое и последнее время каждого типа события. Т.е. для Error начало = первое время для Error и кончало = последнее время для Error и аналигично для "Ок".
Поправьте, если я не прав.
Моя же цель - найти первое время "плохого" события и первое после него время "хорошего" события. Т.е. первый Error и первый после него "Ок".
...
Рейтинг: 0 / 0
03.03.2015, 13:25
    #38893470
Поиск "открывающих" и "закрывающих" событий в логах
sir.ilgizНасколько я понимаю, ваш вариант ищет начала и кончала как первое и последнее время каждого типа событиявс ё верно. так оно и есть.
...
Рейтинг: 0 / 0
03.03.2015, 15:50
    #38893700
sir.ilgiz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск "открывающих" и "закрывающих" событий в логах
Добрый Э - Эх, спасибо за работу.
Вопрос еще актуален
...
Рейтинг: 0 / 0
03.03.2015, 16:01
    #38893719
Поиск "открывающих" и "закрывающих" событий в логах
Добрый Э - Эхsir.ilgizНасколько я понимаю, ваш вариант ищет начала и кончала как первое и последнее время каждого типа событиявс ё верно. так оно и есть.но оба варианта можно допилить под требования автора...
...
Рейтинг: 0 / 0
03.03.2015, 16:03
    #38893724
Поиск "открывающих" и "закрывающих" событий в логах
sir.ilgizВопрос еще актуаленСформулируй его ещё раз. А то я потерял нить твоей мысли...
...
Рейтинг: 0 / 0
03.03.2015, 18:45
    #38893999
sir.ilgiz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск "открывающих" и "закрывающих" событий в логах
Добрый Э - Эх,
Извини, я, наверное, запутал.
Итак, у меня есть несколько сервисов, которые пишут логи в одну таблицу.
Если упростить, при ошибке пишется "Error", при ее устранении пишется "Ok".
При этом, если после возникновения ошибки был повторный запрос к сервису, он отправит в ответ ошибку и в логи запишет еще одно событие "Error".
Таким образом, последовательность событий может быть "Error" - "Error" - "Error" - "Ok". В этом случае с момента первого "Error" и до первого "Ok" сервис простаивает.

Таблица лога в этом случае следующая:
service_idtimestampstatus126/02/2015Error127/02/2015Error228/02/2015Error102/03/2015Ok203/03/2015Ok

Для каждого сервиса надо найти момент возникновения ошибки и момент ее устранения.

Здесь:
а) для сервиса service_id=1 была одна ошибка, которая возникла 26/02/2015 и была устранена 02/03/2015
б) для сервиса service_id=2 была одна ошибка, которая возникла 28/02/2015 и была устранена 03/03/2015.
...
Рейтинг: 0 / 0
03.03.2015, 19:41
    #38894027
Поиск "открывающих" и "закрывающих" событий в логах
sir.ilgiz,

И запрос не должен содержать серверно-зависимых решений, так как работать запрос будет и в оракле, и в информиксе?
...
Рейтинг: 0 / 0
03.03.2015, 20:00
    #38894036
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск "открывающих" и "закрывающих" событий в логах
sir.ilgiz
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select 
 a.service_id,
 min(a.start_time) as start_time, 
 a.finish_time
from
 (
 select 
  a.service_id,
  a.timestamp as start_time,
  min(b.timestamp) as finish_time
 from 
  t_log a left join t_log b on a.service_id=b.service_id
 where
  b.timestamp>=a.timestamp
  and a.status='Error'
  and b.status='Ok'
 group by a.service_id,a.timestamp--,b.status
 ) as a
group by a.service_id,a.finish_time



Дык вполне рабочий запрос, в чём вопрос...
Через подзапросы будет не лучше...
...
Рейтинг: 0 / 0
03.03.2015, 22:11
    #38894103
sir.ilgiz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск "открывающих" и "закрывающих" событий в логах
Добрый Э - Эхsir.ilgiz,

И запрос не должен содержать серверно-зависимых решений, так как работать запрос будет и в оракле, и в информиксе?

В точку :)
...
Рейтинг: 0 / 0
03.03.2015, 22:18
    #38894108
sir.ilgiz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск "открывающих" и "закрывающих" событий в логах
АнатоЛойДык вполне рабочий запрос, в чём вопрос...
Через подзапросы будет не лучше...
Та я просто не так опытен, потому, естественно, меня гложат сомнения в оптимальности. Может изобрёл велосипед, а может есть более "правильное" решение.
Так как подразумевается анализ логов, объем данных будет большой (over 1000 сервисов, что даёт до 10-15 млн записей каждый месяц).
Да и алгоритм может пригодиться для других задач, которые сейчас никто не хочет решать именно по причине больших объёмов данных и отсутствия простого решения
...
Рейтинг: 0 / 0
04.03.2015, 00:26
    #38894144
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск "открывающих" и "закрывающих" событий в логах
sir.ilgizАнатоЛойДык вполне рабочий запрос, в чём вопрос...
Через подзапросы будет не лучше...
Та я просто не так опытен, потому, естественно, меня гложат сомнения в оптимальности. Может изобрёл велосипед, а может есть более "правильное" решение.
Так как подразумевается анализ логов, объем данных будет большой (over 1000 сервисов, что даёт до 10-15 млн записей каждый месяц).
Да и алгоритм может пригодиться для других задач, которые сейчас никто не хочет решать именно по причине больших объёмов данных и отсутствия простого решения
Если оптимизатор не облажается, эффективнее не сделаешь. Ну и индексы если сам не провтыкаешь. Эффективнее будет только не универсальное решение с однопроходной хранимкой на курсоре будет...
...
Рейтинг: 0 / 0
04.03.2015, 08:13
    #38894211
sir.ilgiz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск "открывающих" и "закрывающих" событий в логах
АнатоЛой,

Я понял. Спасибо!
...
Рейтинг: 0 / 0
Форумы / Informix [игнор отключен] [закрыт для гостей] / Поиск "открывающих" и "закрывающих" событий в логах / 17 сообщений из 17, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]