delphi 日志库log4D

在古老的开发工具delphi的日志库非常稀少,不如其他开发语言,比如C++, .NET等等日志库那么多而且现在仍旧持续更新。

想当年delphi可是无数人的理想的开发工具,和vb开发难度差不多但是他开发出的应用程序性能要好得多。

下面说说淘到宝的log4D,用的人很少网上很少完整的开发教程。

首先,log4D和其他语言的日志库类似,有Logger,Layout,ErrorHandler,Filter,Render,Appender等基本概念。

Logger是日志类,用于提供记录日志的方法。 

Layout是指日志打印的格式

Renderer是指对象渲染器,用于对特定的类进行渲染。

ErrorHandler是错误处理器, 

Filter是过滤器,决定特定的日志事件是否会被记录下来。

Appender,附加器,用于将日志内容附加到特定的地方,比如控制台、文件、数据库、网络等等。

这些详细的就不说了,只说他的用法。毕竟是用他不是要更改他现在没时间来仔细阅读他的代码。

配置文件说明(log4D.props来自https://github.com/pretorean/log4d)下面的配置文件和网上的不同,我只是用文件,其他的ODS不用参照下面的和你下载的一比较就知道如何用。

# Set internal debugging
log4d.configDebug=true //内部的调试模式


# Global logging level
log4d.threshold=info //日志级别 all|fatal|error|warn|info|debug|off


# Set logger factory
log4d.loggerFactory=TLogDefaultLoggerFactory //日志工厂,产生Logger的


# Set root level
log4d.rootLogger=warn,RFile1 //配置根Logger的, 格式为[level],appenderName[,appenderName]...


# Create root appender //下面是根Logger的appender配置,注意名称RFile1必须和上面的意志
log4d.appender.RFile1=TLogRollingFileAppender

//Rolling文件类型,他可以定制在maxBackupIndex个文件见循环。这个功能实现的不强,其他语言可以定义一天一个日志文件


log4d.appender.RFile1.append=true //在文件的末尾插入内容
log4d.appender.RFile1.fileName=C:\Temp\Log4D.txt //文件名称
log4d.appender.RFile1.maxFileSize=1KB //这是测试用的,最大文件尺寸。看看源码也可以是MB GB
log4d.appender.RFile1.maxBackupIndex=2 //循环文件的最大个数
log4d.appender.RFile1.errorHandler=TLogOnlyOnceErrorHandler
log4d.appender.RFile1.layout=TLogPatternLayout //输出格式
log4d.appender.RFile1.layout.dateFormat=yyyy-mm-dd hh:nn:ss.zzz //自定义日期时间格式,年月日 时分秒毫秒
log4d.appender.RFile1.layout.pattern=%d [%t] %p %c %x - %m%n //日志的格式,%d 日期时间 %t线程ID...看看源码


# Establish logger hierarchy //这里是自定义的Logger,格式如上。
log4d.logger.testlog4d=error,File1


# Create a file appender
log4d.appender.File1=TLogFileAppender
log4d.appender.File1.append=true
log4d.appender.File1.fileName=C:\Temp\Log4D.log
log4d.appender.File1.errorHandler=TLogOnlyOnceErrorHandler
log4d.appender.File1.layout=TLogPatternLayout
log4d.appender.File1.layout.dateFormat=yyyy-mm-dd hh:nn:ss.zzz
log4d.appender.File1.layout.pattern=%d [%t] %p %c %x - %m%n


delphi中使用

procedure TForm2.Button1Click(Sender: TObject);
var
    logger1 : TLogLogger;

    logger2 : TLogLogger;
begin
  TLogPropertyConfigurator.Configure('log4d.props'); //此时log4d.props和exe必须在同一目录
  logger1 := TLogLogger.GetLogger('testlog4d'); //这是获得log4d.logger.testlog4d=error,File1,注意名称必须一样否则写不上
  logger1.Error('error output');
  logger1.Warn('warn output');
  logger1.Info('info output');
  logger1.Debug('debug output');
  logger1.Trace('trace output');


  logger2 := TLogLogger.GetRootLogger; //这是获得log4d.rootLogger=warn,RFile1 定义的logger
  logger2.Fatal('fatal output');
  logger2.Error('error output');
  logger2.Warn('warn output');
  logger2.Info('info output');
  logger2.Debug('debug output');
  logger2.Trace('trace output');
end;


执行后参照下日志文件的内容和上面的代码写的,发现了什么?

没发现?

对了,logger1是不是缺少了什么?对的,因为他设置为error,所以只写error,fatal,其他的级别不够忽略了!

Delphi Logger { 超简单实用的DELPHI日志单元 1.0.0 优化版 引用本单元即可使用 一共四个方法 procedure log4error(msg: AnsiString); //写ERROR级别的日志 procedure log4info(msg: AnsiString); //写INFO级别的日志 procedure log4debug(msg: AnsiString); //写DEBUG级别的日志 function log4filename():AnsiString; //得到当前日志文件全名 一个配置文件 log4me.ini #配置文件和主程序在同一目录.没有这个文件或不在主目录中则不写日志 [log4me] #path,日志的存放目录.必须是主程序目录及子目录. #例子:主程序目录 #path=. #例子:子目录 #path=temp\logs path=logs #level,日志等级,只能是 error,info,debug之一 #为error时,只有log4error打印的日志被输出. #为info时,log4error和log4info打印的日志被输出. #为debug时,log4error,log4info,log4debug打印的日志都被输出. level=info 一个可选工具 tail.exe 命令行中输入 >tail.exe -1000f 日志文件名 即可动态查看日志输出 或用程序调用 var cmd :AnsiString; log_file:AnsiString; begin log_file := log4filename(); //得到当前日志文件全名 cmd := ExtractFilePath(ParamStr(0)) + 'tail.exe -1000f "'+ log_file +'"'; WinExec(PAnsiChar(cmd),SW_SHOWNORMAL); //程序调用 tail.exe工具来查看日志 } unit log4me; interface uses classes, sysutils, ComObj, windows,IniFiles; procedure log4error(msg: AnsiString); //写ERROR级别的日志 procedure log4info(msg: AnsiString); //写INFO级别的日志 procedure log4debug(msg: AnsiString); //写DEBUG级别的日志 function log4filename():AnsiString; //得到当前日志文件全名 var log_filename: AnsiString; //日志文件全名 implementation var log_ThreadLock: TRTLCriticalSection; // 临界区 log_fileStream: TFileStream; log_filepath: AnsiString; //日志文件路径 log_initime:TDateTime; log_doerror, log_dodebug, log_doinfo: Boolean; procedure log_init(); var tmpStr:String; begin log_doerror := False; log_dodebug := False; log_doinfo := False; if FileExists(ExtractFilePath(ParamStr(0)) + 'log4me.ini') then begin with TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'log4me.ini') do try log_filepath := ExtractFilePath(ParamStr(0)) + '\' + ReadString('log4me','path','logs') + '\'; tmpStr := LowerCase(ReadString('log4me','level','info')); log_doerror := (tmpStr = 'debug') or (tmpStr = 'info') or (tmpStr = 'error'); log_doinfo := (tmpStr = 'debug') or (tmpStr = 'info'); log_dodebug := (tmpStr = 'debug') ; finally Free; end; end; log_initime := Now; end; procedure log4me_addLog(filename: AnsiString; p: PAnsiChar); var fmode :Word; tmp:AnsiString; begin //进入临界区,多线程时可以保护资源 EnterCriticalSection(log_ThreadLock); try try //如果要写的日志文件和打开的不同(在程序第一次运行和跨天的时候出现) //则关闭打开的日志文件。 if filename log_filename then begin log_filename := filename; if Assigned(log_fileStream) then begin log_fileStream.Free; log_fileStream := nil; end; end; //如果要写的日志文件没有打开(在程序第一次运行和跨天的时候出现) //则打开日志文件。 if not Assigned(log_fileStream) then begin if FileExists(log_filename) then fmode := fmOpenWrite or fmShareDenyNone else fmode := fmCreate or fmShareDenyNone ; log_fileStream := TFileStream.Create(log_filename,fmode); log_fileStream.Position := log_fileStream.Size; end; //在日志文件中写入日志 log_fileStream.Write(p^, strlen(p)); except on E:Exception do begin try tmp := ExtractFilePath(ParamStr(0)) + 'log4me_err.log'; if FileExists(tmp) then fmode := fmOpenWrite or fmShareDenyNone else fmode := fmCreate or fmShareDenyNone ; with TFileStream.Create(tmp, fmode) do begin Position := Size; tmp := FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now) + ' ' + E.Message + #13#10; Write(tmp[1],Length(tmp)); Free; end; except end; end; end; finally //无论如何,离开临界区 LeaveCriticalSection(log_ThreadLock); end; end; procedure log4write(msg: AnsiString); var strline: AnsiString; begin // 最多每秒重加载一次配置文件 if (Now() - log_initime) > (1/(24*60*60)) then log_init(); //日志开头加时间 strline := FormatDateTime('hh:nn:ss.zzz', Now) + ' ' + msg + #13#10; //写到当天的日志文件中 log4me_addLog(log_filepath + FormatDateTime('yyyy-mm-dd', Now) + '.log', PAnsiChar(strline)); end; //-----下面4个是对外方法------------------------- function log4filename():AnsiString; begin Result := log_filename; end; procedure log4error(msg: AnsiString); begin if log_doerror then log4write('[error]' + msg); end; procedure log4info(msg: AnsiString); begin if log_doinfo then log4write('[info ]' + msg); end; procedure log4debug(msg: AnsiString); begin if log_dodebug then log4write('[debug]' + msg); end; // ----------- 类初始化 -------------// initialization InitializeCriticalSection(log_ThreadLock); log_init; log4info('log4me:application starting....'); // ----------- 类销毁 -------------// finalization log4info('log4me:application stoping....'); DeleteCriticalSection(log_ThreadLock); if Assigned(log_fileStream) then log_fileStream.Free; end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值