今天调程序,要用到日志。XE7有Qlog,D7用什么
从网上找到了Logger,下载的原文是不支持D7的,不过也只是很少的地方不同,自己修改了下就可以用了
感谢原作者和红鱼的分享
unit Logger; // ======================================================================= // 鏃ュ織绫伙紙TLogger锛?ver.1.0 // 绾㈤奔鍎?http://blog.sina.com.cn/hblyuhong // 2014/06/24 // 鍩轰簬1.0淇�敼 // PFeng (http://www.pfeng.org / xxmc01#gmail.com) // 2012/11/08 // 鏃ュ織绾у埆绾﹀畾锛? // 0 - Information // 1 - Notice // 2 - Warning // 3 - Error // ======================================================================= interface uses Windows, Classes, SysUtils, StdCtrls, ComCtrls, ComObj, Messages; const WRITE_LOG_DIR = 'log'; // 璁板綍鏃ュ織榛樿�鐩�綍 WRITE_LOG_MIN_LEVEL = 0; // 璁板綍鏃ュ織鐨勬渶浣庣骇鍒�紝灏忎簬姝ょ骇鍒�彧鏄剧ず涓嶈�褰? WRITE_LOG_ADD_TIME = True; // 璁板綍鏃ュ織鏄�惁娣诲姞鏃堕棿 WRITE_LOG_TIME_FORMAT = 'hh:nn:ss.zzz'; // 璁板綍鏃ュ織娣诲姞鏃堕棿鐨勬牸寮? SHOW_LOG_ADD_TIME = True; // 鏃ュ織鏄剧ず瀹瑰櫒鏄�惁娣诲姞鏃堕棿 SHOW_LOG_TIME_FORMAT = 'yyyy/mm/dd hh:nn:ss.zzz'; // 鏃ュ織鏄剧ず娣诲姞鏃堕棿鐨勬牸寮? SHOW_LOG_CLEAR_COUNT = 1000; // 鏃ュ織鏄剧ず瀹瑰櫒鏈€澶ф樉绀烘潯鏁? type TLogger = class private FCSLock: TRTLCriticalSection; // 涓寸晫鍖? FFileStream: TFileStream; // 鏂囦欢娴? FLogShower: TComponent; // 鏃ュ織鏄剧ず瀹瑰櫒 FLogName: String; // 鏃ュ織鍚嶇О FEnabled: Boolean; FLogFileDir: string; // 鏃ュ織鐩�綍 procedure SetEnabled(const Value: Boolean); procedure SetLogFileDir(const Value: string); procedure SetLogShower(const Value: TComponent); protected procedure ShowLog(Log: String; const LogLevel: Integer = 0); public procedure WriteLog(Log: String; const LogLevel: Integer = 0); overload; procedure WriteLog(Log: String; const Args: array of const; const LogLevel: Integer = 0); overload; constructor Create; destructor Destroy; override; // 启用 property Enabled: Boolean read FEnabled write SetEnabled; // 日志目录 property LogFileDir: string read FLogFileDir write SetLogFileDir; // 显示控件 property LogShower: TComponent read FLogShower write SetLogShower; end; implementation constructor TLogger.Create; begin InitializeCriticalSection(FCSLock); FLogShower := nil; LogFileDir := ExtractFilePath(ParamStr(0)) + WRITE_LOG_DIR; end; procedure TLogger.WriteLog(Log: String; const Args: array of const; const LogLevel: Integer = 0); begin WriteLog(Format(Log, Args), LogLevel); end; procedure TLogger.WriteLog(Log: String; const LogLevel: Integer = 0); var logName: String; fMode: Word; Fstrs:TStringStream; begin EnterCriticalSection(FCSLock); try if not Enabled then Exit; ShowLog(Log, LogLevel); // 鏄剧ず鏃ュ織鍒板�鍣? if LogLevel >= WRITE_LOG_MIN_LEVEL then begin logName := FormatDateTime('yyyymmdd', Now) + '.log'; if FLogName <> logName then begin FLogName := logName; if FileExists(FLogFileDir + FLogName) then // 濡傛灉褰撳ぉ鐨勬棩蹇楁枃浠跺瓨鍦? fMode := fmOpenWrite or fmShareDenyNone else fMode := fmCreate or fmShareDenyNone; if Assigned(FFileStream) then FreeAndNil(FFileStream); FFileStream := TFileStream.Create(FLogFileDir + FLogName, fMode); end; FFileStream.Position := FFileStream.Size; // 杩藉姞鍒版渶鍚? case LogLevel of 0: Log := '[Information] ' + Log; 1: Log := '[Notice] ' + Log; 2: Log := '[Warning] ' + Log; 3: Log := '[Error] ' + Log; end; if WRITE_LOG_ADD_TIME then Log := FormatDateTime(WRITE_LOG_TIME_FORMAT, Now) + ' ' + Log + #13#10; Fstrs:=TStringStream.Create(log); Fstrs.Position:=0; FFileStream.CopyFrom(Fstrs,Fstrs.Size); end; finally FreeAndNil(Fstrs); LeaveCriticalSection(FCSLock); end; end; procedure TLogger.SetEnabled(const Value: Boolean); begin FEnabled := Value; end; procedure TLogger.SetLogFileDir(const Value: string); begin FLogFileDir := Value; if not DirectoryExists(FLogFileDir) then if not ForceDirectories(FLogFileDir) then begin raise Exception.Create('日志路径错误,日志类对象不能被创建'); end; end; procedure TLogger.SetLogShower(const Value: TComponent); begin FLogShower := Value; end; procedure TLogger.ShowLog(Log: String; const LogLevel: Integer = 0); var lineCount: Integer; listItem: TListItem; begin if FLogShower = nil then Exit; if (FLogShower is TMemo) then begin if SHOW_LOG_ADD_TIME then Log := FormatDateTime(SHOW_LOG_TIME_FORMAT, Now) + ' ' + Log; lineCount := TMemo(FLogShower).Lines.Add(Log); // 滚动到最后一个 SendMessage(TMemo(FLogShower).Handle, WM_VSCROLL, SB_LINEDOWN, 0); if lineCount >= SHOW_LOG_CLEAR_COUNT then TMemo(FLogShower).Clear; end else if (FLogShower is TListBox) then begin if SHOW_LOG_ADD_TIME then Log := FormatDateTime(SHOW_LOG_TIME_FORMAT, Now) + ' ' + Log; lineCount := TListBox(FLogShower).Items.Add(Log); SendMessage(TListBox(FLogShower).Handle, WM_VSCROLL, SB_LINEDOWN, 0); if lineCount >= SHOW_LOG_CLEAR_COUNT then TListBox(FLogShower).Clear; end else if (FLogShower is TListView) then begin listItem := TListView(FLogShower).Items.Add; if SHOW_LOG_ADD_TIME then listItem.Caption := FormatDateTime(SHOW_LOG_TIME_FORMAT, Now); if Assigned(TListView(FLogShower).SmallImages) and (TListView(FLogShower).SmallImages.Count - 1 >= LogLevel) then listItem.ImageIndex := LogLevel; // 根据不同等级显示不同图片 listItem.SubItems.Add(Log); SendMessage(TListView(FLogShower).Handle, WM_VSCROLL, SB_LINEDOWN, 0); if TListView(FLogShower).Items.Count >= SHOW_LOG_CLEAR_COUNT then TListView(FLogShower).Items.Clear; end else raise Exception.Create('日志容器类型不支持' + FLogShower.ClassName); end; destructor TLogger.Destroy; begin DeleteCriticalSection(FCSLock); if Assigned(FFileStream) then FreeAndNil(FFileStream); end; end.