我的任务是创建一个类来收集围绕几个应用程序的用户活动。实现线程安全日志记录
比方说,我有一个类TLogging
和一个名为Logging
的全局对象。 (可能放入TLogging
的(字符串)列表中),并在一定的时间间隔(每10分钟)后保存到日志文件中,或者应用程序在应用程序中收集用户活动(屏幕打开等)关闭了。
最重要的是日志记录必须处于“静默模式”,它不得以任何方式影响用户工作流程:没有屏幕挂起,没有例外。
请给我这个任务的方向。
我的任务是创建一个类来收集围绕几个应用程序的用户活动。实现线程安全日志记录
比方说,我有一个类TLogging
和一个名为Logging
的全局对象。 (可能放入TLogging
的(字符串)列表中),并在一定的时间间隔(每10分钟)后保存到日志文件中,或者应用程序在应用程序中收集用户活动(屏幕打开等)关闭了。
最重要的是日志记录必须处于“静默模式”,它不得以任何方式影响用户工作流程:没有屏幕挂起,没有例外。
请给我这个任务的方向。
这是一个涉及多个领域的非常广泛的问题。一些提示:
至少考虑一个建立的日志框架。较新的Delphi版本附带CodeSite。 SmartInspect是另一种选择。
使用同步原语,使你的类是线程安全的:TCriticalSection,TMREWSync
确保您了解尝试写一个线程安全的日志框架之前参与了多线程和同步的问题。 Martin Harvey的指导Multithreading - The Delphi Way是一个好的开始。
使用后台线程将日志内容定期刷新到磁盘或缓冲了足够的数据。
如果遇到特定问题,可以在此处询问更具体的问题。
使用OmniThreadLibrary并假设记录对象是一个单身人士,这非常简单。我还会限制等待写入的最大消息数量,以便内部队列不能使用太多的内存。
const
CMaxMsgCount = 1000;
CMaxLogTimeout_ms = 10{min}*60{sec/min}*1000{ms/sec};
type
TLogging = class
strict private
FLogMsgCount: IOmniResourceCount;
FLogQueue: IOmniBlockingCollection;
FWriter: IOmniTaskControl;
strict protected
procedure Logger(const task: IOmniTask);
public
constructor Create;
destructor Destroy;
procedure Log(const msg: string);
end;
var
Logging: TLogging;
constructor TLogging.Create;
begin
FLogMsgCount := CreateResourceCount(CMaxMsgCount);
FLogQueue := TOmniBlockingCollection.Create;
FWriter := CreateTask(Logger, 'Logger').Run;
end;
destructor TLogging.Destroy;
begin
FWriter.Terminate;
end;
procedure TLogging.Log(const msg: string);
begin
FLogQueue.Add(msg);
FLogMsgCount.Allocate;
end;
procedure TLogging.Logger(const task: IOmniTask);
procedure Flush;
var
logData: TOmniValue;
begin
// open file, possibly with retry
while FLogQueue.TryTake(logData) do begin
FLogMsgCount.Release;
// write logData.AsString
end;
// close file
end;
begin
while DSiWaitForTwoObjects(task.TerminateEvent, FLogMsgCount.Handle, false, CMaxLogTimeout_ms) <> WAIT_OBJECT_0 do
Flush;
Flush;
end;
(声明:“它编译我的机器上”,否则未经考验的。)
你把所有这些功能(以及其他功能,例如异常跟踪,方法分析,线程安全或可选的每(我们的OpenSource TSynLog类)(http://blog.synopse.info/post/2011/04/14/Enhanced-logging-in-SynCommons)。对于德尔福5至XE2。包括日志查看器和基于集合的级别(不是一个全局级别,而是一组自定义级别)。 –
@Arnaud这不就是答案吗? – NGLN
另请参阅:[日志和同步](http://stackoverflow.com/questions/659094),[哪个日志库更好?](http://stackoverflow.com/questions/72983)和其他所有[Delphi日志](http://stackoverflow.com/search?q=%5Bdelphi%5D+logging)相关的问答。 – NGLN