1
0
mirror of synced 2024-11-08 22:29:16 +00:00
x2log/X2Log.TextFormatter.Json.pas

128 lines
3.4 KiB
ObjectPascal
Raw Normal View History

unit X2Log.TextFormatter.Json;
interface
uses
X2Log.JsonDataObjects,
X2Log.Details.Intf,
X2Log.Intf,
X2Log.TextFormatter.Intf;
type
{
Default:
X2Log naming convention is used for the property names
Kibana:
Logstash/Kibana compatible (message, @timestamp, @version) property names
}
TX2LogJsonStyle = (Default, Kibana);
TX2LogJsonTextFormatter = class(TInterfacedObject, IX2LogTextFormatter)
private
FSingleLine: Boolean;
FStyle: TX2LogJsonStyle;
protected
function GetText(AHelper: IX2LogTextFormatterHelper; ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; const ACategory: string; ADetails: IX2LogDetails): string;
procedure AddDictionaryDetails(AObject: TJsonObject; ADetails: IX2LogDetailsDictionary);
property SingleLine: Boolean read FSingleLine;
property Style: TX2LogJsonStyle read FStyle;
public
constructor Create(ASingleLine: Boolean = True; AStyle: TX2LogJsonStyle = TX2LogJsonStyle.Default);
end;
implementation
uses
System.SysUtils;
{ TX2LogJsonTextFormatter }
constructor TX2LogJsonTextFormatter.Create(ASingleLine: Boolean; AStyle: TX2LogJsonStyle);
begin
inherited Create;
FSingleLine := ASingleLine;
FStyle := AStyle;
end;
function TX2LogJsonTextFormatter.GetText(AHelper: IX2LogTextFormatterHelper; ALevel: TX2LogLevel; ADateTime: TDateTime;
const AMessage, ACategory: string; ADetails: IX2LogDetails): string;
const
LogLevelName: array[TX2LogLevel] of string = ('verbose', 'info', 'warning', 'error');
var
line: TJsonObject;
dictionaryDetails: IX2LogDetailsDictionary;
detailsFileName: string;
begin
line := TJsonObject.Create;
try
case Style of
Default:
begin
line.D['dateTime'] := ADateTime;
line.S['message'] := AMessage;
end;
Kibana:
begin
line.S['@version'] := '1';
line.D['@timestamp'] := ADateTime;
line.S['message'] := AMessage;
end;
end;
line.S['level'] := LogLevelName[ALevel];
line.S['category'] := ACategory;
if Supports(ADetails, IX2LogDetailsDictionary, dictionaryDetails) then
begin
AddDictionaryDetails(line, dictionaryDetails);
end else
begin
detailsFileName := AHelper.GetDetailsFilename;
if Length(detailsFileName) > 0 then
line.S['details'] := ExtractFileName(detailsFileName);
end;
Result := line.ToJSON(SingleLine);
finally
FreeAndNil(line);
end;
end;
procedure TX2LogJsonTextFormatter.AddDictionaryDetails(AObject: TJsonObject; ADetails: IX2LogDetailsDictionary);
var
key: string;
jsonKey: string;
valueType: TX2LogValueType;
begin
for key in ADetails.Keys do
begin
jsonKey := key;
while AObject.Contains(jsonKey) do
jsonKey := '_' + jsonKey;
valueType := ADetails.ValueType[key];
case valueType of
StringValue: AObject.S[jsonKey] := ADetails.StringValue[key];
BooleanValue: AObject.B[jsonKey] := ADetails.BooleanValue[key];
IntValue: AObject.L[jsonKey] := ADetails.IntValue[key];
FloatValue: AObject.F[jsonKey] := ADetails.FloatValue[key];
DateTimeValue: AObject.D[jsonKey] := ADetails.DateTimeValue[key];
else
AObject.S[jsonKey] := Format('<error: unknown ValueType %d>', [Ord(valueType)]);
end;
end;
end;
end.