Delphi 5. Учебник



         

Запись в Log-файл



    Запись отладочной информации в файл протокола (Log-файл) существенно отличается от предыдущих приемов записи, так как это уже нельзя назвать "быстро и грязно". Это отличная технология, которую можно использовать в любом приложении.
    Запись в файл протокола выполняется так же, как и вывод на консоль, но вместо WriteLn (. . . ) используется WriteLn (LogFile, . . . ), где LogFile — имя файловой переменной типа TextFile. Надо также не забывать открывать этот файл в начале работы приложения и закрывать — в конце. Проще всего этого добиться, поместив соответствующий код в свой модуль, который благодаря возможности условной компиляции подключается только в отладочной версии вашей программы.

Листинг 2.1. Модуль протоколирования отладочной информации.

    unit uLoq;
    interface
    procedure Log(S: Strings-implementation uses
        Windows, SysUtils;
    var
        LogFile: TextFile;
        LogCriticalSection: TRtlCriticalSection;
    procedure Log(S: String);
    var
        SystemTime: TSystemTime;
        FileTime: TFileTime;
    begin
        GetSystemTime (SystemTime) ;
        SystemTimeToFileTime(SystemTime, FileTime) ;
        EnterCriticalSection(LogCriticalSection);
        WriteLn(LogFile, Format('%s %.8x%.8x %5',
            [FormatDateTime('yy.mm.dd hh.inm.ss'. Now),
            FileTime.dwHighDateTime, FileTime.dwLowDateTime, S])) ;
        LeaveCriticalSection(LogCriticalSection) ;
    end;
    procedure Startup;
    var
        FileName: String;
    begin
        InitializeCriticalSection(LogCriticalSection);
        FileName := Format("Log file for %s at %s.txf,
            [ParamStr(O), DateTimeToStr(Now)]) ;
        while Pos(':', FileName) 0 do
            FileName[Pos(':', FileName)] := '.';
        while Pos('/', FileName) 0 do
            FileName[Pos('/', FileName)] := '-';
        while Pos('\', FileName) 0 do
            FileName[Pos('\', FileName)] := '.';
        AssignFile(LogFile, FileName);
        Rewrite(LogFile) ;
    end;
    procedure Shutdown;
    begin
        CloseFile(LogFile) ;
        DeleteCriticalSection(LogCriticalSection) ;
    end;
    initialization Startup;
    finalization Shutdown;
end.

    Этот модуль сам создает, открывает и закрывает файл протокола. Имя файла создается с учетом имени приложения и текущих даты и времени, что исключает возможность записи информации поверх существующего файла. Для использования модуля условно включите его, как показано ниже.

    unit MyUnit;
    interface
    uses
        ($ifdef Debug} uLog, {$endif)
        Windows, Messages, SysUtils, Classes,
        . . .

    Затем используйте его приблизительно так.

    {$ifdef Debug)
    Log(Format('Entering the Foo procedure; Bar = %d',[Bar]));
    {$endif}

    He забывайте размещать вызов между директивами условной компиляции, иначе при компиляции коммерческой версии возникнет ошибка.
    Модуль uLog обладает двумя интересными и полезными свойствами. Во-первых, каждая запись в файл предваряется информацией о дате, времени и шестнадцатеричным числом, соответствующим системному времени в миллисекундах. Эта информация может быть весьма полезной, особенно когда вы хотите отследить последовательность событий в приложении. Во-вторых, модуль использует критические разделы (critical section), что обеспечивает доступ к файлу только одной подзадачи в один момент времени.
    На рис. 2.25 показан типичный файл протокола в программе Notepad.  

Рис. 2.25. Пример отладочного файла протокола

    Как правильно использовать файл протокола? Какую информацию в него записывать? Сколько программистов, столько и ответов на эти вопросы. Лично я предпочитаю придерживаться золотой середины между "записывай все" и "записывай только то, что отлаживаешь".




Содержание  Назад  Вперед