Added framework for dictionary details, facilitating structured logging
This commit is contained in:
parent
e12d1fe497
commit
76d0536255
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
__history/
|
||||
Test/lib/
|
||||
Test/bin/
|
||||
*.tvsconfig
|
||||
*.local
|
||||
*.identcache
|
@ -37,15 +37,19 @@ type
|
||||
|
||||
procedure Verbose(const AMessage: string; const ADetails: string = '');
|
||||
procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure VerboseS(const AMessage: string; ANamedParams: array of const);
|
||||
|
||||
procedure Info(const AMessage: string; const ADetails: string = '');
|
||||
procedure InfoEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure InfoS(const AMessage: string; ANamedParams: array of const);
|
||||
|
||||
procedure Warning(const AMessage: string; const ADetails: string = '');
|
||||
procedure WarningEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure WarningS(const AMessage: string; ANamedParams: array of const);
|
||||
|
||||
procedure Error(const AMessage: string; const ADetails: string = '');
|
||||
procedure ErrorEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure ErrorS(const AMessage: string; ANamedParams: array of const);
|
||||
|
||||
procedure Exception(AException: Exception; const AMessage: string = '');
|
||||
procedure ExceptionEx(AException: Exception; const AMessage: string = ''; const ACategory: string = '');
|
||||
@ -126,6 +130,13 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2LogCategoryDecorator.VerboseS(const AMessage: string; ANamedParams: array of const);
|
||||
begin
|
||||
if Assigned(DecoratedLog) then
|
||||
DecoratedLog.Log(TX2LogLevel.Verbose, Now, AMessage, CategoryName, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams));
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2LogCategoryDecorator.Info(const AMessage, ADetails: string);
|
||||
begin
|
||||
if Assigned(DecoratedLog) then
|
||||
@ -140,6 +151,12 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2LogCategoryDecorator.InfoS(const AMessage: string; ANamedParams: array of const);
|
||||
begin
|
||||
if Assigned(DecoratedLog) then
|
||||
DecoratedLog.Log(TX2LogLevel.Info, Now, AMessage, CategoryName, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams));
|
||||
end;
|
||||
|
||||
procedure TX2LogCategoryDecorator.Warning(const AMessage, ADetails: string);
|
||||
begin
|
||||
if Assigned(DecoratedLog) then
|
||||
@ -154,6 +171,12 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2LogCategoryDecorator.WarningS(const AMessage: string; ANamedParams: array of const);
|
||||
begin
|
||||
if Assigned(DecoratedLog) then
|
||||
DecoratedLog.Log(TX2LogLevel.Warning, Now, AMessage, CategoryName, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams));
|
||||
end;
|
||||
|
||||
procedure TX2LogCategoryDecorator.Error(const AMessage, ADetails: string);
|
||||
begin
|
||||
if Assigned(DecoratedLog) then
|
||||
@ -168,6 +191,13 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2LogCategoryDecorator.ErrorS(const AMessage: string; ANamedParams: array of const);
|
||||
begin
|
||||
if Assigned(DecoratedLog) then
|
||||
DecoratedLog.Log(TX2LogLevel.Error, Now, AMessage, CategoryName, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams));
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2LogCategoryDecorator.Exception(AException: Exception; const AMessage: string);
|
||||
begin
|
||||
if Assigned(DecoratedLog) then
|
||||
|
@ -3,6 +3,7 @@ unit X2Log.Details.Default;
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
System.Generics.Collections,
|
||||
Vcl.Graphics,
|
||||
|
||||
X2Log.Details.Intf,
|
||||
@ -33,6 +34,29 @@ type
|
||||
end;
|
||||
|
||||
|
||||
TX2LogDictionaryDetails = class(TInterfacedObject, IX2LogDetails, IX2LogDetailsDictionary,
|
||||
IX2LogDetailsCopyable, IX2LogDetailsStreamable)
|
||||
private
|
||||
FValues: TDictionary<string, Variant>;
|
||||
public
|
||||
class function CreateIfNotEmpty(AValues: array of const): TX2LogDictionaryDetails;
|
||||
|
||||
constructor Create(AValues: array of const);
|
||||
destructor Destroy; override;
|
||||
|
||||
{ IX2LogDetails }
|
||||
function GetSerializerIID: TGUID;
|
||||
|
||||
{ IX2LogDetailsDictionary }
|
||||
function GetValue(const Key: string): Variant;
|
||||
|
||||
{ IX2LogDetailsCopyable }
|
||||
procedure CopyToClipboard;
|
||||
|
||||
{ IX2LogDetailsStreamable }
|
||||
procedure SaveToStream(AStream: TStream);
|
||||
end;
|
||||
|
||||
|
||||
TX2LogBinaryDetails = class(TInterfacedObject, IX2LogDetails, IX2LogDetailsBinary,
|
||||
IX2LogDetailsStreamable)
|
||||
@ -98,6 +122,7 @@ uses
|
||||
|
||||
const
|
||||
StringDetailsSerializerIID: TGUID = '{4223C30E-6E80-4D66-9EDC-F8688A7413D2}';
|
||||
DictionaryDetailsSerializerIID: TGUID = '{1D28FF6E-8AA7-41FA-96D7-0CE921D9CA2E}';
|
||||
BinaryDetailsSerializerIID: TGUID = '{05F6E8BD-118E-41B3-B626-1F190CC2A7D3}';
|
||||
GraphicDetailsSerializerIID: TGUID = '{BD31E42A-83DC-4947-A862-79ABAE8D5056}';
|
||||
|
||||
@ -112,6 +137,14 @@ type
|
||||
end;
|
||||
|
||||
|
||||
TX2LogDictionaryDetailsSerializer = class(TInterfacedObject, IX2LogDetailsSerializer)
|
||||
public
|
||||
{ IX2LogDetailsSerializer }
|
||||
procedure Serialize(ADetails: IX2LogDetails; AStream: TStream);
|
||||
function Deserialize(AStream: TStream): IX2LogDetails;
|
||||
end;
|
||||
|
||||
|
||||
TX2LogBinaryDetailsSerializer = class(TInterfacedObject, IX2LogDetailsSerializer)
|
||||
public
|
||||
{ IX2LogDetailsSerializer }
|
||||
@ -178,6 +211,58 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{ TX2LogDictionaryDetails }
|
||||
class function TX2LogDictionaryDetails.CreateIfNotEmpty(AValues: array of const): TX2LogDictionaryDetails;
|
||||
begin
|
||||
if Length(AValues) > 0 then
|
||||
Result := TX2LogDictionaryDetails.Create(AValues)
|
||||
else
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
|
||||
constructor TX2LogDictionaryDetails.Create(AValues: array of const);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
FValues := TDictionary<string, Variant>.Create();
|
||||
|
||||
// TODO parse AValues
|
||||
end;
|
||||
|
||||
|
||||
destructor TX2LogDictionaryDetails.Destroy;
|
||||
begin
|
||||
FreeAndNil(FValues);
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
||||
function TX2LogDictionaryDetails.GetSerializerIID: TGUID;
|
||||
begin
|
||||
Result := DictionaryDetailsSerializerIID;
|
||||
end;
|
||||
|
||||
|
||||
function TX2LogDictionaryDetails.GetValue(const Key: string): Variant;
|
||||
begin
|
||||
// TODO
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2LogDictionaryDetails.CopyToClipboard;
|
||||
begin
|
||||
// TODO
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2LogDictionaryDetails.SaveToStream(AStream: TStream);
|
||||
begin
|
||||
// TODO
|
||||
end;
|
||||
|
||||
|
||||
{ TX2LogBinaryDetails }
|
||||
constructor TX2LogBinaryDetails.Create;
|
||||
begin
|
||||
@ -311,6 +396,18 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{ TX2LogDictionaryDetailsSerializer }
|
||||
function TX2LogDictionaryDetailsSerializer.Deserialize(AStream: TStream): IX2LogDetails;
|
||||
begin
|
||||
// TODO
|
||||
end;
|
||||
|
||||
procedure TX2LogDictionaryDetailsSerializer.Serialize(ADetails: IX2LogDetails; AStream: TStream);
|
||||
begin
|
||||
// TODO
|
||||
end;
|
||||
|
||||
|
||||
{ TX2LogBinaryDetailsSerializer }
|
||||
procedure TX2LogBinaryDetailsSerializer.Serialize(ADetails: IX2LogDetails; AStream: TStream);
|
||||
var
|
||||
@ -376,6 +473,7 @@ end;
|
||||
|
||||
initialization
|
||||
TX2LogDetailsRegistry.Register(StringDetailsSerializerIID, TX2LogStringDetailsSerializer.Create);
|
||||
TX2LogDetailsRegistry.Register(DictionaryDetailsSerializerIID, TX2LogDictionaryDetailsSerializer.Create);
|
||||
TX2LogDetailsRegistry.Register(BinaryDetailsSerializerIID, TX2LogBinaryDetailsSerializer.Create);
|
||||
TX2LogDetailsRegistry.Register(GraphicDetailsSerializerIID, TX2LogGraphicDetailsSerializer.Create);
|
||||
|
||||
|
@ -17,6 +17,14 @@ type
|
||||
end;
|
||||
|
||||
|
||||
IX2LogDetailsDictionary = interface(IX2LogDetails)
|
||||
['{24211DC0-F359-466B-A9CD-AF6AA3AE85F4}']
|
||||
function GetValue(const Key: string): Variant;
|
||||
|
||||
property Values[const Key: string]: Variant read GetValue;
|
||||
end;
|
||||
|
||||
|
||||
IX2LogDetailsBinary = interface(IX2LogDetails)
|
||||
['{265739E7-BB65-434B-BCD3-BB89B936A854}']
|
||||
function GetAsStream: TStream;
|
||||
|
@ -79,47 +79,23 @@ type
|
||||
|
||||
procedure Verbose(const AMessage: string; const ADetails: string = '');
|
||||
procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure VerboseS(const AMessage: string; ANamedParams: array of const); overload;
|
||||
|
||||
procedure Info(const AMessage: string; const ADetails: string = '');
|
||||
procedure InfoEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure InfoS(const AMessage: string; ANamedParams: array of const); overload;
|
||||
|
||||
procedure Warning(const AMessage: string; const ADetails: string = '');
|
||||
procedure WarningEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure WarningS(const AMessage: string; ANamedParams: array of const); overload;
|
||||
|
||||
procedure Error(const AMessage: string; const ADetails: string = '');
|
||||
procedure ErrorEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure ErrorS(const AMessage: string; ANamedParams: array of const); overload;
|
||||
|
||||
procedure Exception(AException: Exception; const AMessage: string = '');
|
||||
procedure ExceptionEx(AException: Exception; const AMessage: string = ''; const ACategory: string = '');
|
||||
end;
|
||||
|
||||
|
||||
|
||||
TX2LogMessageHeaderV1 = packed record
|
||||
ID: Word;
|
||||
Version: Byte;
|
||||
Size: Word;
|
||||
DateTime: TDateTime;
|
||||
Level: TX2LogLevel;
|
||||
|
||||
{
|
||||
Payload:
|
||||
|
||||
CategoryLength: Cardinal
|
||||
Category: WideString
|
||||
MessageLength: Cardinal
|
||||
Message: WideString
|
||||
DetailsLength: Cardinal
|
||||
Details: WideString
|
||||
}
|
||||
end;
|
||||
|
||||
|
||||
TX2LogMessageHeader = TX2LogMessageHeaderV1;
|
||||
|
||||
const
|
||||
X2LogMessageHeader: Word = $B258;
|
||||
X2LogMessageVersion: Byte = 1;
|
||||
|
||||
|
||||
implementation
|
||||
|
28
X2Log.pas
28
X2Log.pas
@ -26,15 +26,19 @@ type
|
||||
|
||||
procedure Verbose(const AMessage: string; const ADetails: string = '');
|
||||
procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure VerboseS(const AMessage: string; ANamedParams: array of const);
|
||||
|
||||
procedure Info(const AMessage: string; const ADetails: string = '');
|
||||
procedure InfoEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure InfoS(const AMessage: string; ANamedParams: array of const);
|
||||
|
||||
procedure Warning(const AMessage: string; const ADetails: string = '');
|
||||
procedure WarningEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure WarningS(const AMessage: string; ANamedParams: array of const);
|
||||
|
||||
procedure Error(const AMessage: string; const ADetails: string = '');
|
||||
procedure ErrorEx(const AMessage: string; ADetails: IX2LogDetails = nil);
|
||||
procedure ErrorS(const AMessage: string; ANamedParams: array of const);
|
||||
|
||||
procedure Exception(AException: Exception; const AMessage: string = '');
|
||||
procedure ExceptionEx(AException: Exception; const AMessage: string = ''; const ACategory: string = '');
|
||||
@ -85,6 +89,12 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2Log.VerboseS(const AMessage: string; ANamedParams: array of const);
|
||||
begin
|
||||
Log(TX2LogLevel.Verbose, Now, AMessage, LogCategoryDefault, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams));
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2Log.Info(const AMessage, ADetails: string);
|
||||
begin
|
||||
Log(TX2LogLevel.Info, AMessage, LogCategoryDefault, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||
@ -97,6 +107,12 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2Log.InfoS(const AMessage: string; ANamedParams: array of const);
|
||||
begin
|
||||
Log(TX2LogLevel.Info, Now, AMessage, LogCategoryDefault, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams));
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2Log.Warning(const AMessage, ADetails: string);
|
||||
begin
|
||||
Log(TX2LogLevel.Warning, AMessage, LogCategoryDefault, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||
@ -109,6 +125,12 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2Log.WarningS(const AMessage: string; ANamedParams: array of const);
|
||||
begin
|
||||
Log(TX2LogLevel.Warning, Now, AMessage, LogCategoryDefault, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams));
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2Log.Error(const AMessage, ADetails: string);
|
||||
begin
|
||||
Log(TX2LogLevel.Error, AMessage, LogCategoryDefault, TX2LogStringDetails.CreateIfNotEmpty(ADetails));
|
||||
@ -121,6 +143,12 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2Log.ErrorS(const AMessage: string; ANamedParams: array of const);
|
||||
begin
|
||||
Log(TX2LogLevel.Error, Now, AMessage, LogCategoryDefault, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams));
|
||||
end;
|
||||
|
||||
|
||||
procedure TX2Log.Exception(AException: Exception; const AMessage: string);
|
||||
begin
|
||||
ExceptionEx(AException, AMessage, LogCategoryDefault);
|
||||
|
Loading…
Reference in New Issue
Block a user