теперь исходники я заливаю на GitHub: https://github.com/hinst/EPCL, там на странице есть такая замечательная кнопочка "Download", которая позволяет все их разом откачать.
На данный момент я запилил только модули для лога. Теперь они совсем не такие, как были, а сделаны по типу log4j
Собственно, получить представление о том, как оно теперь всё запилено, можно из этого небольшого примера:
- Код: Выделить всё
program log_demo_project;
{$mode objfpc}{$H+}
uses
Classes, log_unit, log_appenders;
{$R *.res}
type
{ TMy }
TMy = class
constructor Create;
private
log: ILogClient;
public
procedure test;
destructor Destroy; override;
end;
var
logman: TLogManager;
{ TMy }
constructor TMy.Create;
begin
inherited Create;
log:=logman.getLogClient(self);
end;
procedure TMy.test;
begin
log.fatal('Fatal error');
log.error('Error');
log.info('Info');
log.debug('Debug');
log.trace('Trace');
log.m(66, 'Custom');
end;
destructor TMy.Destroy;
begin
log.info('Destroyed.');
inherited Destroy;
end;
type
{ TMyAppender }
TMyAppender = class(TLogAppender, ILogAppender)
function appendMessage(const aMessage: PLogMessage): boolean;
end;
{ TMyAppender }
function TMyAppender.appendMessage(const aMessage: PLogMessage): boolean;
begin
if aMessage^.kind <= TLog.error then
WriteLN(' [Application panic]');
end;
var
my: TMy;
begin
logman:=TLogManager.Create(nil);
logman.addAppender(TWritelnLogAppender);
logman.addAppender(TFileLogAppender.Create('log.text'));
logman.addAppender(TMyAppender);
my:=TMy.Create;
my.test;
my.Free;
logman.getLogClient(nil).info('Bye.');
logman.Free;
end.
Смотреть модуль: https://github.com/hinst/EPCL/blob/master/log_unit.pas
Центральный объект - TLogManager, он должен быть, по идее, один на всё приложение
К нему пришпиливаются объекты, которые будут записывать все сообщения. Они реализовывать интерфейс ILogAppender, в котором надо перекрыть единственный метод - appendMessage(...). Работает подсчёт ссылок, и если вы руками не держите указателей на свой аппендер, то он освободится тогда же, когда и TLogManager, то есть, вручную ни один аппендер освобождать не надо.
От экземпляра TLogManager'а можно брать методом getLogClient(тут указывать self) клиенты лога. Они тоже интерфейсы. опять же, работает подсчёт ссылок, ни у кого, кроме вашего объекта, который захотел пописать в лог, указателей после вызова getLogClient не остаётся. То есть, опять же, освобождать клиента лога вручную не надо, он освобождается при смерти писавшего в лог объекта. Всё это я проверял, что так оно всё и работает.
Короче, в сравнении с той схемой, которая была у меня раньше, стало, по-моему, намного лучше.
Вкладываю в сообщение архив с библиотекой, в котором модули, связанные с логгированием, точно работают. Пример использования модулей для лога тоже там лежит, он в подпапке examples/log_demo.
Вот ещё диаграмма, которая как бэ символизирует структуру модуля log_unit.pas: