| Начало » Использование СУБД » Firebird, HQbird, InterBase » логгирование работы Переход к форуму:
	| 
		
			| логгирование работы [сообщение #455] | Mon, 05 September 2022 11:53  |  
			| 
				
				|  |  Док Сообщений: 101
 Зарегистрирован: June 2022
 | Senior Member |  |  |  
	| Комрады, поделитесь, плз, практическими советами и хитростями по логированию работы БД. Интересуют детали, типа: структура таблицы логов, примеры триггеров и проч.проч. 
 FPC/Lazarus (trunk) | Win10 x64 Ultim/Debian 11 amd64/Darwin x86_64 Monterey | Firebird 3.0.10 x64 | IBX by TonyWhyman
 
 https://zoltanleo.blogspot.com/
 |  
	|  |  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	| 
		
			| Re: логгирование работы [сообщение #485 является ответом на сообщение #482] | Tue, 06 September 2022 05:13   |  
			| 
				
				
					|  fraks Сообщений: 152
 Зарегистрирован: June 2022
 Географическое положение: Новосибирск
 | Senior Member |  |  |  
	| У меня есть несколько систем логирования, наиболее общая и понятная - это логирование таблиц справочников, у которых первичный ключ - ID и он идентифицирует объект. Т.е. когда нам интересна история изменения объекта - то идентификатор этого объекта - ID.
 
 Сам лог сделан вот так.
 
 
 А на таблицах которые нужно логировать делается такого плана триггеры.
CREATE GENERATOR GEN_LOGS_ID;
CREATE TABLE LOGS (
    ID       INTEGER NOT NULL,
    TNAME    VARCHAR(31),
    FNAME    VARCHAR(31),
    ID_SRC   INTEGER,
    A        CHAR(1),
    VAL      VARCHAR(1000),
    VAL_OLD  VARCHAR(1000),
    A_DT     TIMESTAMP default current_timestamp,
    A_USER   VARCHAR(32) default current_user,
    A_IP     VARCHAR(253),
    A_EXE    VARCHAR(253)
);
ALTER TABLE LOGS ADD CONSTRAINT LOGS_PK PRIMARY KEY (ID);
CREATE INDEX LOGS_A_DT   ON LOGS (A_DT);
CREATE INDEX LOGS_FNAME  ON LOGS (FNAME);
CREATE INDEX LOGS_ID_SRC ON LOGS (ID_SRC);
CREATE INDEX LOGS_TNAME  ON LOGS (TNAME);
SET TERM ^ ;
CREATE OR ALTER TRIGGER LOGS_BI_ID FOR LOGS
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id is null) then
    new.id = gen_id(gen_logs_id,1);
end
^
CREATE OR ALTER TRIGGER LOGS_BI_IP FOR LOGS
ACTIVE BEFORE INSERT POSITION 0
as
begin
  --
  -- Вставка IP вносившего изменение
  --
  select rdb$get_context('SYSTEM', 'CLIENT_ADDRESS')
    from rdb$database
    into NEW.a_ip;
end
^
SET TERM ; ^
COMMENT ON TABLE LOGS IS
'Лог справочников.
Для фиксирования изменений в таблицах где есть primary key(id)';
COMMENT ON COLUMN LOGS.TNAME   IS 'Имя таблицы - источника';
COMMENT ON COLUMN LOGS.FNAME   IS 'Имя поля в таблице-источнике';
COMMENT ON COLUMN LOGS.ID_SRC  IS 'Первичный ключ записи в таблице-источнике';
COMMENT ON COLUMN LOGS.A       IS 'Action (I/U/D)';
COMMENT ON COLUMN LOGS.VAL     IS 'Новое значение в логируемом поле';
COMMENT ON COLUMN LOGS.VAL_OLD IS 'Старое значение в логируемом поле';
COMMENT ON COLUMN LOGS.A_DT    IS 'Дата-время изменения';
COMMENT ON COLUMN LOGS.A_USER  IS 'Кто изменил';
COMMENT ON COLUMN LOGS.A_IP    IS 'С какого IP было изменение';
COMMENT ON COLUMN LOGS.A_EXE   IS 'Из какой программы были изменения.';
Тест триггера получается широковат, но если строки заворачивать то очень сильно страдает читаемость.
 В нормальном редакторе или в IBExpert на мониторе FullHD получается вполне удобно.
 
 ID, понятное дело, в этих таблицах не меняется, просто я не стал делать исключение для этого поля.
 
 
 В программе в контекстном меню справочников есть пункт "История" - вызываем стандартное окошко просмотра лога, передавая ему в параметре ID и название таблицы.
SET TERM ^ ;
CREATE OR ALTER TRIGGER SPUB_AIUD_LOGS FOR SPUB
ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 0
as
declare variable vtname  varchar(31);
declare variable va      char(1);
declare variable vid_src integer;
begin
  --
  -- Логирование изменений
  --
  if (gen_id(GEN_SW_LOGS_SPUB, 0) = 0) then exit;
  --
  vtname = 'SPUB';
  --
  if (inserting) then begin va = 'I'; vid_src = new.id; end else
  if (updating ) then begin va = 'U'; vid_src = old.id; end else
  if (deleting ) then begin va = 'D'; vid_src = old.id; end
                 else begin va = '?'; vid_src = null;   end
  --
  -- обработка полей
  --
  if ((updating and new.id           is distinct from old.id          ) or inserting or deleting) then insert into logs(tname, fname, a, id_src, val_old, val) values(:vtname, 'ID'            , :va, :vid_src, old.id   , new.id          );
  if ((updating and new.name         is distinct from old.name        ) or inserting or deleting) then insert into logs(tname, fname, a, id_src, val_old, val) values(:vtname, 'NAME'          , :va, :vid_src, old.name , new.name        );
  --
end
^
SET TERM ; ^
В самом окошке, если интересует история конкретного поля, можно дополнительно зафильтровать.
 
 Для примера взят очень простой справочник, а есть такие где например 50 полей. Триггер увеличивается, главное не забыть при модификации таблицы поменять и триггер.
 Т.к. у меня все базы одинаковой структуры, а логирование не везде имеет смысл - то сделано отключение логирования, через значения в соответствующем генераторе. Способ не очень корректный т.к. доступ к генераторам есть у всех.
 
 Т.к. лог растет довольно быстро, я примерно раз в год делаю выгрузку старых записей во внешнюю базу архивов логов, оставляя в рабочей базе логов за последние 2 года.
 В окне просмотра лога есть возможность посмотреть историю как из рабочей так и из архивной базы логов.
 
 Из минусов - все значения приведены к строке, не поддерживаются блобы. Но на практике это мне еще ни разу не мешало.
 
 |  
	|  |  |  
	|  |  
	|  |  
	| 
		
			| Re: логгирование работы [сообщение #490 является ответом на сообщение #487] | Tue, 06 September 2022 14:35   |  
			| 
				
				|  |  Док Сообщений: 101
 Зарегистрирован: June 2022
 | Senior Member |  |  |  
	| @fraks 
 Володя, спасибо. Как всегда, основательно
  Есть, над чем подумать 
 
 @Старый Плюшев
 
 С целью кто и что удалил из данных, если что
  
 Вообще-то, в этот раз я спланировал архитектуру так, что записи физически не удаляются, а помечаются "удаленными" (физически удалить их может только DBA).  А логи только помогут найти виновных. Просто есть пару заказов от мелких клиник, там потеря данных критична
 
 
 @hvlad
 
 У меня как раз есть желание избежать велосипедостроительства. И твои дельные советы оказали бы мне более существенную помощь, чем сарказм
  
 
 
 FPC/Lazarus (trunk) | Win10 x64 Ultim/Debian 11 amd64/Darwin x86_64 Monterey | Firebird 3.0.10 x64 | IBX by TonyWhyman
 
 https://zoltanleo.blogspot.com/
 [Обновления: Tue, 06 September 2022 14:36] Известить модератора |  
	|  |  |  
	|  |  
	| 
		
			| Re: логгирование работы [сообщение #492 является ответом на сообщение #490] | Tue, 06 September 2022 15:13   |  
			| 
				
				
					|  МП Сообщений: 889
 Зарегистрирован: August 2022
 Географическое положение: бурятский тун...
 | Senior Member |  |  |  
	| Док Вообще-то, в этот раз я спланировал архитектуру так, что записи физически не удаляются, а помечаются "удаленными" (физически удалить их может только DBA).  А логи только помогут найти виновных. Просто есть пару заказов от мелких клиник, там потеря данных критичнатам где помечаешь запись "удалённой", там же и помечай КТО и КОГДА. я же показывал как.
 полное логгирование всего и вся в большинстве случаев нафиг не нужно.
 [Обновления: Tue, 06 September 2022 15:16] Известить модератора |  
	|  |  |  
	|  |  
	| 
		
			| Re: логгирование работы [сообщение #500 является ответом на сообщение #490] | Tue, 06 September 2022 17:40   |  
			| 
				
				
					|  hvlad Сообщений: 381
 Зарегистрирован: August 2022
 | Senior Member |  |  |  
	| Док писал(а) Tue, 06 September 2022 14:35 Цель "сарказма" ровно одна - заставить думать над собственными действиями.@hvlad
 
 У меня как раз есть желание избежать велосипедостроительства. И твои дельные советы оказали бы мне более существенную помощь, чем сарказм
  
 
 И это часто лучше, чем готовые рецепты.
 Я так считаю.
 
 [Обновления: Tue, 06 September 2022 17:42] Известить модератора |  
	|  |  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	| 
		
			| Re: логгирование работы [сообщение #518 является ответом на сообщение #505] | Wed, 07 September 2022 12:42   |  
			| 
				
				
					|   Сообщений: 204
 Зарегистрирован: September 2022
 | Senior Member |  |  |  
	| Док, ты логируй критически важные документы, а не таблички. На уровне клиентского приложения, не на уровне базы. Тогда можно будет логировать не только модификацию данных, но факт обращения к данным (построение отчета, например).
 Заведи табличку (или даже базу) - помойку, в которую сливай интересные с твоей точки зрения факты и данные.
 В табличке поля: момент времени, типа события, тип документа, пользователь, и блоб - поле для текста (json, например, сжатый zip-ом). И сделай простой браузер для просмотра.
 
 |  
	|  |  |  
	|  | 
 
 
 Текущее время: Fri Oct 31 07:57:07 GMT+3 2025 
 Общее время, затраченное на создание страницы: 0.01575 секунд |