写本地日志(方法/日志类)

本文介绍了一个使用Delphi编写的日志记录组件,该组件能够自动保存日志信息,并支持定时保存功能。通过定时器,组件每500毫秒自动保存一次日志,同时具备自动修改日志文件名的功能,确保每次保存前调用相应的函数进行日志文件的更新。

 

procedure writeWorkLog(sqlstr: string);
var filev: TextFile;
  ss: string;
begin
  sqlstr:=DateTimeToStr(Now)+' Log: '+sqlstr;
  ss:='c:\ErpRunLog.txt';
  if FileExists(ss) then
  begin
    AssignFile(filev, ss);
    append(filev);
    writeln(filev, sqlstr);
  end else begin
    AssignFile(filev, ss);
    ReWrite(filev);
    writeln(filev, sqlstr);
  end;
  CloseFile(filev);
end;
unit WriteLog;

interface
  uses SysUtils,windows, Classes,ExtCtrls,Forms;

type
  TWriteLog = class
  Private
    logs:TstringList;
    //定时器,每隔500ms自动保存一次。
    FTmrSave:TTimer;
    FAutoSave: Boolean;
    FLogName: String;
    FLogPath: String;
    //定时器的事件。
    procedure OnAutoSave(Sender:TObject);
    procedure SetAutoSave(const Value: Boolean);
    //定时修改Log文件名.每次保存之前要调用此函数
    procedure SetLogName();
  public
    constructor Create;
    //退出时要保存一次.
    destructor Destroy; Override;
    //添加要保存的log信息。自动附上时间。
    procedure Addlog(sLog:string);
  Published
    //是否自动保存
    property AutoSave:Boolean Read FAutoSave Write SetAutoSave;
    //日志文件名.
    property LogName :String Read FLogName Write FLogName;
    Property LogPath :String Read FLogPath Write FLogPath;
  end;

var
  Gv_Log: TWriteLog;

implementation


procedure TWriteLog.SetLogName;
var
  sPath,sDate:string; 
begin
  sDate:=FormatDateTime('yyyymmdd',Date);
  if FLogPath <>'' then
    sPath := FLogPath
  else
    sPath:=ExtractFilePath(Application.ExeName)+'LOG_PAY';

  if not DirectoryExists(sPath) Then
    CreateDir(sPath);
  if Copy(sPath,Length(sPath),1)<>'\' then
    sPath:=sPath+'\';

  {//如果有重复的就改名。
  i:=1;
  if not FileExists(sPath+sDate+'.log') then
  begin
    fLogName:=sPath+sDate+'.Log';
  end
  else
  begin
    while fileExists(sPath+sDate+'--'+intToStr(i)+'.Log') do
      inc(i);
    fLogName:=sPath+sDate+'--'+intToStr(i)+'.Log';
  end;
  }
  // 不检查是否有重名的文件。
  FLogName:=sPath+sDate+'.Log';

end;

constructor TWriteLog.Create;
begin
  Inherited;
  FLogPath := '';
  
  FTmrSave:=TTimer.Create(Nil);
  FTmrSave.Interval:=500;
  FTmrSave.OnTimer:=OnAutoSave;
  //设置log文件名.
  
  SetLogName;
  logs:=TStringList.Create;
end;
destructor TWriteLog.Destroy;
begin
  //保存
  OnAutoSave(Nil);
  FTmrSave.Free;
  logs.Free;
  Inherited;
end;

procedure TWriteLog.Addlog(sLog:string);
begin
  logs.Add(DateTimeToStr(now)+Char(vk_Tab)+sLog);
  //logs.Add(sLog);
  if not FTmrSave.Enabled Then
    FTmrSave.Enabled:=True;
end;

procedure TWriteLog.OnAutoSave(Sender: TObject);
var
  F: TFileStream; 
begin
  FTmrSave.Enabled:=false;
  if Logs.Count>0 Then
  begin
    SetLogName;
    
    if FileExists(fLogName) then
    begin
      F:=TFileStream.Create(fLogName,fmOpenWrite);
    end
    else begin
      F:=TFileStream.Create(fLogName,fmCreate,fmShareExclusive);
    end;
    F.Seek(0,soFromEnd);
    Logs.SaveToStream(F);
    F.Free;
    Logs.Clear;
    FTmrSave.Enabled:=true;
  end;
end;

procedure TWriteLog.SetAutoSave(const Value: Boolean);
begin
  FAutoSave := Value;
  Self.FTmrSave.Enabled := Value;
end;


end.





 

长时间运行的程序(例如服务器程序),或者流程复杂的多线程程序,打日志几乎是必需的,然而易这个圈子我到目前为止没有见过任何一个正经的日志轮子。 关于无锁 :无锁直接在未知的项目中大量使用的话,可能会比有锁的日志安全。 关于性能 :开启自动轮替,比 CreateFile + WriteFile + 临界资源 直接写慢一点, 但是要注意 ,后者没有自动轮替,而且后者的自动轮替实现起来相对复杂,而且轮替的过程中容易阻塞、死锁或者丢失日志,而打日志最重要的就是【千万不要丢失日志】。 什么是自动轮替: 英文名 LogRotate,例如日志文件隔了一天就要换一个文件,否则文件越来越大,而且也不好整理和管理。比如默认每隔一天轮替一次。 我在这个日志系统里还加入了按照文件大小轮替,比如默认 100MB 轮替一次,太大了分析起来很吃力,编辑器带不动(我的日志不会太多,所以我自己使用会按照 10MB 来轮替,但是如果你的日志很频繁,轮替大小设置太小就会影响性能了)。 关于代码 : 代码从某天想起到成型也没有多久(事实上今天才算写了个雏形),没有经历过正式的项目,经历了好几个版本所以也没有整理得很好看(相对的,可读性也还算可以了)。注释不多,对原理感兴趣的可以自行面向搜索引擎理解,不懂也可以交流。 吐槽 : 易的自定义数据型真的慢啊。。。感谢 kyozy 指点,以后能不用自定义数据型就不用了。 最后,这是个简陋的轮子,希望各位多多扩展和贡献代码,一个人的精力有限,所涉及的项目规模和场景也有限,所以... 我觉得这是个简陋但是很有意义的源码,希望各位与我一起完成它。 源码下载: 测试看  _临时子程序()  下面的  测试_无锁日志()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值