unit ULogger; interface uses Classes, SysUtils, StrUtils, WindowsSysVersion, superobject, Dialogs, IdHTTP; type TLogger = class private FLoginName: string; FIP: string; FPlatform: string; FEnable: Boolean; FUrl: string; public procedure Log(AMessage, ACode: string); procedure AsynLog(AMessage, ACode: string); constructor Create(ALoginName, AIP, APlatform, AUrl: string; AEnable: Boolean); end; TLoggerManager = class private FLoggers: TStringList; FPlatform: string; FEnable: Boolean; FUrl, FAppCode, FClientVersion: string; FDefaultLogger: TLogger; FIP: string; public function GetLogger(ALoginName: string): TLogger; procedure Init; constructor Create; destructor Destroy; override; end; TSendLogThread = class(TThread) private FHttp: TidHttp; FMessage: string; FUrl: string; public constructor Create(AUrl: string; AMessage: string); destructor Destroy; override; procedure Execute; override; end; function Log(AMessage, ALoginName, ACode: string): Boolean; function AsynLog(AMessage, ALoginName, ACode: string): Boolean; const CONFIG_DIR: string = 'config\logger.config'; JSON_LOG: string = '{'+ '"appCode":"%s",'+ '"loginName":"%s",'+ '"time":"%d",'+ '"client":'+ '{'+ '"platform":"%s",'+ '"clientVersion":"%s",'+ '"ip":"%s"'+ '},'+ '"exception":'+ '{'+ '"code":"%s",'+ '"message":"%s"'+ '},'+ '"level":"%s"' + '}'; implementation var LoggerManager: TLoggerManager; function Log(AMessage, ALoginName, ACode: string): Boolean; var ALogger: TLogger; begin if (LoggerManager = nil) then begin LoggerManager := TLoggerManager.Create; LoggerManager.Init; end; if (not LoggerManager.FEnable) then Exit; ALogger := LoggerManager.GetLogger(ALoginName); ALogger.Log(AMessage, ACode); end; function AsynLog(AMessage, ALoginName, ACode: string): Boolean; var ALogger: TLogger; begin if (LoggerManager = nil) then begin LoggerManager := TLoggerManager.Create; LoggerManager.Init; end; if (not LoggerManager.FEnable) then Exit; ALogger := LoggerManager.GetLogger(ALoginName); ALogger.AsynLog(AMessage, ACode); end; { TLogger } constructor TLogger.Create(ALoginName, AIP, APlatform, AUrl: string; AEnable: Boolean); begin FLoginName := ALoginName; FIP := AIP; FPlatform := APlatform; FUrl := AUrl; FEnable := AEnable; end; procedure TLogger.Log(AMessage, ACode: string); var AJson: string; ASendThread: TSendLogThread; begin AJson := Format(JSON_LOG, [FLoginName, Now, FPlatform, FIP, ACode, AMessage]); ASendThread := TSendLogThread.Create(FUrl, Ajson); end; procedure TLogger.AsynLog(AMessage, ACode: string); var AJson: TStringStream; AHttp: TIdHTTP; Respone: string; begin AJson := TStringStream.Create(AnsiToUtf8(Format(JSON_LOG, [FLoginName, Now, FPlatform, FIP, ACode, AMessage]))); AHttp := TIdHttp.Create(nil); AHttp.HandleRedirects := True;//允许头转向 AHttp.ReadTimeout := 5000;//请求超时设置 try AJson.Position := 0; Respone := AHttp.Post(FUrl, AJson); Respone := Utf8ToAnsi(Respone) finally AJson.Free; AHttp.Free; end; end; { TLoggerManager } constructor TLoggerManager.Create; begin FLoggers := TStringList.Create; inherited Create; end; destructor TLoggerManager.Destroy; var ALogger: TLogger; begin while FLoggers.Count > 0 do begin ALogger :=FLoggers.Objects[0] as TLogger; FLoggers.Delete(0); FreeAndNil(ALogger); end; FreeAndNil(FLoggers); if Assigned(FDefaultLogger) then FreeAndNil(FDefaultLogger); inherited; end; function TLoggerManager.GetLogger(ALoginName: string): TLogger; var index: Integer; ALogger: TLogger; begin if ALoginName = '' then begin Result := FDefaultLogger; Exit; end; index := FLoggers.IndexOf(ALoginName); if index > -1 then Result := FLoggers.Objects[index] as TLogger else begin ALogger := TLogger.Create(ALoginName, FIP, FPlatform, FUrl, FEnable); Result := ALogger; FLoggers.AddObject(ALoginName, ALogger); end; end; procedure TLoggerManager.Init; var AVersion: TWinVer; AFullPath: string; jo: ISuperObject; p: PChar; begin case GetWindowsSystemVersion of WinNone: FPlatform := '未知'; Win95: FPlatform := 'Windows 95'; Win98: FPlatform := 'Windows 98'; WinMe: FPlatform := 'Windows Me'; Win2000: FPlatform := 'Windows 2000'; WinServer2000: FPlatform := 'Windows Server 2000'; WinXp: FPlatform := 'Windows XP'; WinXp64: FPlatform := 'Windows XP x64'; WinServer2003: FPlatform := 'Windows Server 2003'; WinHomeServer: FPlatform := 'Windows Home Server'; WinServer2003R2: FPlatform := 'Windows Server 2003 R2'; WinVista: FPlatform := 'Windows Vista'; WinServer2008: FPlatform := 'Windows Server 2008'; WinServer2008R2: FPlatform := 'Windows Server 2008 R2'; Win7: FPlatform := 'Windows 7'; end; AFullPath := ExtractFilePath(ParamStr(0)) + CONFIG_DIR; if not FileExists(AFullPath) then begin FEnable := False; Exit; end; FIP := LocalIP; try jo := TSuperObject.ParseFile(AFullPath, False); FEnable := jo['enable'].AsBoolean(); FUrl := jo['url'].AsString(); except on E: Exception do begin FEnable := False; Dialogs.ShowMessage(E.Message); end; end; FDefaultLogger := TLogger.Create('', FIP, FPlatform, FUrl, FEnable); end; { TSendLogThread } constructor TSendLogThread.Create(AUrl, AMessage: string); begin FHttp := TIdHttp.Create(nil); FHttp.HandleRedirects := True;//允许头转向 FHttp.ReadTimeout := 5000;//请求超时设置 FUrl := AUrl; FMessage := AMessage; inherited Create(False); end; destructor TSendLogThread.Destroy; begin FHttp.Free; inherited; end; procedure TSendLogThread.Execute; var AJson: TStringStream; begin AJson := TStringStream.Create(AnsiToUtf8(FMessage)); try // Dialogs.ShowMessage(FMessage); AJson.Position := 0; FHttp.Post(FUrl, AJson); finally AJson.Free; end; end; initialization LoggerManager := TLoggerManager.Create; LoggerManager.Init; finalization if LoggerManager <> nil then FreeAndNil(LoggerManager); end.