Хотелось бы продолжить рассказ о расширениях PostgreSQL и поговорить о логировании и исключениях. Рассматривать их нужно вместе, поскольку в PostgreSQL это связанные механизмы. Хотя ранее мы уже и использовали макрос elog() , тема была затронута лишь поверхностно.
Большую часть того, что нужно знать о логировании и исключениях, можно почерпнуть из файла src/include/utils/elog.h в исходном коде PostgreSQL.
В простейшем случае логирование осуществляется при помощи elog():
elog ( NOTICE , «Transaction start timestamp: %lld» , ( long long ) now ) ;
Форматирование практически такое же, как в обычном printf(), но с некоторыми отличиями. Например, можно написать %m
, и это будет аналогично строке, возвращаемой strerror(errno)
. Дополнительных аргументов для %m
передавать не нужно. Для форматирования 64-х битных чисел можно воспользоваться %lld
или %llu
. Чтобы это правильно работало, соответствующие аргументы нужно явно преобразовать в long long или unsigned long long соответственно. Все подробности касаемо форматированного вывода в PostgreSQL можно найти в файле src/port/snprintf.c .
Есть разные уровни логирования — DEBUG5…DEBUG1, INFO, NOTICE, WARNING, ERROR, FATAL, PANIC и другие. Они ведут себя по-разному. Например, NOTICE отображается в пользовательской сессии, но по-умолчанию не пишется в лог-файл. ERROR бросает исключение (о них ниже) и отменяет исполнение текущей транзакции. FATAL приводит к завершению работы текущего процесса, а PANIC останавливает работу всей СУБД. Подробнее о всех существующих уровнях логирования можно прочитать в elog.h.
Отображаемый уровень логирования бывает удобно изменить в рамках сессии, например, для отладки. Сделать это можно так:
Что пишется в лог-файл определяется настройками, описанными в разделе Error Reporting and Logging документации.
Макрос elog() определен, как обвязка над ereport():
ereport(elevel, errmsg_internal(__VA_ARGS__))
В новом коде рекомендуется использовать именно ereport(). Типичный пример:
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
errmsg ( «Invalid argument » %s «» «» arg )
errhint ( «»This is a hint message.»» ) ) ) ;
Указывать errhint() не обязательно. Хотя использовать elog() и не рекомендуется в новом кодеиногда он полезен. Например