读书人

delphi记录日志的有关问题创建当前l

发布时间: 2013-04-02 12:35:26 作者: rapoo

delphi记录日志的问题,创建当前log写入日志文件发生错误
我日志类的文件代码为:
---------------------------------------------------
unit Logger;
{----------------------------------------\-
日志类(TLogger)
日志级别约定:
0 - Info
1 - Debug
2 - Warn
3 - Error
\-----------------------------------------}
interface

uses
Windows,Classes,SysUtils;

const WRITE_LOG_DIR = 'log\'; //记录日志默认目录
WRITE_LOG_MIN_LEVEL = 0; //记录日志的最低级别,小于此级别只显示不记录
WRITE_LOG_ADD_TIME = True; //记录日志是否添加时间
WRITE_LOG_TIME_FORMAT = 'hh:nn:ss.zzz';//记录日志添加时间的格式

type
TLogger = class

private
FCSLock: TRTLCriticalSection; //临界区
FFileStream: TFileStream; //文件流
FLogDir: AnsiString; //日志目录
FLogName: AnsiString; //日志名称
public
procedure WriteLog(Log:AnsiString; const LogLevel:Integer = 0);
constructor Create(LogDir: AnsiString);
destructor Destroy; override;
end;

implementation

constructor TLogger.Create(LogDir: AnsiString);
begin
InitializeCriticalSection(FCSLock);
if Trim(LogDir) = '' then
FLogDir := ExtractFilePath(ParamStr(0)) + WRITE_LOG_DIR
else
FLogDir := LogDir;

if not DirectoryExists(FLogDir) then
if not ForceDirectories(FLogDir) then
begin
raise Exception.Create('日志路径错误,日志类对象不能被创建');
end;

end;

procedure TLogger.WriteLog(Log:AnsiString; const LogLevel:Integer = 0);
var
logName: AnsiString;
fMode: Word;
begin
EnterCriticalSection(FCSLock);
try
if LogLevel >= WRITE_LOG_MIN_LEVEL then
begin
logName := FormatDateTime('yyyymmdd',Now)+'.log';
if FLogName <> logName then FLogName := logName;
if FileExists(FLogDir+FLogName) then //如果当天的日志文件存在
fMode := fmOpenWrite or fmShareDenyNone
else
fMode := fmCreate or fmShareDenyNone;
if Assigned(FFileStream) then FreeAndNil(FFileStream);
FFileStream := TFileStream.Create(FLogDir+FLogName,fmode);


FFileStream.Position := FFileStream.Size; //追加到最后
case LogLevel of
0: Log := '[Info] ' + Log;
1: Log := '[Debug] ' + Log;
2: Log := '[Warn] ' + Log;
3: Log := '[Error] ' + Log;
end;
if WRITE_LOG_ADD_TIME then
Log := FormatDateTime(WRITE_LOG_TIME_FORMAT, Now) + ' '+ Log + #13#10;
FFileStream.Write(PAnsiChar(Log)^, StrLen(PAnsiChar(Log)));
end;
finally
LeaveCriticalSection(FCSLock);
end;

end;


destructor TLogger.Destroy;
begin
DeleteCriticalSection(FCSLock);
end;

end.


我记录日志时这样调用的:
logger := TLogger.Create('');
logger.WriteLog('日志信息内容',1);//参数1为日志级别
logger.FreeInstance;


这个是会在每天创建当天的日志文件,经常在第二天开始00:00:00创建新日志文件的时候报错,报错内容为:
delphi记录日志的有关问题,创建当前log写入日志文件发生异常

提示当天创建的日志文件正在被使用,进程无法访问 ,大家帮忙看看这个日志类问题在哪? 万分感谢!!! delphi 日志 异常 cannot?open
[解决办法]
创建的时候也进下临界区;


constructor TLogger.Create(LogDir: AnsiString);
begin
InitializeCriticalSection(FCSLock);
EnterCriticalSection(FCSLock);
try
if Trim(LogDir) = '' then
FLogDir := ExtractFilePath(ParamStr(0)) + WRITE_LOG_DIR
else
FLogDir := LogDir;

if not DirectoryExists(FLogDir) then
if not ForceDirectories(FLogDir) then
begin
raise Exception.Create('日志路径错误,日志类对象不能被创建');
end;
finally
LeaveCriticalSection(FCSLock);
end;
end;

[解决办法]
你是不是创建了多个logger???多个时会起这种冲突。
[解决办法]
引用:
我通过代码调试,慢慢往下执行没出错,但是不打断点快速往下执行就会出错,是因为速度太快导致前面什么操作还在执行吗? 大家帮忙看看

做个延时

先断点确定是那儿执行快了会出错, 然后在这之前加个sleep(0)或application.processMessage之类的
[解决办法]
引用:
引用:引用:我通过代码调试,慢慢往下执行没出错,但是不打断点快速往下执行就会出错,是因为速度太快导致前面什么操作还在执行吗? 大家帮忙看看


做个延时

先断点确定是那儿执行快了会出错, 然后在这之前加个sleep(0)或application.processMessage之类的

……


记录日志的类做成单例模式可以解决你的问题

读书人网 >.NET

热点推荐