Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.09.2015, 08:28   #1
Prostaf
Пользователь
 
Регистрация: 09.09.2015
Сообщений: 25
По умолчанию Логирование в Delphi

Здравствуйте, уважаемые форумчане. Вопрос. Мне нужно сделать логирование серверной части моего проекта. Сервер не особо сложный, он просто принимает http запросы, обрабатывает их и формирует .xml ответ. Дело в том, что с логированием никогда не сталкивался. Будьте добры, подскажите, с чего начать, что следует знать и прочее, буду благодарен!

P.S ссылать на статьи по логированию не нужно, ибо был уже там, хотелось бы более простого и понятного объяснения.
Prostaf вне форума Ответить с цитированием
Старый 22.09.2015, 08:43   #2
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Ну, попробуй начать с просмотра вот этого:
Код:
unit uEventLog;

interface

uses
  //============================== Модули проекта ==============================
  //========================= Модули проекта с формами =========================
  //=============================== Левые модули ===============================
  //=================== Системные модули, добавленные вручную ==================
  Windows, Messages, Classes, SysUtils;

type
  TTimerProc = procedure (hWindow: HWND; uMsg, idEvent, dwTime: DWORD); stdcall;
  TEventLog = class(TStringList)
  private
    //
    TIMER_ID: DWORD;
    FTimerProc: TTimerProc;
    //
    FActive: Boolean;
    FFileName: string;
    FTimes: Boolean;
    FTimerInterval: DWORD;


    procedure SetTimerInterval(const ANew: DWORD);
  protected
    function TimeStr: string; virtual;
  public
    constructor Create(const AFileName: string); reintroduce;
    destructor Destroy; override;
    function Flush(const AFileName: string = ''): Boolean;

    procedure Add(const S: string); reintroduce; //override;
    procedure AddLine(const ALine: string);
    procedure AddWindowMessage(const hWindow: HWND; const MSG_ID, WParam, LParam: DWORD);
    procedure AddObjectAbout(AObj: TObject; const AAbout: string);

    property Active: Boolean read FActive write FActive;
    property FileName: string read FFileName;
    property Times: Boolean read FTimes write FTimes;
    property TimerInterval: DWORD read FTimerInterval write SetTimerInterval;
  end;

var
  EventLog: TEventLog;
  TempFolder: string;

const
  MillisecondsInDay = 86400000;

function TicksToDateTimeStr(const TC: DWORD): string;

implementation

procedure TimerProc(hWindow: HWND; uMsg, idEvent, dwTime: DWORD); stdcall;
begin
  EventLog.AddLine('Autoflush.');
  EventLog.Flush();
end;

function TicksToDateTime(const TC: DWORD): TDateTime;
begin
  // TC - целое число миллисекунд.
  // сутки в миллисекундах = 24 * 3600 * 1000 = 86400000 - целая часть TDateTime
  Result:= TC / MillisecondsInDay;
end;

function TicksToDateTimeStr(const TC: DWORD): string;
var
  dt: TDateTime;
  Days: DWORD;
begin
  dt:= TC / MillisecondsInDay;
  Days:= Trunc(dt);
  if Days = 0
    then Result:= TimeToStr(Time)
    else Result:= IntToStr(Days) + 'd, ' + TimeToStr(Time);
end;

{ TEventLog }

procedure TEventLog.Add(const S: string);
begin
  if FActive then inherited Add(S);
end;

procedure TEventLog.AddLine(const ALine: string);
begin
  Add(TimeStr + ALine);
end;

procedure TEventLog.AddObjectAbout(AObj: TObject; const AAbout: string);
begin
  if (AObj is TComponent) and (TComponent(AObj).Name <> '')
    then AddLine(TComponent(AObj).Name + ' - ' + AAbout)
    else AddLine(AObj.ToString + ' - ' + AAbout);
end;

procedure TEventLog.AddWindowMessage(const hWindow: HWND; const MSG_ID, WParam,
  LParam: DWORD);
begin
  AddLine(Format('0x%.8X <--- ID: 0x%.8X; WParam: 0x%.8X; LParam: 0x%.8X',
                 [hWindow, MSG_ID, WParam, LParam]));
end;

constructor TEventLog.Create(const AFileName: string);
begin
  inherited Create();
  FFileName:= AFileName;
  FTimes:= True;
  FActive:= True;
  FTimerProc:= TimerProc;

  AddLine('--------- СТАРТ ---------');
  Add(FFileName);
end;

destructor TEventLog.Destroy;
begin
  SetTimerInterval(0);
  AddLine('--------- ВЫХОД ---------');
  if not Self.Flush()
    then Self.Flush(IncludeTrailingPathDelimiter(TempFolder) +
                    ChangeFileExt(ExtractFileName(ParamStr(0)), '.log'));
  inherited;
end;

function TEventLog.Flush(const AFileName: string = ''): Boolean;
begin
  try
    if AFileName = ''
      then Self.SaveToFile(FFileName)
      else Self.SaveToFile(AFileName);

    Result:= True;
  except
    Result:= False;
  end;
end;

procedure TEventLog.SetTimerInterval(const ANew: DWORD);
begin
  if ANew = FTimerInterval
    then Exit;

  FTimerInterval:= ANew;

  // сначала убить установленный таймер, если есть
  if TIMER_ID <> 0
    then KillTimer(0, TIMER_ID);

  // затем создать новый
  if ANew <> 0
    then TIMER_ID:= SetTimer(0, 0, FTimerInterval, @FTimerProc)
    else TIMER_ID:= 0;
end;

function TEventLog.TimeStr: string;
begin
  if FTimes
    then Result:= '[' + TimeToStr(Time()) + ']: '
    else Result:= '';
end;

initialization
  TempFolder:= GetEnvironmentVariable('TEMP');
  EventLog:= TEventLog.Create(ChangeFileExt(ParamStr(0), '.log'));

finalization
  EventLog.Free();


end.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 22.09.2015, 08:45   #3
Toxa
Форумчанин Подтвердите свой е-майл
 
Аватар для Toxa
 
Регистрация: 01.12.2006
Сообщений: 514
По умолчанию

Цитата:
хотелось бы более простого и понятного объяснения.
понатыкай в программе в важных местах запись в файл/БД/куда_угодно и добавь обработку ошибок с записью текста ошибки в то же место.
я, например, логирую все места где потенциально может возникнуть ошибка
Код:
try
except on exception do
log(e.message);
end;
и просто ставлю контрольные точки, чтобы знать какие действия выполнились перед ошибкой
Пишу на Delphi за еду
Toxa вне форума Ответить с цитированием
Старый 22.09.2015, 08:47   #4
Prostaf
Пользователь
 
Регистрация: 09.09.2015
Сообщений: 25
По умолчанию

Цитата:
Сообщение от Toxa Посмотреть сообщение
понатыкай в программе в важных местах запись в файл/БД/куда_угодно и добавь обработку ошибок с записью текста ошибки в то же место.
я, например, логирую все места где потенциально может возникнуть ошибка
Код:
try
except on exception do
log(e.message);
end;
и просто ставлю контрольные точки, чтобы знать какие действия выполнились перед ошибкой
т.е. можно в каждую процедуру или функцию просто писать что-то такое?
procedure TdmServer.DataModuleCreate(Sender: TObject);
begin
Log(' ');
end;
И когда процедура или функция выполняется, то записи будут попадать в лог?
Prostaf вне форума Ответить с цитированием
Старый 22.09.2015, 08:50   #5
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
И когда процедура или функция выполняется, то записи будут попадать в лог?
Ты мой прототип смотрел? Там всё это так и организовано.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 22.09.2015, 08:51   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Дозапись в конец текстового файла. Можно используя AssignFile и компанию, можно FileOpen со своей компашкой. Открывать и закрывать файл по каждой дозаписи
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 22.09.2015, 08:57   #7
Prostaf
Пользователь
 
Регистрация: 09.09.2015
Сообщений: 25
По умолчанию

Всем спасибо за примеры и помощь. А как быть, если код написан в 2-х юнитах?
Prostaf вне форума Ответить с цитированием
Старый 22.09.2015, 09:01   #8
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
А как быть, если код написан в 2-х юнитах?
К логированию это не имеет никакого отношения.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 22.09.2015, 09:05   #9
Prostaf
Пользователь
 
Регистрация: 09.09.2015
Сообщений: 25
По умолчанию

Цитата:
Сообщение от min@y™ Посмотреть сообщение
К логированию это не имеет никакого отношения.
Спасибо за совет и пример!
Prostaf вне форума Ответить с цитированием
Старый 22.09.2015, 09:05   #10
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
А как быть, если код написан в 2-х юнитах?
Процедуры логирования в отдельном юните. В uses-ах юнитов, из которых к ним обращение ссыль на этот юнит. Вообщ-то это стандартная практика, а не только для логирования
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Логирование qZED Общие вопросы Delphi 18 13.01.2014 15:17
python логирование Lemon2009 PHP 1 11.09.2012 15:59
Логирование EventLog mrChester Общие вопросы .NET 7 18.04.2012 09:55
Логирование запуска программы Dima DDM Общие вопросы Delphi 0 05.08.2011 15:48