Added: Category support (breaking change)
Fixed: graphic didn't show up in test Named Pipe client due to TJPEGImage not being referenced
This commit is contained in:
parent
ca47ad3f4e
commit
53220780db
@ -2,7 +2,9 @@ program X2LogNamedPipeClient;
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
// FastMM4,
|
// FastMM4,
|
||||||
|
System.Classes,
|
||||||
Vcl.Forms,
|
Vcl.Forms,
|
||||||
|
Vcl.Imaging.jpeg,
|
||||||
X2Log.Intf,
|
X2Log.Intf,
|
||||||
X2Log.Client.NamedPipe,
|
X2Log.Client.NamedPipe,
|
||||||
X2Log.Observer.MonitorForm;
|
X2Log.Observer.MonitorForm;
|
||||||
@ -13,6 +15,9 @@ var
|
|||||||
client: IX2LogObservable;
|
client: IX2LogObservable;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
{ To deserialize the graphic, make sure GetClass succeeds }
|
||||||
|
RegisterClass(TJPEGImage);
|
||||||
|
|
||||||
ReportMemoryLeaksOnShutdown := True;
|
ReportMemoryLeaksOnShutdown := True;
|
||||||
|
|
||||||
Application.Initialize;
|
Application.Initialize;
|
||||||
|
@ -228,8 +228,6 @@ object MainForm: TMainForm
|
|||||||
Caption = 'Monitor Form Observer'
|
Caption = 'Monitor Form Observer'
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
OnClick = btnMonitorFormClick
|
OnClick = btnMonitorFormClick
|
||||||
ExplicitLeft = 151
|
|
||||||
ExplicitTop = -6
|
|
||||||
end
|
end
|
||||||
object btnLock: TButton
|
object btnLock: TButton
|
||||||
AlignWithMargins = True
|
AlignWithMargins = True
|
||||||
@ -246,7 +244,6 @@ object MainForm: TMainForm
|
|||||||
Caption = 'Lock'
|
Caption = 'Lock'
|
||||||
TabOrder = 2
|
TabOrder = 2
|
||||||
OnClick = btnLockClick
|
OnClick = btnLockClick
|
||||||
ExplicitLeft = 149
|
|
||||||
end
|
end
|
||||||
object btnUnlock: TButton
|
object btnUnlock: TButton
|
||||||
AlignWithMargins = True
|
AlignWithMargins = True
|
||||||
@ -263,7 +260,6 @@ object MainForm: TMainForm
|
|||||||
Caption = 'Unlock'
|
Caption = 'Unlock'
|
||||||
TabOrder = 3
|
TabOrder = 3
|
||||||
OnClick = btnUnlockClick
|
OnClick = btnUnlockClick
|
||||||
ExplicitLeft = 359
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
object pcDispatch: TPageControl
|
object pcDispatch: TPageControl
|
||||||
@ -337,6 +333,15 @@ object MainForm: TMainForm
|
|||||||
Text = 'Hello world!'
|
Text = 'Hello world!'
|
||||||
OnKeyDown = edtMessageKeyDown
|
OnKeyDown = edtMessageKeyDown
|
||||||
end
|
end
|
||||||
|
object btnCategory: TButton
|
||||||
|
Left = 416
|
||||||
|
Top = 39
|
||||||
|
Width = 101
|
||||||
|
Height = 21
|
||||||
|
Caption = 'With category'
|
||||||
|
TabOrder = 5
|
||||||
|
OnClick = btnCategoryClick
|
||||||
|
end
|
||||||
end
|
end
|
||||||
object tsException: TTabSheet
|
object tsException: TTabSheet
|
||||||
Caption = 'Exception'
|
Caption = 'Exception'
|
||||||
@ -458,7 +463,7 @@ object MainForm: TMainForm
|
|||||||
Left = 552
|
Left = 552
|
||||||
Top = 176
|
Top = 176
|
||||||
Bitmap = {
|
Bitmap = {
|
||||||
494C01010200140048000C000C00FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
|
494C01010200140050000C000C00FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
|
||||||
0000000000003600000028000000300000000C00000001002000000000000009
|
0000000000003600000028000000300000000C00000001002000000000000009
|
||||||
0000000000000000000000000000000000000000000000000000000000000000
|
0000000000000000000000000000000000000000000000000000000000000000
|
||||||
0000000000000000000000000000000000000000000000000000000000000000
|
0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
@ -61,6 +61,7 @@ type
|
|||||||
lbNamedPipeServers: TListBox;
|
lbNamedPipeServers: TListBox;
|
||||||
btnLock: TButton;
|
btnLock: TButton;
|
||||||
btnUnlock: TButton;
|
btnUnlock: TButton;
|
||||||
|
btnCategory: TButton;
|
||||||
|
|
||||||
procedure FormCreate(Sender: TObject);
|
procedure FormCreate(Sender: TObject);
|
||||||
procedure FormDestroy(Sender: TObject);
|
procedure FormDestroy(Sender: TObject);
|
||||||
@ -81,13 +82,14 @@ type
|
|||||||
procedure btnBinaryRawByteStringClick(Sender: TObject);
|
procedure btnBinaryRawByteStringClick(Sender: TObject);
|
||||||
procedure btnGraphicClick(Sender: TObject);
|
procedure btnGraphicClick(Sender: TObject);
|
||||||
procedure btnNamedPipeRefreshClick(Sender: TObject);
|
procedure btnNamedPipeRefreshClick(Sender: TObject);
|
||||||
|
procedure btnCategoryClick(Sender: TObject);
|
||||||
private
|
private
|
||||||
FLog: IX2Log;
|
FLog: IX2Log;
|
||||||
FEventObserver: IX2LogObserver;
|
FEventObserver: IX2LogObserver;
|
||||||
FFileObserver: IX2LogObserver;
|
FFileObserver: IX2LogObserver;
|
||||||
FNamedPipeObserver: IX2LogObserver;
|
FNamedPipeObserver: IX2LogObserver;
|
||||||
protected
|
protected
|
||||||
procedure DoLog(Sender: TObject; Level: TX2LogLevel; DateTime: TDateTime; const Msg: string; Details: IX2LogDetails);
|
procedure DoLog(Sender: TObject; Level: TX2LogLevel; DateTime: TDateTime; const Msg, Category: string; Details: IX2LogDetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -149,13 +151,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.DoLog(Sender: TObject; Level: TX2LogLevel; DateTime: TDateTime; const Msg: string; Details: IX2LogDetails);
|
procedure TMainForm.DoLog(Sender: TObject; Level: TX2LogLevel; DateTime: TDateTime; const Msg, Category: string; Details: IX2LogDetails);
|
||||||
var
|
var
|
||||||
text: string;
|
text: string;
|
||||||
logDetailsText: IX2LogDetailsText;
|
logDetailsText: IX2LogDetailsText;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
text := GetLogLevelText(Level) + ': ' + Msg;
|
text := GetLogLevelText(Level) + ': ' + Category + ': ' + Msg;
|
||||||
|
|
||||||
if Supports(Details, IX2LogDetailsText, logDetailsText) then
|
if Supports(Details, IX2LogDetailsText, logDetailsText) then
|
||||||
text := text + ' (' + logDetailsText.AsString + ')';
|
text := text + ' (' + logDetailsText.AsString + ')';
|
||||||
@ -183,6 +185,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.btnCloseClick(Sender: TObject);
|
procedure TMainForm.btnCloseClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
Close;
|
Close;
|
||||||
@ -243,6 +246,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMainForm.btnCategoryClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FLog.Category('Test').Info(edtMessage.Text);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.btnMonitorFormClick(Sender: TObject);
|
procedure TMainForm.btnMonitorFormClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
TX2LogObserverMonitorForm.ShowInstance(FLog);
|
TX2LogObserverMonitorForm.ShowInstance(FLog);
|
||||||
|
@ -19,8 +19,8 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
{ IX2LogBase }
|
{ IX2LogBase }
|
||||||
procedure Log(ALevel: TX2LogLevel; const AMessage: string; ADetails: IX2LogDetails = nil); overload; virtual;
|
procedure Log(ALevel: TX2LogLevel; const AMessage: string; const ACategory: string = ''; ADetails: IX2LogDetails = nil); overload; virtual;
|
||||||
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails = nil); overload; virtual;
|
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; const ACategory: string = ''; ADetails: IX2LogDetails = nil); overload; virtual;
|
||||||
|
|
||||||
{ IX2LogObservable }
|
{ IX2LogObservable }
|
||||||
procedure Attach(AObserver: IX2LogObserver);
|
procedure Attach(AObserver: IX2LogObserver);
|
||||||
@ -64,23 +64,23 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2LogBaseClient.Log(ALevel: TX2LogLevel; const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2LogBaseClient.Log(ALevel: TX2LogLevel; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
var
|
var
|
||||||
observer: IX2LogObserver;
|
observer: IX2LogObserver;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
for observer in Observers do
|
for observer in Observers do
|
||||||
observer.Log(ALevel, AMessage, ADetails);
|
observer.Log(ALevel, AMessage, ACategory, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2LogBaseClient.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2LogBaseClient.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
var
|
var
|
||||||
observer: IX2LogObserver;
|
observer: IX2LogObserver;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
for observer in Observers do
|
for observer in Observers do
|
||||||
observer.Log(ALevel, ADateTime, AMessage, ADetails);
|
observer.Log(ALevel, ADateTime, AMessage, ACategory, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -345,6 +345,7 @@ var
|
|||||||
detailsSize: Cardinal;
|
detailsSize: Cardinal;
|
||||||
detailsStream: TMemoryStream;
|
detailsStream: TMemoryStream;
|
||||||
serializer: IX2LogDetailsSerializer;
|
serializer: IX2LogDetailsSerializer;
|
||||||
|
category: string;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if MessageData.Size > 0 then
|
if MessageData.Size > 0 then
|
||||||
@ -365,6 +366,9 @@ begin
|
|||||||
end else if headerDiff < 0 then
|
end else if headerDiff < 0 then
|
||||||
raise EReadError.Create('Header too small');
|
raise EReadError.Create('Header too small');
|
||||||
|
|
||||||
|
{ Category }
|
||||||
|
category := TStreamUtil.ReadString(MessageData);
|
||||||
|
|
||||||
{ Message }
|
{ Message }
|
||||||
msg := TStreamUtil.ReadString(MessageData);
|
msg := TStreamUtil.ReadString(MessageData);
|
||||||
|
|
||||||
@ -393,7 +397,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Client.Log(header.Level, header.DateTime, msg, details);
|
Client.Log(header.Level, header.DateTime, msg, category, details);
|
||||||
except
|
except
|
||||||
on E:EReadError do
|
on E:EReadError do
|
||||||
ClosePipe;
|
ClosePipe;
|
||||||
|
@ -11,6 +11,11 @@ resourcestring
|
|||||||
LogLevelWarning = 'Warning';
|
LogLevelWarning = 'Warning';
|
||||||
LogLevelError = 'Error';
|
LogLevelError = 'Error';
|
||||||
|
|
||||||
|
LogCategorySeparator = ' - ';
|
||||||
|
|
||||||
|
// Note: currently not translatable
|
||||||
|
LogCategoryDefault = '';
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
X2Log.Observer.LogFile
|
X2Log.Observer.LogFile
|
||||||
@ -36,6 +41,7 @@ resourcestring
|
|||||||
|
|
||||||
{ Caption of the columns in the live log view }
|
{ Caption of the columns in the live log view }
|
||||||
LogMonitorFormColumnTime = 'Time';
|
LogMonitorFormColumnTime = 'Time';
|
||||||
|
LogMonitorFormColumnCategory = 'Category';
|
||||||
LogMonitorFormColumnMessage = 'Message';
|
LogMonitorFormColumnMessage = 'Message';
|
||||||
|
|
||||||
{ Caption of the toolbar buttons }
|
{ Caption of the toolbar buttons }
|
||||||
|
@ -24,8 +24,10 @@ type
|
|||||||
class procedure SetExceptionStrategy(AStrategy: IX2LogExceptionStrategy);
|
class procedure SetExceptionStrategy(AStrategy: IX2LogExceptionStrategy);
|
||||||
|
|
||||||
{ Facade for IX2LogBase }
|
{ Facade for IX2LogBase }
|
||||||
class procedure Log(ALevel: TX2LogLevel; const AMessage: string; ADetails: IX2LogDetails); overload;
|
class procedure Log(ALevel: TX2LogLevel; const AMessage: string; const ACategory: string = ''; ADetails: IX2LogDetails = nil); overload;
|
||||||
class procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails); overload;
|
class procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; const ACategory: string = ''; ADetails: IX2LogDetails = nil); overload;
|
||||||
|
|
||||||
|
class function Category(const ACategory: string): IX2Log;
|
||||||
|
|
||||||
class procedure Verbose(const AMessage: string; const ADetails: string = '');
|
class procedure Verbose(const AMessage: string; const ADetails: string = '');
|
||||||
class procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
class procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||||
@ -82,15 +84,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
class procedure TX2GlobalLog.Log(ALevel: TX2LogLevel; const AMessage: string; ADetails: IX2LogDetails);
|
class function TX2GlobalLog.Category(const ACategory: string): IX2Log;
|
||||||
begin
|
begin
|
||||||
Instance.Log(ALevel, AMessage, ADetails);
|
Result := Instance.Category(ACategory);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
class procedure TX2GlobalLog.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
class procedure TX2GlobalLog.Log(ALevel: TX2LogLevel; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
Instance.Log(ALevel, ADateTime, AMessage, ADetails);
|
Instance.Log(ALevel, AMessage, ACategory, ADetails);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class procedure TX2GlobalLog.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
|
begin
|
||||||
|
Instance.Log(ALevel, ADateTime, AMessage, ACategory, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,8 +48,8 @@ type
|
|||||||
{ Logging }
|
{ Logging }
|
||||||
IX2LogBase = interface
|
IX2LogBase = interface
|
||||||
['{1949E8DC-6DC5-43DC-B678-55CF8274E79D}']
|
['{1949E8DC-6DC5-43DC-B678-55CF8274E79D}']
|
||||||
procedure Log(ALevel: TX2LogLevel; const AMessage: string; ADetails: IX2LogDetails = nil); overload;
|
procedure Log(ALevel: TX2LogLevel; const AMessage: string; const ACategory: string = ''; ADetails: IX2LogDetails = nil); overload;
|
||||||
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails = nil); overload;
|
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; const ACategory: string = ''; ADetails: IX2LogDetails = nil); overload;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -75,6 +75,8 @@ type
|
|||||||
['{A6FF38F9-EDA8-4C76-9C95-2C0317560D78}']
|
['{A6FF38F9-EDA8-4C76-9C95-2C0317560D78}']
|
||||||
procedure SetExceptionStrategy(AStrategy: IX2LogExceptionStrategy);
|
procedure SetExceptionStrategy(AStrategy: IX2LogExceptionStrategy);
|
||||||
|
|
||||||
|
function Category(const ACategory: string): IX2Log;
|
||||||
|
|
||||||
procedure Verbose(const AMessage: string; const ADetails: string = '');
|
procedure Verbose(const AMessage: string; const ADetails: string = '');
|
||||||
procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||||
|
|
||||||
@ -102,6 +104,8 @@ type
|
|||||||
{
|
{
|
||||||
Payload:
|
Payload:
|
||||||
|
|
||||||
|
CategoryLength: Cardinal
|
||||||
|
Category: WideString
|
||||||
MessageLength: Cardinal
|
MessageLength: Cardinal
|
||||||
Message: WideString
|
Message: WideString
|
||||||
DetailsLength: Cardinal
|
DetailsLength: Cardinal
|
||||||
@ -109,6 +113,7 @@ type
|
|||||||
}
|
}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
TX2LogMessageHeader = TX2LogMessageHeaderV1;
|
TX2LogMessageHeader = TX2LogMessageHeaderV1;
|
||||||
|
|
||||||
const
|
const
|
||||||
|
@ -15,15 +15,15 @@ type
|
|||||||
private
|
private
|
||||||
FLogLevels: TX2LogLevels;
|
FLogLevels: TX2LogLevels;
|
||||||
protected
|
protected
|
||||||
procedure DoLog(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails); virtual; abstract;
|
procedure DoLog(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails); virtual; abstract;
|
||||||
|
|
||||||
property LogLevels: TX2LogLevels read FLogLevels;
|
property LogLevels: TX2LogLevels read FLogLevels;
|
||||||
public
|
public
|
||||||
constructor Create(ALogLevels: TX2LogLevels = X2LogLevelsDefault);
|
constructor Create(ALogLevels: TX2LogLevels = X2LogLevelsDefault);
|
||||||
|
|
||||||
{ IX2LogBase }
|
{ IX2LogBase }
|
||||||
procedure Log(ALevel: TX2LogLevel; const AMessage: string; ADetails: IX2LogDetails = nil); overload;
|
procedure Log(ALevel: TX2LogLevel; const AMessage: string; const ACategory: string = ''; ADetails: IX2LogDetails = nil); overload;
|
||||||
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails = nil); overload;
|
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; const ACategory: string = ''; ADetails: IX2LogDetails = nil); overload;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -39,16 +39,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2LogCustomObserver.Log(ALevel: TX2LogLevel; const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2LogCustomObserver.Log(ALevel: TX2LogLevel; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
Log(ALevel, Now, AMessage, ADetails);
|
Log(ALevel, Now, AMessage, ACategory, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2LogCustomObserver.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2LogCustomObserver.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
if ALevel in LogLevels then
|
if ALevel in LogLevels then
|
||||||
DoLog(ALevel, ADateTime, AMessage, ADetails);
|
DoLog(ALevel, ADateTime, AMessage, ACategory, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -20,7 +20,7 @@ type
|
|||||||
protected
|
protected
|
||||||
function CreateWorkerThread: TX2LogObserverWorkerThread; virtual; abstract;
|
function CreateWorkerThread: TX2LogObserverWorkerThread; virtual; abstract;
|
||||||
|
|
||||||
procedure DoLog(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails); override;
|
procedure DoLog(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails); override;
|
||||||
|
|
||||||
property WorkerThread: TX2LogObserverWorkerThread read FWorkerThread;
|
property WorkerThread: TX2LogObserverWorkerThread read FWorkerThread;
|
||||||
public
|
public
|
||||||
@ -34,9 +34,10 @@ type
|
|||||||
FDetails: IX2LogDetails;
|
FDetails: IX2LogDetails;
|
||||||
FLevel: TX2LogLevel;
|
FLevel: TX2LogLevel;
|
||||||
FDateTime: TDateTime;
|
FDateTime: TDateTime;
|
||||||
|
FCategory: string;
|
||||||
FMessage: string;
|
FMessage: string;
|
||||||
public
|
public
|
||||||
constructor Create(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails); overload;
|
constructor Create(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails); overload;
|
||||||
constructor Create(AEntry: TX2LogQueueEntry); overload;
|
constructor Create(AEntry: TX2LogQueueEntry); overload;
|
||||||
|
|
||||||
procedure Assign(Source: TPersistent); override;
|
procedure Assign(Source: TPersistent); override;
|
||||||
@ -44,6 +45,7 @@ type
|
|||||||
property DateTime: TDateTime read FDateTime;
|
property DateTime: TDateTime read FDateTime;
|
||||||
property Details: IX2LogDetails read FDetails;
|
property Details: IX2LogDetails read FDetails;
|
||||||
property Level: TX2LogLevel read FLevel;
|
property Level: TX2LogLevel read FLevel;
|
||||||
|
property Category: string read FCategory;
|
||||||
property Message: string read FMessage;
|
property Message: string read FMessage;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -71,7 +73,7 @@ type
|
|||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -97,20 +99,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2LogCustomThreadedObserver.DoLog(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2LogCustomThreadedObserver.DoLog(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
WorkerThread.Log(ALevel, ADateTime, AMessage, ADetails);
|
WorkerThread.Log(ALevel, ADateTime, AMessage, ACategory, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ TX2LogQueueEntry }
|
{ TX2LogQueueEntry }
|
||||||
constructor TX2LogQueueEntry.Create(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
constructor TX2LogQueueEntry.Create(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
|
|
||||||
FLevel := ALevel;
|
FLevel := ALevel;
|
||||||
FDateTime := ADateTime;
|
FDateTime := ADateTime;
|
||||||
|
FCategory := ACategory;
|
||||||
FMessage := AMessage;
|
FMessage := AMessage;
|
||||||
FDetails := ADetails;
|
FDetails := ADetails;
|
||||||
end;
|
end;
|
||||||
@ -135,6 +138,7 @@ begin
|
|||||||
|
|
||||||
FLevel := entrySource.Level;
|
FLevel := entrySource.Level;
|
||||||
FDateTime := entrySource.DateTime;
|
FDateTime := entrySource.DateTime;
|
||||||
|
FCategory := entrySource.Category;
|
||||||
FMessage := entrySource.Message;
|
FMessage := entrySource.Message;
|
||||||
FDetails := entrySource.Details;
|
FDetails := entrySource.Details;
|
||||||
end else
|
end else
|
||||||
@ -168,11 +172,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2LogObserverWorkerThread.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2LogObserverWorkerThread.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
TMonitor.Enter(LogQueue);
|
TMonitor.Enter(LogQueue);
|
||||||
try
|
try
|
||||||
LogQueue.Enqueue(TX2LogQueueEntry.Create(ALevel, ADateTime, AMessage, ADetails));
|
LogQueue.Enqueue(TX2LogQueueEntry.Create(ALevel, ADateTime, AMessage, ACategory, ADetails));
|
||||||
finally
|
finally
|
||||||
TMonitor.Exit(LogQueue);
|
TMonitor.Exit(LogQueue);
|
||||||
end;
|
end;
|
||||||
|
@ -7,7 +7,7 @@ uses
|
|||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TX2LogEvent = procedure(Sender: TObject; Level: TX2LogLevel; DateTime: TDateTime; const Msg: string; Details: IX2LogDetails) of object;
|
TX2LogEvent = procedure(Sender: TObject; Level: TX2LogLevel; DateTime: TDateTime; const Msg, Category: string; Details: IX2LogDetails) of object;
|
||||||
|
|
||||||
|
|
||||||
TX2LogEventObserver = class(TX2LogCustomObserver)
|
TX2LogEventObserver = class(TX2LogCustomObserver)
|
||||||
@ -15,7 +15,7 @@ type
|
|||||||
FOnLog: TX2LogEvent;
|
FOnLog: TX2LogEvent;
|
||||||
FRunInMainThread: Boolean;
|
FRunInMainThread: Boolean;
|
||||||
protected
|
protected
|
||||||
procedure DoLog(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails); override;
|
procedure DoLog(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails); override;
|
||||||
public
|
public
|
||||||
constructor Create(ALogLevels: TX2LogLevels = X2LogLevelsDefault); overload;
|
constructor Create(ALogLevels: TX2LogLevels = X2LogLevelsDefault); overload;
|
||||||
constructor Create(AOnLog: TX2LogEvent; ALogLevels: TX2LogLevels = X2LogLevelsDefault); overload;
|
constructor Create(AOnLog: TX2LogEvent; ALogLevels: TX2LogLevels = X2LogLevelsDefault); overload;
|
||||||
@ -48,7 +48,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2LogEventObserver.DoLog(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2LogEventObserver.DoLog(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
if Assigned(FOnLog) then
|
if Assigned(FOnLog) then
|
||||||
begin
|
begin
|
||||||
@ -58,10 +58,10 @@ begin
|
|||||||
procedure
|
procedure
|
||||||
begin
|
begin
|
||||||
if Assigned(FOnLog) then
|
if Assigned(FOnLog) then
|
||||||
FOnLog(Self, ALevel, ADateTime, AMessage, ADetails);
|
FOnLog(Self, ALevel, ADateTime, AMessage, ACategory, ADetails);
|
||||||
end);
|
end);
|
||||||
end else
|
end else
|
||||||
FOnLog(Self, ALevel, ADateTime, AMessage, ADetails);
|
FOnLog(Self, ALevel, ADateTime, AMessage, ACategory, ADetails);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
PixelsPerInch = 96
|
PixelsPerInch = 96
|
||||||
TextHeight = 13
|
TextHeight = 13
|
||||||
object splDetails: TSplitter
|
object splDetails: TSplitter
|
||||||
Left = 602
|
Left = 682
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 6
|
Width = 6
|
||||||
Height = 496
|
Height = 496
|
||||||
@ -29,9 +29,9 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
ExplicitHeight = 519
|
ExplicitHeight = 519
|
||||||
end
|
end
|
||||||
object pnlDetails: TPanel
|
object pnlDetails: TPanel
|
||||||
Left = 608
|
Left = 688
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 382
|
Width = 302
|
||||||
Height = 496
|
Height = 496
|
||||||
Align = alRight
|
Align = alRight
|
||||||
BevelOuter = bvNone
|
BevelOuter = bvNone
|
||||||
@ -39,7 +39,7 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
object tbDetails: TToolBar
|
object tbDetails: TToolBar
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 382
|
Width = 302
|
||||||
Height = 22
|
Height = 22
|
||||||
AutoSize = True
|
AutoSize = True
|
||||||
ButtonWidth = 80
|
ButtonWidth = 80
|
||||||
@ -76,7 +76,7 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
object pnlBorder: TPanel
|
object pnlBorder: TPanel
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 22
|
Top = 22
|
||||||
Width = 382
|
Width = 302
|
||||||
Height = 474
|
Height = 474
|
||||||
Align = alClient
|
Align = alClient
|
||||||
BevelKind = bkFlat
|
BevelKind = bkFlat
|
||||||
@ -85,21 +85,21 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
object hcDetails: THeaderControl
|
object hcDetails: THeaderControl
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 378
|
Width = 298
|
||||||
Height = 19
|
Height = 19
|
||||||
Sections = <
|
Sections = <
|
||||||
item
|
item
|
||||||
AutoSize = True
|
AutoSize = True
|
||||||
ImageIndex = -1
|
ImageIndex = -1
|
||||||
Text = 'Details'
|
Text = 'Details'
|
||||||
Width = 378
|
Width = 298
|
||||||
end>
|
end>
|
||||||
NoSizing = True
|
NoSizing = True
|
||||||
end
|
end
|
||||||
object reDetails: TRichEdit
|
object reDetails: TRichEdit
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 19
|
Top = 19
|
||||||
Width = 378
|
Width = 298
|
||||||
Height = 451
|
Height = 451
|
||||||
Align = alClient
|
Align = alClient
|
||||||
BorderStyle = bsNone
|
BorderStyle = bsNone
|
||||||
@ -118,7 +118,7 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
object sbDetailsImage: TScrollBox
|
object sbDetailsImage: TScrollBox
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 19
|
Top = 19
|
||||||
Width = 378
|
Width = 298
|
||||||
Height = 451
|
Height = 451
|
||||||
HorzScrollBar.Tracking = True
|
HorzScrollBar.Tracking = True
|
||||||
VertScrollBar.Tracking = True
|
VertScrollBar.Tracking = True
|
||||||
@ -141,7 +141,7 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
object pnlLog: TPanel
|
object pnlLog: TPanel
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 602
|
Width = 682
|
||||||
Height = 496
|
Height = 496
|
||||||
Align = alClient
|
Align = alClient
|
||||||
BevelOuter = bvNone
|
BevelOuter = bvNone
|
||||||
@ -149,10 +149,10 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
object vstLog: TVirtualStringTree
|
object vstLog: TVirtualStringTree
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 22
|
Top = 22
|
||||||
Width = 602
|
Width = 682
|
||||||
Height = 474
|
Height = 474
|
||||||
Align = alClient
|
Align = alClient
|
||||||
Header.AutoSizeIndex = 2
|
Header.AutoSizeIndex = 3
|
||||||
Header.Font.Charset = DEFAULT_CHARSET
|
Header.Font.Charset = DEFAULT_CHARSET
|
||||||
Header.Font.Color = clWindowText
|
Header.Font.Color = clWindowText
|
||||||
Header.Font.Height = -11
|
Header.Font.Height = -11
|
||||||
@ -182,14 +182,19 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
end
|
end
|
||||||
item
|
item
|
||||||
Position = 2
|
Position = 2
|
||||||
Width = 428
|
Width = 150
|
||||||
|
WideText = 'Category'
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Position = 3
|
||||||
|
Width = 354
|
||||||
WideText = 'Message'
|
WideText = 'Message'
|
||||||
end>
|
end>
|
||||||
end
|
end
|
||||||
object tbLog: TToolBar
|
object tbLog: TToolBar
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 602
|
Width = 682
|
||||||
Height = 22
|
Height = 22
|
||||||
AutoSize = True
|
AutoSize = True
|
||||||
ButtonWidth = 67
|
ButtonWidth = 67
|
||||||
@ -216,7 +221,7 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
Left = 116
|
Left = 116
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 46
|
Width = 46
|
||||||
Height = 13
|
Height = 22
|
||||||
Caption = ' Filter: '
|
Caption = ' Filter: '
|
||||||
Layout = tlCenter
|
Layout = tlCenter
|
||||||
end
|
end
|
||||||
@ -267,7 +272,7 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
Left = 448
|
Left = 448
|
||||||
Top = 48
|
Top = 48
|
||||||
Bitmap = {
|
Bitmap = {
|
||||||
494C01010A004000EC0010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
|
494C01010A004000F40010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
|
||||||
0000000000003600000028000000400000003000000001002000000000000030
|
0000000000003600000028000000400000003000000001002000000000000030
|
||||||
0000000000000000000000000000000000000000000000000000000000000000
|
0000000000000000000000000000000000000000000000000000000000000000
|
||||||
0000000000000000000000000000000000000000000000000000000000000000
|
0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
@ -183,8 +183,8 @@ type
|
|||||||
procedure Unlock;
|
procedure Unlock;
|
||||||
|
|
||||||
{ IX2LogObserver }
|
{ IX2LogObserver }
|
||||||
procedure Log(ALevel: TX2LogLevel; const AMessage: string; ADetails: IX2LogDetails); overload;
|
procedure Log(ALevel: TX2LogLevel; const AMessage, ACategory: string; ADetails: IX2LogDetails); overload;
|
||||||
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails); overload;
|
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails); overload;
|
||||||
|
|
||||||
property FreeOnClose: Boolean read FFreeOnClose write FFreeOnClose;
|
property FreeOnClose: Boolean read FFreeOnClose write FFreeOnClose;
|
||||||
property MaxEntries: Cardinal read FMaxEntries write FMaxEntries;
|
property MaxEntries: Cardinal read FMaxEntries write FMaxEntries;
|
||||||
@ -212,10 +212,11 @@ type
|
|||||||
Time: TDateTime;
|
Time: TDateTime;
|
||||||
Paused: Boolean;
|
Paused: Boolean;
|
||||||
Level: TX2LogLevel;
|
Level: TX2LogLevel;
|
||||||
|
Category: string;
|
||||||
Message: string;
|
Message: string;
|
||||||
Details: IX2LogDetails;
|
Details: IX2LogDetails;
|
||||||
|
|
||||||
procedure Initialize(APaused: Boolean; ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
procedure Initialize(APaused: Boolean; ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
PLogEntryNodeData = ^TLogEntryNodeData;
|
PLogEntryNodeData = ^TLogEntryNodeData;
|
||||||
@ -224,17 +225,19 @@ type
|
|||||||
const
|
const
|
||||||
ColumnLevel = 0;
|
ColumnLevel = 0;
|
||||||
ColumnTime = 1;
|
ColumnTime = 1;
|
||||||
ColumnMessage = 2;
|
ColumnCategory = 2;
|
||||||
|
ColumnMessage = 3;
|
||||||
|
|
||||||
LevelImageIndex: array[TX2LogLevel] of TImageIndex = (0, 1, 2, 3);
|
LevelImageIndex: array[TX2LogLevel] of TImageIndex = (0, 1, 2, 3);
|
||||||
|
|
||||||
|
|
||||||
{ TLogEntryNode }
|
{ TLogEntryNode }
|
||||||
procedure TLogEntryNodeData.Initialize(APaused: Boolean; ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
procedure TLogEntryNodeData.Initialize(APaused: Boolean; ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
Self.Time := ADateTime;
|
Self.Time := ADateTime;
|
||||||
Self.Paused := APaused;
|
Self.Paused := APaused;
|
||||||
Self.Level := ALevel;
|
Self.Level := ALevel;
|
||||||
|
Self.Category := ACategory;
|
||||||
Self.Message := AMessage;
|
Self.Message := AMessage;
|
||||||
Self.Details := ADetails;
|
Self.Details := ADetails;
|
||||||
end;
|
end;
|
||||||
@ -345,6 +348,7 @@ begin
|
|||||||
|
|
||||||
vstLog.NodeDataSize := SizeOf(TLogEntryNodeData);
|
vstLog.NodeDataSize := SizeOf(TLogEntryNodeData);
|
||||||
vstLog.Header.Columns[ColumnTime].Text := GetLogResourceString(@LogMonitorFormColumnTime);
|
vstLog.Header.Columns[ColumnTime].Text := GetLogResourceString(@LogMonitorFormColumnTime);
|
||||||
|
vstLog.Header.Columns[ColumnCategory].Text := GetLogResourceString(@LogMonitorFormColumnCategory);
|
||||||
vstLog.Header.Columns[ColumnMessage].Text := GetLogResourceString(@LogMonitorFormColumnMessage);
|
vstLog.Header.Columns[ColumnMessage].Text := GetLogResourceString(@LogMonitorFormColumnMessage);
|
||||||
|
|
||||||
mmMainFile.Caption := GetLogResourceString(@LogMonitorFormMenuFile);
|
mmMainFile.Caption := GetLogResourceString(@LogMonitorFormMenuFile);
|
||||||
@ -456,13 +460,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2LogObserverMonitorForm.Log(ALevel: TX2LogLevel; const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2LogObserverMonitorForm.Log(ALevel: TX2LogLevel; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
Log(ALevel, Now, AMessage, ADetails);
|
Log(ALevel, Now, AMessage, ACategory, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2LogObserverMonitorForm.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2LogObserverMonitorForm.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
var
|
var
|
||||||
node: PVirtualNode;
|
node: PVirtualNode;
|
||||||
nodeData: PLogEntryNodeData;
|
nodeData: PLogEntryNodeData;
|
||||||
@ -486,7 +490,7 @@ begin
|
|||||||
{ BeginUpdate causes OnInitNode to be triggered on-demand,
|
{ BeginUpdate causes OnInitNode to be triggered on-demand,
|
||||||
moved Initialize call here }
|
moved Initialize call here }
|
||||||
Initialize(nodeData^);
|
Initialize(nodeData^);
|
||||||
nodeData^.Initialize(Paused, ALevel, ADateTime, AMessage, ADetails);
|
nodeData^.Initialize(Paused, ALevel, ADateTime, AMessage, ACategory, ADetails);
|
||||||
|
|
||||||
vstLog.IsVisible[node] := (not Paused) and (ALevel in VisibleLevels);
|
vstLog.IsVisible[node] := (not Paused) and (ALevel in VisibleLevels);
|
||||||
|
|
||||||
@ -762,7 +766,7 @@ begin
|
|||||||
for node in vstLog.Nodes do
|
for node in vstLog.Nodes do
|
||||||
begin
|
begin
|
||||||
nodeData := vstLog.GetNodeData(node);
|
nodeData := vstLog.GetNodeData(node);
|
||||||
ALog.Log(nodeData^.Level, nodeData^.Time, nodeData^.Message, nodeData^.Details);
|
ALog.Log(nodeData^.Level, nodeData^.Time, nodeData^.Message, nodeData^.Category, nodeData^.Details);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -790,6 +794,9 @@ begin
|
|||||||
ColumnTime:
|
ColumnTime:
|
||||||
CellText := DateTimeToStr(nodeData^.Time);
|
CellText := DateTimeToStr(nodeData^.Time);
|
||||||
|
|
||||||
|
ColumnCategory:
|
||||||
|
CellText := nodeData^.Category;
|
||||||
|
|
||||||
ColumnMessage:
|
ColumnMessage:
|
||||||
CellText := nodeData^.Message;
|
CellText := nodeData^.Message;
|
||||||
end;
|
end;
|
||||||
|
@ -220,6 +220,9 @@ begin
|
|||||||
|
|
||||||
WriteBuffer.WriteBuffer(header, SizeOf(header));
|
WriteBuffer.WriteBuffer(header, SizeOf(header));
|
||||||
|
|
||||||
|
{ Category }
|
||||||
|
TStreamUtil.WriteString(WriteBuffer, AEntry.Category);
|
||||||
|
|
||||||
{ Message }
|
{ Message }
|
||||||
TStreamUtil.WriteString(WriteBuffer, AEntry.Message);
|
TStreamUtil.WriteString(WriteBuffer, AEntry.Message);
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ begin
|
|||||||
|
|
||||||
SetLogResourceString(@LogMonitorFormCaption, '%s - Live Log');
|
SetLogResourceString(@LogMonitorFormCaption, '%s - Live Log');
|
||||||
SetLogResourceString(@LogMonitorFormColumnTime, 'Tijd');
|
SetLogResourceString(@LogMonitorFormColumnTime, 'Tijd');
|
||||||
|
SetLogResourceString(@LogMonitorFormColumnCategory, 'Categorie');
|
||||||
SetLogResourceString(@LogMonitorFormColumnMessage, 'Melding');
|
SetLogResourceString(@LogMonitorFormColumnMessage, 'Melding');
|
||||||
|
|
||||||
SetLogResourceString(@LogMonitorFormButtonClear, 'Wissen');
|
SetLogResourceString(@LogMonitorFormButtonClear, 'Wissen');
|
||||||
|
220
X2Log.pas
220
X2Log.pas
@ -11,10 +11,19 @@ uses
|
|||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TX2Log = class(TX2LogBaseClient, IX2Log)
|
IX2LogExceptionCategory = interface
|
||||||
|
['{ED076237-65AA-4B0C-8A25-4A6B28D2F0CB}']
|
||||||
|
procedure Exception(AException: Exception; const AMessage: string = ''; const ACategory: string = '');
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
TX2Log = class(TX2LogBaseClient, IX2Log, IX2LogExceptionCategory)
|
||||||
private
|
private
|
||||||
FExceptionStrategy: IX2LogExceptionStrategy;
|
FExceptionStrategy: IX2LogExceptionStrategy;
|
||||||
private
|
protected
|
||||||
|
{ IX2LogExceptionCategory }
|
||||||
|
procedure Exception(AException: Exception; const AMessage: string = ''; const ACategory: string = ''); overload;
|
||||||
|
|
||||||
property ExceptionStrategy: IX2LogExceptionStrategy read FExceptionStrategy;
|
property ExceptionStrategy: IX2LogExceptionStrategy read FExceptionStrategy;
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
@ -22,6 +31,49 @@ type
|
|||||||
{ IX2Log }
|
{ IX2Log }
|
||||||
procedure SetExceptionStrategy(AStrategy: IX2LogExceptionStrategy);
|
procedure SetExceptionStrategy(AStrategy: IX2LogExceptionStrategy);
|
||||||
|
|
||||||
|
function Category(const ACategory: string): IX2Log;
|
||||||
|
|
||||||
|
procedure Verbose(const AMessage: string; const ADetails: string = '');
|
||||||
|
procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||||
|
|
||||||
|
procedure Info(const AMessage: string; const ADetails: string = '');
|
||||||
|
procedure InfoEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||||
|
|
||||||
|
procedure Warning(const AMessage: string; const ADetails: string = '');
|
||||||
|
procedure WarningEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||||
|
|
||||||
|
procedure Error(const AMessage: string; const ADetails: string = '');
|
||||||
|
procedure ErrorEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||||
|
|
||||||
|
procedure Exception(AException: Exception; const AMessage: string = ''); overload;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
TX2LogCategoryDecorator = class(TInterfacedObject, IX2Log)
|
||||||
|
private
|
||||||
|
FCategoryName: string;
|
||||||
|
FDecoratedLog: IX2Log;
|
||||||
|
protected
|
||||||
|
function GetCategory(const ACategory: string = ''): string;
|
||||||
|
|
||||||
|
property CategoryName: string read FCategoryName write FCategoryName;
|
||||||
|
property DecoratedLog: IX2Log read FDecoratedLog;
|
||||||
|
public
|
||||||
|
constructor Create(ADecoratedLog: IX2Log; const ACategory: string);
|
||||||
|
|
||||||
|
{ IX2LogBase }
|
||||||
|
procedure Log(ALevel: TX2LogLevel; const AMessage: string; const ACategory: string = ''; ADetails: IX2LogDetails = nil); overload;
|
||||||
|
procedure Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; const ACategory: string = ''; ADetails: IX2LogDetails = nil); overload;
|
||||||
|
|
||||||
|
{ IX2LogObservable }
|
||||||
|
procedure Attach(AObserver: IX2LogObserver);
|
||||||
|
procedure Detach(AObserver: IX2LogObserver);
|
||||||
|
|
||||||
|
{ IX2Log }
|
||||||
|
procedure SetExceptionStrategy(AStrategy: IX2LogExceptionStrategy);
|
||||||
|
|
||||||
|
function Category(const ACategory: string): IX2Log;
|
||||||
|
|
||||||
procedure Verbose(const AMessage: string; const ADetails: string = '');
|
procedure Verbose(const AMessage: string; const ADetails: string = '');
|
||||||
procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||||
|
|
||||||
@ -38,8 +90,10 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
uses
|
uses
|
||||||
|
X2Log.Constants,
|
||||||
X2Log.Details.Default,
|
X2Log.Details.Default,
|
||||||
X2Log.Exception.Default;
|
X2Log.Exception.Default;
|
||||||
|
|
||||||
@ -62,55 +116,67 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2Log.Category(const ACategory: string): IX2Log;
|
||||||
|
begin
|
||||||
|
Result := TX2LogCategoryDecorator.Create(Self, ACategory);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2Log.Verbose(const AMessage, ADetails: string);
|
procedure TX2Log.Verbose(const AMessage, ADetails: string);
|
||||||
begin
|
begin
|
||||||
Log(TX2LogLevel.Verbose, AMessage, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
Log(TX2LogLevel.Verbose, AMessage, LogCategoryDefault, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2Log.VerboseEx(const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2Log.VerboseEx(const AMessage: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
Log(TX2LogLevel.Verbose, AMessage, ADetails);
|
Log(TX2LogLevel.Verbose, AMessage, LogCategoryDefault, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2Log.Info(const AMessage, ADetails: string);
|
procedure TX2Log.Info(const AMessage, ADetails: string);
|
||||||
begin
|
begin
|
||||||
Log(TX2LogLevel.Info, AMessage, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
Log(TX2LogLevel.Info, AMessage, LogCategoryDefault, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2Log.InfoEx(const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2Log.InfoEx(const AMessage: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
Log(TX2LogLevel.Info, AMessage, ADetails);
|
Log(TX2LogLevel.Info, AMessage, LogCategoryDefault, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2Log.Warning(const AMessage, ADetails: string);
|
procedure TX2Log.Warning(const AMessage, ADetails: string);
|
||||||
begin
|
begin
|
||||||
Log(TX2LogLevel.Warning, AMessage, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
Log(TX2LogLevel.Warning, AMessage, LogCategoryDefault, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2Log.WarningEx(const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2Log.WarningEx(const AMessage: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
Log(TX2LogLevel.Warning, AMessage, ADetails);
|
Log(TX2LogLevel.Warning, AMessage, LogCategoryDefault, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2Log.Error(const AMessage, ADetails: string);
|
procedure TX2Log.Error(const AMessage, ADetails: string);
|
||||||
begin
|
begin
|
||||||
Log(TX2LogLevel.Error, AMessage, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
Log(TX2LogLevel.Error, AMessage, LogCategoryDefault, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2Log.ErrorEx(const AMessage: string; ADetails: IX2LogDetails);
|
procedure TX2Log.ErrorEx(const AMessage: string; ADetails: IX2LogDetails);
|
||||||
begin
|
begin
|
||||||
Log(TX2LogLevel.Error, AMessage, ADetails);
|
Log(TX2LogLevel.Error, AMessage, LogCategoryDefault, ADetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TX2Log.Exception(AException: Exception; const AMessage: string);
|
procedure TX2Log.Exception(AException: Exception; const AMessage: string);
|
||||||
|
begin
|
||||||
|
Exception(AException, AMessage, LogCategoryDefault);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2Log.Exception(AException: Exception; const AMessage, ACategory: string);
|
||||||
var
|
var
|
||||||
msg: string;
|
msg: string;
|
||||||
details: IX2LogDetails;
|
details: IX2LogDetails;
|
||||||
@ -120,7 +186,139 @@ begin
|
|||||||
details := nil;
|
details := nil;
|
||||||
|
|
||||||
ExceptionStrategy.Execute(AException, msg, details);
|
ExceptionStrategy.Execute(AException, msg, details);
|
||||||
Log(TX2LogLevel.Error, msg, details);
|
Log(TX2LogLevel.Error, msg, LogCategoryDefault, details);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TX2LogCategoryDecorator }
|
||||||
|
constructor TX2LogCategoryDecorator.Create(ADecoratedLog: IX2Log; const ACategory: string);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
|
||||||
|
FDecoratedLog := ADecoratedLog;
|
||||||
|
FCategoryName := ACategory;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.Log(ALevel: TX2LogLevel; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Log(ALevel, AMessage, GetCategory(ACategory), ADetails);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.Log(ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage, ACategory: string; ADetails: IX2LogDetails);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Log(ALevel, AMessage, GetCategory(ACategory), ADetails);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.Attach(AObserver: IX2LogObserver);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Attach(AObserver);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.Detach(AObserver: IX2LogObserver);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Detach(AObserver);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.SetExceptionStrategy(AStrategy: IX2LogExceptionStrategy);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.SetExceptionStrategy(AStrategy);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogCategoryDecorator.Category(const ACategory: string): IX2Log;
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
Result := Self.Create(DecoratedLog, GetCategory(ACategory));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.Verbose(const AMessage, ADetails: string);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Log(TX2LogLevel.Verbose, AMessage, CategoryName, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.VerboseEx(const AMessage: string; ADetails: IX2LogDetails);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Log(TX2LogLevel.Verbose, AMessage, CategoryName, ADetails);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.Info(const AMessage, ADetails: string);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Log(TX2LogLevel.Info, AMessage, CategoryName, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.InfoEx(const AMessage: string; ADetails: IX2LogDetails);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Log(TX2LogLevel.Info, AMessage, CategoryName, ADetails);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.Warning(const AMessage, ADetails: string);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Log(TX2LogLevel.Warning, AMessage, CategoryName, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.WarningEx(const AMessage: string; ADetails: IX2LogDetails);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Log(TX2LogLevel.Warning, AMessage, CategoryName, ADetails);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.Error(const AMessage, ADetails: string);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Log(TX2LogLevel.Error, AMessage, CategoryName, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.ErrorEx(const AMessage: string; ADetails: IX2LogDetails);
|
||||||
|
begin
|
||||||
|
if Assigned(DecoratedLog) then
|
||||||
|
DecoratedLog.Log(TX2LogLevel.Error, AMessage, CategoryName, ADetails);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TX2LogCategoryDecorator.Exception(AException: Exception; const AMessage: string);
|
||||||
|
var
|
||||||
|
exceptionCategory: IX2LogExceptionCategory;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if not Assigned(DecoratedLog) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
if Supports(DecoratedLog, IX2LogExceptionCategory, exceptionCategory) then
|
||||||
|
exceptionCategory.Exception(AException, AMessage, CategoryName)
|
||||||
|
else
|
||||||
|
DecoratedLog.Log(TX2LogLevel.Error, AMessage, CategoryName);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogCategoryDecorator.GetCategory(const ACategory: string): string;
|
||||||
|
begin
|
||||||
|
Result := CategoryName;
|
||||||
|
|
||||||
|
if Length(ACategory) > 0 then
|
||||||
|
Result := Result + LogCategorySeparator + ACategory;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user