设计一个日志系统
Designing a logging system
我有一个程序需要批量处理文件。我不需要在屏幕上的消息框中显示错误(这将暂停程序的执行),而是需要在用户可以在程序执行时看到的日志中显示这些错误消息。
所以我不需要像这样的程序执行日志Which logging library is better?
我现在正在使用从 TRichEdit 派生的东西。基本上,丰富的编辑和一些额外的方法,如 AddError(s)、AddWarn(s)、AddVerbose(s) 等
TRichLog = class(TMyRichEdit)
private
protected
Indent: Integer; { Indent new added lines x spaces }
public
constructor Create(AOwner: TComponent); override;
procedure AddBold (CONST Mesaj: string);
procedure AddMsg (CONST Mesaj: string);
procedure AddMsgLvl (CONST Mesaj: string; MsgType: Integer);
procedure AddColorMsg (CONST Mesaj: string; Culoare: TColor);
procedure AddVerb (CONST Mesaj: string);
procedure AddHint (CONST Mesaj: string);
procedure AddInfo (CONST Mesaj: string);
procedure AddPath (CONST Mesaj: string);
procedure AddWarn (CONST Mesaj: string);
procedure AddError (CONST Mesaj: string);
procedure AddMsgInt (CONST Mesaj: string; i: Integer); { Adds a message text followed by an integer }
procedure AddInteger (CONST i: Integer);
procedure AddFromFile (CONST FileName: string; MsgType: Integer); { Reads lines from the specified file and adds them to the log using the specified color. }
procedure AddEmptyRow;
procedure AddDateStamp;
procedure Append (RamLog: TObject); { RamLog will be typecased to TRamLog }
procedure SaveAsRtf (CONST FullPath: string);
procedure AppendToFile(CONST FullPath: string);
function VerbosityAsString: string;
published
property InsertTime: Boolean read FInsertTime write FInsertTime default FALSE;
property InsertDate: Boolean read FInsertDate write FInsertDate default FALSE;
property AutoScroll: Boolean read FAutoScroll write FAutoScroll default TRUE; { Automatically scroll to show the last line }
property Verbosity : Integer read FVerbosity write FVerbosity default vHints;
property OnLogError: TNotifyEvent read FLogError write FLogError; { Can be used to inform the application to automatically switch to log when an error is listed }
property OnLogWarn : TNotifyEvent read FLogWarn write FLogWarn;
但我想让用户动态过滤上下文。例如,用户应该能够隐藏所有详细消息并仅保留警告和错误。如果用户改变主意,则放回详细消息。
RichEdit 中的(现有)文本可以这样过滤吗?如果没有,我想得到一些关于如何重新实现它的指示。我正在考虑编写自己的格式来保留 lines/messages。例如:
Cannot open file,#msgErr,#Bold
我将有一个 TStringGrid 来仅显示有限数量的行(屏幕上可见的行)。这样我就可以拥有数百万行,而无需在屏幕上实际渲染所有行。浪费时间解析无关紧要,因为我只需要解析可见行。
要求:
- 支持 RichEdit 中的颜色(红色表示错误等)
- 轻量级
- 应该有两个 类:一个可视的(基于 TStringGrid)和一个非可视的控制台程序(记录到 RAM 并稍后保存日志或在控制台中将消息显示为简单文本) .
- 无硬依赖(Delphi 版本、Indy、数据库引擎、第 3 方控件等)
- 小(TRichEdit 大大增加了 EXE 文件的大小)
- 一个 PAS 文件
另一种方法是不使用网格并自己绘制文本(例如在 TPanel 派生的组件中)。或者也许这样的控件已经存在。
欢迎对我的想法提出任何建设性的批评。你有比使用网格更好的主意吗?
恕我直言,我们可能会有所不同:
- 针对开发人员和支持人员的低级日志记录;
- 针对最终用户的高级日志记录。
根据您的评论,听起来您是否需要第二种,通常也称为 "Audit Trail",尤其是在条款或法规方面。
我们通常通过将事件存储在数据库中来实现高级 "Audit Trail"。例如,本地高性能 SQLite3 数据库,或 MongoDB 集中式实例。
使用 RDBMS(或无SQL 数据库)有几个优点:
- 它的结构可以同时是固定的(例如通过定义类别)和进化的(通过一些文本字段,甚至一些与其他表的外键);
- 与您现有的 UI 交互很容易,例如使用强大的第三方网格,具有排序和过滤功能;
- 您可以使用 SQL 在日志内容中搜索,然后甚至为大多数有用的情况定义专用的 UI;
- 易于维护(DELETE FROM ... 会删除旧的未删除条目,并可能在数据库中保留错误)。
我们通常在生产中这样做,使用 our Open Source SOA framework: all service calls can be directly written in a SQlite3 or MongoDB instance, without any code to write! Then you could even search within the parameters using JSON queries. And you still have integrated low-level logging available。
我有一个程序需要批量处理文件。我不需要在屏幕上的消息框中显示错误(这将暂停程序的执行),而是需要在用户可以在程序执行时看到的日志中显示这些错误消息。
所以我不需要像这样的程序执行日志Which logging library is better?
我现在正在使用从 TRichEdit 派生的东西。基本上,丰富的编辑和一些额外的方法,如 AddError(s)、AddWarn(s)、AddVerbose(s) 等
TRichLog = class(TMyRichEdit)
private
protected
Indent: Integer; { Indent new added lines x spaces }
public
constructor Create(AOwner: TComponent); override;
procedure AddBold (CONST Mesaj: string);
procedure AddMsg (CONST Mesaj: string);
procedure AddMsgLvl (CONST Mesaj: string; MsgType: Integer);
procedure AddColorMsg (CONST Mesaj: string; Culoare: TColor);
procedure AddVerb (CONST Mesaj: string);
procedure AddHint (CONST Mesaj: string);
procedure AddInfo (CONST Mesaj: string);
procedure AddPath (CONST Mesaj: string);
procedure AddWarn (CONST Mesaj: string);
procedure AddError (CONST Mesaj: string);
procedure AddMsgInt (CONST Mesaj: string; i: Integer); { Adds a message text followed by an integer }
procedure AddInteger (CONST i: Integer);
procedure AddFromFile (CONST FileName: string; MsgType: Integer); { Reads lines from the specified file and adds them to the log using the specified color. }
procedure AddEmptyRow;
procedure AddDateStamp;
procedure Append (RamLog: TObject); { RamLog will be typecased to TRamLog }
procedure SaveAsRtf (CONST FullPath: string);
procedure AppendToFile(CONST FullPath: string);
function VerbosityAsString: string;
published
property InsertTime: Boolean read FInsertTime write FInsertTime default FALSE;
property InsertDate: Boolean read FInsertDate write FInsertDate default FALSE;
property AutoScroll: Boolean read FAutoScroll write FAutoScroll default TRUE; { Automatically scroll to show the last line }
property Verbosity : Integer read FVerbosity write FVerbosity default vHints;
property OnLogError: TNotifyEvent read FLogError write FLogError; { Can be used to inform the application to automatically switch to log when an error is listed }
property OnLogWarn : TNotifyEvent read FLogWarn write FLogWarn;
但我想让用户动态过滤上下文。例如,用户应该能够隐藏所有详细消息并仅保留警告和错误。如果用户改变主意,则放回详细消息。
RichEdit 中的(现有)文本可以这样过滤吗?如果没有,我想得到一些关于如何重新实现它的指示。我正在考虑编写自己的格式来保留 lines/messages。例如:
Cannot open file,#msgErr,#Bold
我将有一个 TStringGrid 来仅显示有限数量的行(屏幕上可见的行)。这样我就可以拥有数百万行,而无需在屏幕上实际渲染所有行。浪费时间解析无关紧要,因为我只需要解析可见行。
要求:
- 支持 RichEdit 中的颜色(红色表示错误等)
- 轻量级
- 应该有两个 类:一个可视的(基于 TStringGrid)和一个非可视的控制台程序(记录到 RAM 并稍后保存日志或在控制台中将消息显示为简单文本) .
- 无硬依赖(Delphi 版本、Indy、数据库引擎、第 3 方控件等)
- 小(TRichEdit 大大增加了 EXE 文件的大小)
- 一个 PAS 文件
另一种方法是不使用网格并自己绘制文本(例如在 TPanel 派生的组件中)。或者也许这样的控件已经存在。
欢迎对我的想法提出任何建设性的批评。你有比使用网格更好的主意吗?
恕我直言,我们可能会有所不同:
- 针对开发人员和支持人员的低级日志记录;
- 针对最终用户的高级日志记录。
根据您的评论,听起来您是否需要第二种,通常也称为 "Audit Trail",尤其是在条款或法规方面。
我们通常通过将事件存储在数据库中来实现高级 "Audit Trail"。例如,本地高性能 SQLite3 数据库,或 MongoDB 集中式实例。
使用 RDBMS(或无SQL 数据库)有几个优点:
- 它的结构可以同时是固定的(例如通过定义类别)和进化的(通过一些文本字段,甚至一些与其他表的外键);
- 与您现有的 UI 交互很容易,例如使用强大的第三方网格,具有排序和过滤功能;
- 您可以使用 SQL 在日志内容中搜索,然后甚至为大多数有用的情况定义专用的 UI;
- 易于维护(DELETE FROM ... 会删除旧的未删除条目,并可能在数据库中保留错误)。
我们通常在生产中这样做,使用 our Open Source SOA framework: all service calls can be directly written in a SQlite3 or MongoDB instance, without any code to write! Then you could even search within the parameters using JSON queries. And you still have integrated low-level logging available。