Добро пожаловать в "Будни программиста".
Сегодня я хотел бы начать освящать вопрос логирования исключительных ситуаций происходящих во время выполнения хранимых процедур. Не буду говорить о пользе такого функционала, ибо, думаю, это и так понятно. Скажу только, что из-за отсутствия такого функционала вчера пришлось потратить более часа на локализацию исключения возникающего у клиента, и чуть более минуты на устранение причины исключения.
Что нужно от логирования?
На первый взгляд это все что нужно. В процессе буду дополнять, если потребуется.
Чтобы начать что-то делать. необходимо понять, какие возможности может предоставить PostgreSQL. Для этого создадим тестовую хранимую процедуру (на ней и будем обкатывать и тестить все варианты исполнения):
Первое, что хотелось бы знать, может ли PostgreSQL вернуть код и сообщение об ошибке возникшего исключения.
После непродолжительных поисков я нашел переменные SQLERRM и SQLSTATE.
SQLERRM - содержит текстовое описание исключения. То что надо!!!
SQLSTATE - содержит код, что тоже будет далеко не лишним.
Чтобы протестировать как PostgreSQL это делает немного модифицируем тестовую хранимку:
И спровоцируем деление на ноль таким вызовом:
и получим результат:
NOTICE: division by zero, 22012
Ну чтож, код ошибки и описание теперь есть.
Далее, было бы круто получить данные по локализации исключений. А именно запрос который инициировал исключение.
PostgreSQL позволяет получить выполняющийся запрос в реалтайме с помощью функции current_query() (источник), и это очень замечательно. В связи с этим модифицируем тестовую хранимку:
Вызов:
Результат не может не радовать:
NOTICE: division by zero, 22012, select test_except_log('',10,0);
Итак, получили все, что было нужно:
Местом хранения я немерен сделать таблицу в специально отведенной для такого функционала (не имеющего отношение к бизнес логике) схеме.
Таблица будет содержать:
Наполнять таблицу данными будет процедура со следующими входнями параметрами:
Вот такой план получился... Пора пристпуать к реализации, но об этом в следующем посте.
Сегодня я хотел бы начать освящать вопрос логирования исключительных ситуаций происходящих во время выполнения хранимых процедур. Не буду говорить о пользе такого функционала, ибо, думаю, это и так понятно. Скажу только, что из-за отсутствия такого функционала вчера пришлось потратить более часа на локализацию исключения возникающего у клиента, и чуть более минуты на устранение причины исключения.
Что нужно от логирования?
- Доступное хранилище лога исключений;
- Добавление в лог новых записей при возникновении исключений любого типа;
- Возможность хранения кода и текстового сообщения исключения;
- Необходимо хранить данные для локализации. В идеале SQL-запрос который вызвал исключение (в т.ч. имя хранимки (породившей исключение) с указанными значениями параметров);
- Способ разметки областей хранимой процедуры для более точной локализации возникновения исключений.
На первый взгляд это все что нужно. В процессе буду дополнять, если потребуется.
Чтобы начать что-то делать. необходимо понять, какие возможности может предоставить PostgreSQL. Для этого создадим тестовую хранимую процедуру (на ней и будем обкатывать и тестить все варианты исполнения):
create or replace function test_except_log(
value1 character varying,
value2 integer,
value3 integer)
returns character varying as
$body$
begin
return '';
exception
when others then
--.......
end;
$body$
language plpgsql;
Первое, что хотелось бы знать, может ли PostgreSQL вернуть код и сообщение об ошибке возникшего исключения.
После непродолжительных поисков я нашел переменные SQLERRM и SQLSTATE.
SQLERRM - содержит текстовое описание исключения. То что надо!!!
SQLSTATE - содержит код, что тоже будет далеко не лишним.
Чтобы протестировать как PostgreSQL это делает немного модифицируем тестовую хранимку:
create or replace function test_except_log(
value1 character varying,
value2 integer,
value3 integer)
returns character varying as
$body$
begin
select value2/value3;
return '';
exception
when others then
raise notice '%, %', SQLERRM, SQLSTATE;
end;
$body$
language plpgsql;
И спровоцируем деление на ноль таким вызовом:
select test_except_log('',10,0);
и получим результат:
NOTICE: division by zero, 22012
Ну чтож, код ошибки и описание теперь есть.
Далее, было бы круто получить данные по локализации исключений. А именно запрос который инициировал исключение.
PostgreSQL позволяет получить выполняющийся запрос в реалтайме с помощью функции current_query() (источник), и это очень замечательно. В связи с этим модифицируем тестовую хранимку:
create or replace function test_except_log(
value1 character varying,
value2 integer,
value3 integer)
returns character varying as
$body$
begin
select value2/value3;
return 'test';
exception
when others then
raise notice '%, %, %', SQLERRM, SQLSTATE, current_query();
end;
$body$
language plpgsql;
Вызов:
select test_except_log('',10,0);
Результат не может не радовать:
NOTICE: division by zero, 22012, select test_except_log('',10,0);
Итак, получили все, что было нужно:
- Код исключения;
- Описание;
- Запрос спровоцировавший исключение.
Местом хранения я немерен сделать таблицу в специально отведенной для такого функционала (не имеющего отношение к бизнес логике) схеме.
Таблица будет содержать:
- Дату и время возникновения исключения;
- Код исключения;
- Описание исключения;
- Запрос породивший исключение;
- Метка исключения; (Что это? См. ниже)
- Имя пользователя запустившего запрос;
- Версия сервера*;
- Данные о расположении базы данных*.
Наполнять таблицу данными будет процедура со следующими входнями параметрами:
- Код исключения;
- Описание;
- Запрос инициирующий исключение;
- Метка исключения (для более точной локализации области хранимки в которой было сгенерировано исключение).
Вот такой план получился... Пора пристпуать к реализации, но об этом в следующем посте.
Комментариев нет:
Отправить комментарий