⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cllogger.pas

📁 Clever_Internet_Suite_6.2的代码 Clever_Internet_Suite_6.2的代码 Clever_Internet_Suite_6.2的代码
💻 PAS
字号:
{
  Clever Internet Suite Version 6.2
  Copyright (C) 1999 - 2006 Clever Components
  www.CleverComponents.com
}

unit clLogger;

interface

uses
  Classes, Windows, SysUtils, SyncObjs;

type
  TclLogEntryDirection = (edEnter, edLeave, edInside);

  TclLogger = class
  private
    FAccessor: TCriticalSection;
    FLogFileName: string;
    constructor CreateInstance;
    class function AccessInstance(Request: Integer): TclLogger;
    procedure PutMessageToFile(const AFileName, AMessage: string);
    procedure PutDataToFile(const AFileName: string; AData: PChar; ADataSize: Integer);
  public
    constructor Create;
    destructor Destroy; override;
    class function Instance: TclLogger;
    class procedure ReleaseInstance;

    procedure SetLogMessageFile(const AFileName: string);
    procedure InitLogMessage(const AFileName: string);
    procedure PutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
      const AMessage: string; E: Exception; const Args: array of const); overload;
    procedure PutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
      const AMessage: string; E: Exception); overload;
    procedure PutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
      const AMessage: string); overload;
    procedure PutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
      const AMessage: string; E: Exception; IsDataConnection: Boolean); overload;
    procedure PutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
      const AMessage: string; AData: PChar; ADataSize: Integer); overload;
    property LogFileName: string read FLogFileName;
  end;

//TEMPLATE
//  {IFDEF LOGGER}try clPutLogMessage(Self, edEnter, 'AssignError');{ENDIF}
//  {IFDEF LOGGER}clPutLogMessage(Self, edLeave, 'AssignError'); except on E: Exception do begin clPutLogMessage(Self, edLeave, 'AssignError', E); raise; end; end;{ENDIF}

procedure clPutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string); overload;

procedure clPutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; E: Exception); overload;

procedure clPutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; E: Exception; const Args: array of const); overload;

procedure clPutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; AData: PChar; ADataSize: Integer); overload;

procedure clPutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; AData: TStream; APosition: Integer); overload;

implementation

procedure clPutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string);
begin
  TclLogger.Instance().PutLogMessage(AInstance, ADirection, AMessage);
end;

procedure clPutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; E: Exception);
begin
  TclLogger.Instance().PutLogMessage(AInstance, ADirection, AMessage, E);
end;

procedure clPutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; E: Exception; const Args: array of const);
begin
  TclLogger.Instance().PutLogMessage(AInstance, ADirection, AMessage, E, Args);
end;

procedure clPutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; AData: PChar; ADataSize: Integer);
begin
  TclLogger.Instance().PutLogMessage(AInstance, ADirection, AMessage, AData, ADataSize);
end;

procedure clPutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; AData: TStream; APosition: Integer); overload;
var
  oldPos, size: Integer;
  buf: PChar;
begin
  try
    oldPos := AData.Position;
    GetMem(buf, AData.Size);
    try
      AData.Position := APosition;
      size := AData.Read(buf^, AData.Size);
      clPutLogMessage(AInstance, ADirection, AMessage, buf, size);
    finally
      FreeMem(buf);
      AData.Position := oldPos;
    end;
  except
  end;
end;

{ TclLogger }

var
  FInstance: TclLogger = nil;

class function TclLogger.AccessInstance(Request: Integer): TclLogger;
begin
  case Request of
    0 : ;
    1 : if not Assigned(FInstance) then FInstance := CreateInstance();
    2 : FInstance := nil;
  else raise Exception.CreateFmt('Illegal request %d in AccessInstance', [Request]);
  end;
  Result := FInstance;
end;

constructor TclLogger.Create;
begin
  inherited Create();
  raise Exception.CreateFmt('Access class %s through Instance only', [ClassName]);
end;

constructor TclLogger.CreateInstance;
begin
  inherited Create();
  FAccessor := TCriticalSection.Create();
  FLogFileName := ExtractFilePath(ParamStr(0)) + '\clevercomponents.log';
  FLogFileName := StringReplace(FLogFileName, '\\', '\', [rfReplaceAll]);
end;

destructor TclLogger.Destroy;
begin
  if AccessInstance(0) = Self then AccessInstance(2);
  FAccessor.Free();
  inherited Destroy();
end;

procedure TclLogger.InitLogMessage(const AFileName: string);
var
  hFile: THANDLE;
  CreationTime, LastAccessTime, LastWriteTime: TFileTime;
  sysTime: TSystemTime;
  sysDate: TDateTime;
begin
  FAccessor.Enter();
  try
    hFile := CreateFile(PChar(AFileName), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
    if (hFile <> INVALID_HANDLE_VALUE) then
    begin
      GetFileTime(hFile, @CreationTime, @LastAccessTime, @LastWriteTime);
      CloseHandle(hFile);
      FileTimeToLocalFileTime(LastWriteTime, LastWriteTime);
      FileTimeToSystemTime(LastWriteTime, sysTime);
      sysDate := SystemTimeToDateTime(sysTime);
      if (sysDate < Date()) then
      begin
        DeleteFile(AFileName);
      end;
    end;
  finally
    FAccessor.Leave();
  end;
  SetLogMessageFile(AFileName);
end;

class function TclLogger.Instance: TclLogger;
begin
  Result:=AccessInstance(1);
end;

procedure TclLogger.PutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; E: Exception);
const
  cDirection: array[TclLogEntryDirection] of string = ('>', '<', '=');
var
  prefix, postfix: string;
  code: DWORD;
begin
  code := GetLastError();
  try
    prefix := FormatDateTime('dd-mm-yyyy:hh-nn-ss-zzz', Now()) + ' ';
    if (AInstance = nil) then
    begin
      prefix := prefix + '0 ';
    end else
    begin
      prefix := prefix + AInstance.ClassName + ' ';
    end;

    prefix := prefix + IntToStr(GetCurrentThreadId()) + ':' + IntToStr(Integer(AInstance))
      + ' ' + cDirection[ADirection] + ' ';
    if (E <> nil) then
    begin
      postfix := ' ' + E.ClassName + ': ' + E.Message;
    end else
    begin
      postfix := ' ';
    end;

    PutMessageToFile(LogFileName, prefix + AMessage + postfix + #13#10);
  finally
    SetLastError(code);
  end;
end;

procedure TclLogger.PutDataToFile(const AFileName: string; AData: PChar; ADataSize: Integer);
var
  hFile: THandle; 
  cnt: Cardinal;
begin
  FAccessor.Enter();
  try
    hFile := CreateFile(PChar(AFileName), GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if (hFile = INVALID_HANDLE_VALUE) then
    begin
      hFile := CreateFile(PChar(AFileName), GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
        CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
    end;
    if (hFile <> INVALID_HANDLE_VALUE) then
    begin
      SetFilePointer(hFile, 0, nil, FILE_END);
      WriteFile(hFile, AData^, ADataSize, cnt, nil);
      CloseHandle(hFile);
    end;
  finally
    FAccessor.Leave();
  end;
end;

procedure TclLogger.PutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; E: Exception; IsDataConnection: Boolean);
const
  data: array[Boolean] of string = ('', 'data: ');
var
  code: DWORD;
begin
  code := GetLastError();
  try
    PutLogMessage(AInstance, ADirection, data[IsDataConnection] + AMessage, E);
  finally
    SetLastError(code);
  end;
end;

procedure TclLogger.PutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection;
  const AMessage: string; E: Exception; const Args: array of const);
var
  code: DWORD;
begin
  code := GetLastError();
  try
    PutLogMessage(AInstance, ADirection, Format(AMessage, Args), E);
  finally
    SetLastError(code);
  end;
end;

procedure TclLogger.PutLogMessage(AInstance: TObject; ADirection: TclLogEntryDirection; const AMessage: string);
var
  code: DWORD;
begin
  code := GetLastError();
  try
    PutLogMessage(AInstance, ADirection, AMessage, nil);
  finally
    SetLastError(code);
  end;
end;

procedure TclLogger.PutMessageToFile(const AFileName, AMessage: string);
var
  hFile: THandle; 
  len, cnt: Cardinal;
  buf: PChar;
begin
  FAccessor.Enter();
  try
    hFile := CreateFile(PChar(AFileName), GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if (hFile = INVALID_HANDLE_VALUE) then
    begin
      hFile := CreateFile(PChar(AFileName), GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
        CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
    end;
    if (hFile <> INVALID_HANDLE_VALUE) then
    begin
      SetFilePointer(hFile, 0, nil, FILE_END);
      len := Length(AMessage) + 1;
      GetMem(buf, len);
      StrCopy(buf, PCHAR(AMessage));
      WriteFile(hFile, buf[0], len - 1, cnt, nil);
      FreeMem(buf);
      CloseHandle(hFile);
    end;
  finally
    FAccessor.Leave();
  end;
end;

class procedure TclLogger.ReleaseInstance;
begin
  AccessInstance(0).Free();
end;

procedure TclLogger.SetLogMessageFile(const AFileName: string);
begin
  FAccessor.Enter();
  try
    FLogFileName := AFileName;
  finally
    FAccessor.Leave();
  end;
end;

procedure TclLogger.PutLogMessage(AInstance: TObject;
  ADirection: TclLogEntryDirection; const AMessage: string; AData: PChar;
  ADataSize: Integer);
const
  eofData = #13#10#13#10;
var
  code: DWORD;
begin
  code := GetLastError();
  try
    if (AData <> nil) and (ADataSize > 0) then
    begin
      PutLogMessage(AInstance, ADirection, AMessage + ' (' + IntToStr(ADataSize) + '): '#13#10);
      PutDataToFile(LogFileName, AData, ADataSize);
      PutDataToFile(LogFileName, eofData, Length(eofData));
    end else
    begin
      PutLogMessage(AInstance, ADirection, AMessage + ' (no data)');
    end;
  finally
    SetLastError(code);
  end;
end;

initialization

finalization
  TclLogger.ReleaseInstance();
  
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -