Added Json text formatter for file output
This commit is contained in:
parent
f124ccd0c2
commit
9571bb4f97
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ Test/bin/
|
|||||||
*.tvsconfig
|
*.tvsconfig
|
||||||
*.local
|
*.local
|
||||||
*.identcache
|
*.identcache
|
||||||
|
*.dcu
|
||||||
|
@ -52,7 +52,11 @@ contains
|
|||||||
X2Log.Util.Stream in '..\X2Log.Util.Stream.pas',
|
X2Log.Util.Stream in '..\X2Log.Util.Stream.pas',
|
||||||
X2Log.Translations.Dutch in '..\X2Log.Translations.Dutch.pas',
|
X2Log.Translations.Dutch in '..\X2Log.Translations.Dutch.pas',
|
||||||
X2Log.Decorator in '..\X2Log.Decorator.pas',
|
X2Log.Decorator in '..\X2Log.Decorator.pas',
|
||||||
X2Log.Observer.RollingLogFile in '..\X2Log.Observer.RollingLogFile.pas';
|
X2Log.Observer.RollingLogFile in '..\X2Log.Observer.RollingLogFile.pas',
|
||||||
|
X2Log.TextFormatter.Default in '..\X2Log.TextFormatter.Default.pas',
|
||||||
|
X2Log.TextFormatter.Intf in '..\X2Log.TextFormatter.Intf.pas',
|
||||||
|
X2Log.Intf.NamedPipe in '..\X2Log.Intf.NamedPipe.pas';
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,6 +109,9 @@
|
|||||||
<DCCReference Include="..\X2Log.Translations.Dutch.pas"/>
|
<DCCReference Include="..\X2Log.Translations.Dutch.pas"/>
|
||||||
<DCCReference Include="..\X2Log.Decorator.pas"/>
|
<DCCReference Include="..\X2Log.Decorator.pas"/>
|
||||||
<DCCReference Include="..\X2Log.Observer.RollingLogFile.pas"/>
|
<DCCReference Include="..\X2Log.Observer.RollingLogFile.pas"/>
|
||||||
|
<DCCReference Include="..\X2Log.TextFormatter.Default.pas"/>
|
||||||
|
<DCCReference Include="..\X2Log.TextFormatter.Intf.pas"/>
|
||||||
|
<DCCReference Include="..\X2Log.Intf.NamedPipe.pas"/>
|
||||||
<BuildConfiguration Include="Base">
|
<BuildConfiguration Include="Base">
|
||||||
<Key>Base</Key>
|
<Key>Base</Key>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
<Projects Include="X2LogFormsDXE2.dproj">
|
<Projects Include="X2LogFormsDXE2.dproj">
|
||||||
<Dependencies/>
|
<Dependencies/>
|
||||||
</Projects>
|
</Projects>
|
||||||
|
<Projects Include="X2LogJsonDXE2.dproj">
|
||||||
|
<Dependencies/>
|
||||||
|
</Projects>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<Borland.Personality>Default.Personality.12</Borland.Personality>
|
<Borland.Personality>Default.Personality.12</Borland.Personality>
|
||||||
@ -47,14 +50,23 @@
|
|||||||
<Target Name="X2LogFormsDXE2:Make">
|
<Target Name="X2LogFormsDXE2:Make">
|
||||||
<MSBuild Projects="X2LogFormsDXE2.dproj" Targets="Make"/>
|
<MSBuild Projects="X2LogFormsDXE2.dproj" Targets="Make"/>
|
||||||
</Target>
|
</Target>
|
||||||
|
<Target Name="X2LogJsonDXE2">
|
||||||
|
<MSBuild Projects="X2LogJsonDXE2.dproj"/>
|
||||||
|
</Target>
|
||||||
|
<Target Name="X2LogJsonDXE2:Clean">
|
||||||
|
<MSBuild Projects="X2LogJsonDXE2.dproj" Targets="Clean"/>
|
||||||
|
</Target>
|
||||||
|
<Target Name="X2LogJsonDXE2:Make">
|
||||||
|
<MSBuild Projects="X2LogJsonDXE2.dproj" Targets="Make"/>
|
||||||
|
</Target>
|
||||||
<Target Name="Build">
|
<Target Name="Build">
|
||||||
<CallTarget Targets="X2LogDXE2;X2LogMadExceptDXE2;X2LogFormsDXE2"/>
|
<CallTarget Targets="X2LogDXE2;X2LogMadExceptDXE2;X2LogFormsDXE2;X2LogJsonDXE2"/>
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="Clean">
|
<Target Name="Clean">
|
||||||
<CallTarget Targets="X2LogDXE2:Clean;X2LogMadExceptDXE2:Clean;X2LogFormsDXE2:Clean"/>
|
<CallTarget Targets="X2LogDXE2:Clean;X2LogMadExceptDXE2:Clean;X2LogFormsDXE2:Clean;X2LogJsonDXE2:Clean"/>
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="Make">
|
<Target Name="Make">
|
||||||
<CallTarget Targets="X2LogDXE2:Make;X2LogMadExceptDXE2:Make;X2LogFormsDXE2:Make"/>
|
<CallTarget Targets="X2LogDXE2:Make;X2LogMadExceptDXE2:Make;X2LogFormsDXE2:Make;X2LogJsonDXE2:Make"/>
|
||||||
</Target>
|
</Target>
|
||||||
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')" Project="$(BDS)\Bin\CodeGear.Group.Targets"/>
|
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')" Project="$(BDS)\Bin\CodeGear.Group.Targets"/>
|
||||||
</Project>
|
</Project>
|
||||||
|
39
Packages/X2LogJsonDXE2.dpk
Normal file
39
Packages/X2LogJsonDXE2.dpk
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package X2LogJsonDXE2;
|
||||||
|
|
||||||
|
{$R *.res}
|
||||||
|
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
|
||||||
|
{$ALIGN 8}
|
||||||
|
{$ASSERTIONS ON}
|
||||||
|
{$BOOLEVAL OFF}
|
||||||
|
{$DEBUGINFO ON}
|
||||||
|
{$EXTENDEDSYNTAX ON}
|
||||||
|
{$IMPORTEDDATA ON}
|
||||||
|
{$IOCHECKS ON}
|
||||||
|
{$LOCALSYMBOLS ON}
|
||||||
|
{$LONGSTRINGS ON}
|
||||||
|
{$OPENSTRINGS ON}
|
||||||
|
{$OPTIMIZATION OFF}
|
||||||
|
{$OVERFLOWCHECKS OFF}
|
||||||
|
{$RANGECHECKS OFF}
|
||||||
|
{$REFERENCEINFO ON}
|
||||||
|
{$SAFEDIVIDE OFF}
|
||||||
|
{$STACKFRAMES ON}
|
||||||
|
{$TYPEDADDRESS OFF}
|
||||||
|
{$VARSTRINGCHECKS ON}
|
||||||
|
{$WRITEABLECONST OFF}
|
||||||
|
{$MINENUMSIZE 1}
|
||||||
|
{$IMAGEBASE $400000}
|
||||||
|
{$DEFINE DEBUG}
|
||||||
|
{$DEFINE $(DELPHIBIN64)}
|
||||||
|
{$ENDIF IMPLICITBUILDING}
|
||||||
|
{$IMPLICITBUILD ON}
|
||||||
|
|
||||||
|
requires
|
||||||
|
rtl,
|
||||||
|
X2LogDXE2;
|
||||||
|
|
||||||
|
contains
|
||||||
|
X2Log.TextFormatter.Json in '..\X2Log.TextFormatter.Json.pas';
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
187
Packages/X2LogJsonDXE2.dproj
Normal file
187
Packages/X2LogJsonDXE2.dproj
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ProjectGuid>{5742A326-C831-4737-AA01-900CC5C18CCA}</ProjectGuid>
|
||||||
|
<MainSource>X2LogJsonDXE2.dpk</MainSource>
|
||||||
|
<ProjectVersion>13.4</ProjectVersion>
|
||||||
|
<FrameworkType>None</FrameworkType>
|
||||||
|
<Base>True</Base>
|
||||||
|
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||||
|
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||||
|
<TargetedPlatforms>3</TargetedPlatforms>
|
||||||
|
<AppType>Package</AppType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
|
||||||
|
<Base>true</Base>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
|
||||||
|
<Base_Win64>true</Base_Win64>
|
||||||
|
<CfgParent>Base</CfgParent>
|
||||||
|
<Base>true</Base>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
|
||||||
|
<Base_Win32>true</Base_Win32>
|
||||||
|
<CfgParent>Base</CfgParent>
|
||||||
|
<Base>true</Base>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
|
||||||
|
<Cfg_1>true</Cfg_1>
|
||||||
|
<CfgParent>Base</CfgParent>
|
||||||
|
<Base>true</Base>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
|
||||||
|
<Cfg_1_Win64>true</Cfg_1_Win64>
|
||||||
|
<CfgParent>Cfg_1</CfgParent>
|
||||||
|
<Cfg_1>true</Cfg_1>
|
||||||
|
<Base>true</Base>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
|
||||||
|
<Cfg_1_Win32>true</Cfg_1_Win32>
|
||||||
|
<CfgParent>Cfg_1</CfgParent>
|
||||||
|
<Cfg_1>true</Cfg_1>
|
||||||
|
<Base>true</Base>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
|
||||||
|
<Cfg_2>true</Cfg_2>
|
||||||
|
<CfgParent>Base</CfgParent>
|
||||||
|
<Base>true</Base>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''">
|
||||||
|
<Cfg_2_Win64>true</Cfg_2_Win64>
|
||||||
|
<CfgParent>Cfg_2</CfgParent>
|
||||||
|
<Cfg_2>true</Cfg_2>
|
||||||
|
<Base>true</Base>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
|
||||||
|
<Cfg_2_Win32>true</Cfg_2_Win32>
|
||||||
|
<CfgParent>Cfg_2</CfgParent>
|
||||||
|
<Cfg_2>true</Cfg_2>
|
||||||
|
<Base>true</Base>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Base)'!=''">
|
||||||
|
<VerInfo_Locale>1043</VerInfo_Locale>
|
||||||
|
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
|
||||||
|
<DCC_CBuilderOutput>All</DCC_CBuilderOutput>
|
||||||
|
<GenPackage>true</GenPackage>
|
||||||
|
<GenDll>true</GenDll>
|
||||||
|
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
|
||||||
|
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
|
||||||
|
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
|
||||||
|
<DCC_E>false</DCC_E>
|
||||||
|
<DCC_N>false</DCC_N>
|
||||||
|
<DCC_S>false</DCC_S>
|
||||||
|
<DCC_F>false</DCC_F>
|
||||||
|
<DCC_K>false</DCC_K>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Base_Win64)'!=''">
|
||||||
|
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||||
|
<DCC_Define>$(DELPHIBIN64);$(DCC_Define)</DCC_Define>
|
||||||
|
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
|
||||||
|
<DCC_DcpOutput>$(DELPHIBIN64)</DCC_DcpOutput>
|
||||||
|
<DCC_DcuOutput>$(DELPHILIB64)</DCC_DcuOutput>
|
||||||
|
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Base_Win32)'!=''">
|
||||||
|
<DCC_Define>$(DELPHIBIN);$(DCC_Define)</DCC_Define>
|
||||||
|
<DCC_DcuOutput>$(DELPHILIB)</DCC_DcuOutput>
|
||||||
|
<DCC_DcpOutput>$(DELPHIBIN)</DCC_DcpOutput>
|
||||||
|
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||||
|
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
|
||||||
|
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Cfg_1)'!=''">
|
||||||
|
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
|
||||||
|
<DCC_Optimize>false</DCC_Optimize>
|
||||||
|
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
|
||||||
|
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
|
||||||
|
<DCC_RemoteDebug>true</DCC_RemoteDebug>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
|
||||||
|
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||||
|
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
|
||||||
|
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||||
|
<DCC_DUPLICATE_CTOR_DTOR>false</DCC_DUPLICATE_CTOR_DTOR>
|
||||||
|
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||||
|
<DCC_RemoteDebug>false</DCC_RemoteDebug>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Cfg_2)'!=''">
|
||||||
|
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
|
||||||
|
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
|
||||||
|
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
|
||||||
|
<DCC_DebugInformation>false</DCC_DebugInformation>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
|
||||||
|
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||||
|
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
|
||||||
|
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||||
|
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<DelphiCompile Include="$(MainSource)">
|
||||||
|
<MainSource>MainSource</MainSource>
|
||||||
|
</DelphiCompile>
|
||||||
|
<DCCReference Include="rtl.dcp"/>
|
||||||
|
<DCCReference Include="X2LogDXE2.dcp"/>
|
||||||
|
<DCCReference Include="..\X2Log.TextFormatter.Json.pas"/>
|
||||||
|
<BuildConfiguration Include="Release">
|
||||||
|
<Key>Cfg_2</Key>
|
||||||
|
<CfgParent>Base</CfgParent>
|
||||||
|
</BuildConfiguration>
|
||||||
|
<BuildConfiguration Include="Base">
|
||||||
|
<Key>Base</Key>
|
||||||
|
</BuildConfiguration>
|
||||||
|
<BuildConfiguration Include="Debug">
|
||||||
|
<Key>Cfg_1</Key>
|
||||||
|
<CfgParent>Base</CfgParent>
|
||||||
|
</BuildConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ProjectExtensions>
|
||||||
|
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
||||||
|
<Borland.ProjectType>Package</Borland.ProjectType>
|
||||||
|
<BorlandProject>
|
||||||
|
<Delphi.Personality>
|
||||||
|
<Source>
|
||||||
|
<Source Name="MainSource">X2LogJsonDXE2.dpk</Source>
|
||||||
|
</Source>
|
||||||
|
<VersionInfo>
|
||||||
|
<VersionInfo Name="IncludeVerInfo">True</VersionInfo>
|
||||||
|
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
|
||||||
|
<VersionInfo Name="MajorVer">1</VersionInfo>
|
||||||
|
<VersionInfo Name="MinorVer">0</VersionInfo>
|
||||||
|
<VersionInfo Name="Release">0</VersionInfo>
|
||||||
|
<VersionInfo Name="Build">0</VersionInfo>
|
||||||
|
<VersionInfo Name="Debug">False</VersionInfo>
|
||||||
|
<VersionInfo Name="PreRelease">False</VersionInfo>
|
||||||
|
<VersionInfo Name="Special">False</VersionInfo>
|
||||||
|
<VersionInfo Name="Private">False</VersionInfo>
|
||||||
|
<VersionInfo Name="DLL">False</VersionInfo>
|
||||||
|
<VersionInfo Name="Locale">1043</VersionInfo>
|
||||||
|
<VersionInfo Name="CodePage">1252</VersionInfo>
|
||||||
|
</VersionInfo>
|
||||||
|
<VersionInfoKeys>
|
||||||
|
<VersionInfoKeys Name="CompanyName"/>
|
||||||
|
<VersionInfoKeys Name="FileDescription"/>
|
||||||
|
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
|
||||||
|
<VersionInfoKeys Name="InternalName"/>
|
||||||
|
<VersionInfoKeys Name="LegalCopyright"/>
|
||||||
|
<VersionInfoKeys Name="LegalTrademarks"/>
|
||||||
|
<VersionInfoKeys Name="OriginalFilename"/>
|
||||||
|
<VersionInfoKeys Name="ProductName"/>
|
||||||
|
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
|
||||||
|
<VersionInfoKeys Name="Comments"/>
|
||||||
|
</VersionInfoKeys>
|
||||||
|
</Delphi.Personality>
|
||||||
|
<Deployment/>
|
||||||
|
<Platforms>
|
||||||
|
<Platform value="Win64">True</Platform>
|
||||||
|
<Platform value="Win32">True</Platform>
|
||||||
|
</Platforms>
|
||||||
|
</BorlandProject>
|
||||||
|
<ProjectFileVersion>12</ProjectFileVersion>
|
||||||
|
</ProjectExtensions>
|
||||||
|
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
|
||||||
|
<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
|
||||||
|
</Project>
|
BIN
Packages/X2LogJsonDXE2.res
Normal file
BIN
Packages/X2LogJsonDXE2.res
Normal file
Binary file not shown.
@ -25,7 +25,10 @@ uses
|
|||||||
X2Log.Util.Stream in '..\X2Log.Util.Stream.pas',
|
X2Log.Util.Stream in '..\X2Log.Util.Stream.pas',
|
||||||
X2Log.Decorator in '..\X2Log.Decorator.pas',
|
X2Log.Decorator in '..\X2Log.Decorator.pas',
|
||||||
X2Log.Observer.RollingLogFile in '..\X2Log.Observer.RollingLogFile.pas',
|
X2Log.Observer.RollingLogFile in '..\X2Log.Observer.RollingLogFile.pas',
|
||||||
X2Log.Intf.NamedPipe in '..\X2Log.Intf.NamedPipe.pas';
|
X2Log.Intf.NamedPipe in '..\X2Log.Intf.NamedPipe.pas',
|
||||||
|
X2Log.TextFormatter.Intf in '..\X2Log.TextFormatter.Intf.pas',
|
||||||
|
X2Log.TextFormatter.Default in '..\X2Log.TextFormatter.Default.pas',
|
||||||
|
X2Log.TextFormatter.Json in '..\X2Log.TextFormatter.Json.pas';
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
|
||||||
|
@ -197,6 +197,9 @@
|
|||||||
<DCCReference Include="..\X2Log.Decorator.pas"/>
|
<DCCReference Include="..\X2Log.Decorator.pas"/>
|
||||||
<DCCReference Include="..\X2Log.Observer.RollingLogFile.pas"/>
|
<DCCReference Include="..\X2Log.Observer.RollingLogFile.pas"/>
|
||||||
<DCCReference Include="..\X2Log.Intf.NamedPipe.pas"/>
|
<DCCReference Include="..\X2Log.Intf.NamedPipe.pas"/>
|
||||||
|
<DCCReference Include="..\X2Log.TextFormatter.Intf.pas"/>
|
||||||
|
<DCCReference Include="..\X2Log.TextFormatter.Default.pas"/>
|
||||||
|
<DCCReference Include="..\X2Log.TextFormatter.Json.pas"/>
|
||||||
<RcItem Include="resources\Graphic.jpg">
|
<RcItem Include="resources\Graphic.jpg">
|
||||||
<ResourceType>RCDATA</ResourceType>
|
<ResourceType>RCDATA</ResourceType>
|
||||||
<ResourceId>GraphicDetails</ResourceId>
|
<ResourceId>GraphicDetails</ResourceId>
|
||||||
|
@ -26,7 +26,7 @@ object MainForm: TMainForm
|
|||||||
Margins.Top = 8
|
Margins.Top = 8
|
||||||
Margins.Right = 8
|
Margins.Right = 8
|
||||||
Margins.Bottom = 8
|
Margins.Bottom = 8
|
||||||
ActivePage = tsNamedPipe
|
ActivePage = tsRollingFile
|
||||||
Align = alClient
|
Align = alClient
|
||||||
Images = ilsObservers
|
Images = ilsObservers
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
@ -131,6 +131,32 @@ object MainForm: TMainForm
|
|||||||
Caption = 'Absolute path'
|
Caption = 'Absolute path'
|
||||||
TabOrder = 5
|
TabOrder = 5
|
||||||
end
|
end
|
||||||
|
object pnlFileTextFormatter: TPanel
|
||||||
|
Left = 88
|
||||||
|
Top = 176
|
||||||
|
Width = 532
|
||||||
|
Height = 49
|
||||||
|
BevelOuter = bvNone
|
||||||
|
TabOrder = 6
|
||||||
|
object rbFileTextFormatterDefault: TRadioButton
|
||||||
|
Left = 0
|
||||||
|
Top = 0
|
||||||
|
Width = 113
|
||||||
|
Height = 17
|
||||||
|
Caption = 'Default'
|
||||||
|
Checked = True
|
||||||
|
TabOrder = 0
|
||||||
|
TabStop = True
|
||||||
|
end
|
||||||
|
object rbFileTextFormatterJson: TRadioButton
|
||||||
|
Left = 0
|
||||||
|
Top = 23
|
||||||
|
Width = 113
|
||||||
|
Height = 17
|
||||||
|
Caption = 'Json'
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
object tsRollingFile: TTabSheet
|
object tsRollingFile: TTabSheet
|
||||||
Caption = 'Rolling File'
|
Caption = 'Rolling File'
|
||||||
@ -212,6 +238,32 @@ object MainForm: TMainForm
|
|||||||
TabOrder = 6
|
TabOrder = 6
|
||||||
Text = '7'
|
Text = '7'
|
||||||
end
|
end
|
||||||
|
object pnlRollingFileTextFormatter: TPanel
|
||||||
|
Left = 88
|
||||||
|
Top = 224
|
||||||
|
Width = 532
|
||||||
|
Height = 49
|
||||||
|
BevelOuter = bvNone
|
||||||
|
TabOrder = 7
|
||||||
|
object rbRollingFileTextFormatterDefault: TRadioButton
|
||||||
|
Left = 0
|
||||||
|
Top = 0
|
||||||
|
Width = 113
|
||||||
|
Height = 17
|
||||||
|
Caption = 'Default'
|
||||||
|
Checked = True
|
||||||
|
TabOrder = 0
|
||||||
|
TabStop = True
|
||||||
|
end
|
||||||
|
object rbRollingFileTextFormatterJson: TRadioButton
|
||||||
|
Left = 0
|
||||||
|
Top = 23
|
||||||
|
Width = 113
|
||||||
|
Height = 17
|
||||||
|
Caption = 'Json'
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
object tsNamedPipe: TTabSheet
|
object tsNamedPipe: TTabSheet
|
||||||
Caption = 'Named Pipe'
|
Caption = 'Named Pipe'
|
||||||
@ -609,7 +661,7 @@ object MainForm: TMainForm
|
|||||||
Left = 552
|
Left = 552
|
||||||
Top = 176
|
Top = 176
|
||||||
Bitmap = {
|
Bitmap = {
|
||||||
494C01010200140060000C000C00FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
|
494C01010200140068000C000C00FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
|
||||||
0000000000003600000028000000300000000C00000001002000000000000009
|
0000000000003600000028000000300000000C00000001002000000000000009
|
||||||
0000000000000000000000000000000000000000000000000000000000000000
|
0000000000000000000000000000000000000000000000000000000000000000
|
||||||
0000000000000000000000000000000000000000000000000000000000000000
|
0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
@ -81,6 +81,12 @@ type
|
|||||||
edtRollingDays: TEdit;
|
edtRollingDays: TEdit;
|
||||||
tsStructured: TTabSheet;
|
tsStructured: TTabSheet;
|
||||||
btnValueTypes: TButton;
|
btnValueTypes: TButton;
|
||||||
|
pnlFileTextFormatter: TPanel;
|
||||||
|
rbFileTextFormatterDefault: TRadioButton;
|
||||||
|
rbFileTextFormatterJson: TRadioButton;
|
||||||
|
pnlRollingFileTextFormatter: TPanel;
|
||||||
|
rbRollingFileTextFormatterDefault: TRadioButton;
|
||||||
|
rbRollingFileTextFormatterJson: TRadioButton;
|
||||||
|
|
||||||
procedure FormCreate(Sender: TObject);
|
procedure FormCreate(Sender: TObject);
|
||||||
procedure FormDestroy(Sender: TObject);
|
procedure FormDestroy(Sender: TObject);
|
||||||
@ -136,6 +142,8 @@ uses
|
|||||||
X2Log.Observer.MonitorForm,
|
X2Log.Observer.MonitorForm,
|
||||||
X2Log.Observer.NamedPipe,
|
X2Log.Observer.NamedPipe,
|
||||||
X2Log.Observer.RollingLogFile,
|
X2Log.Observer.RollingLogFile,
|
||||||
|
X2Log.TextFormatter.Intf,
|
||||||
|
X2Log.TextFormatter.Json,
|
||||||
X2Log.Global;
|
X2Log.Global;
|
||||||
|
|
||||||
|
|
||||||
@ -339,15 +347,22 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
procedure TMainForm.btnFileStartClick(Sender: TObject);
|
procedure TMainForm.btnFileStartClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
textFormatter: IX2LogTextFormatter;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if not Assigned(FFileObserver) then
|
if not Assigned(FFileObserver) then
|
||||||
begin
|
begin
|
||||||
|
textFormatter := nil;
|
||||||
|
if rbFileTextFormatterJson.Checked then
|
||||||
|
textFormatter := TX2LogJsonTextFormatter.Create;
|
||||||
|
|
||||||
if rbProgramData.Checked then
|
if rbProgramData.Checked then
|
||||||
FFileObserver := TX2LogFileObserver.CreateInProgramData(edtFilename.Text)
|
FFileObserver := TX2LogFileObserver.CreateInProgramData(edtFilename.Text, X2LogLevelsDefault, True, textFormatter)
|
||||||
else if rbUserData.Checked then
|
else if rbUserData.Checked then
|
||||||
FFileObserver := TX2LogFileObserver.CreateInUserAppData(edtFilename.Text)
|
FFileObserver := TX2LogFileObserver.CreateInUserAppData(edtFilename.Text, X2LogLevelsDefault, True, textFormatter)
|
||||||
else
|
else
|
||||||
FFileObserver := TX2LogFileObserver.Create(edtFilename.Text);
|
FFileObserver := TX2LogFileObserver.Create(edtFilename.Text, X2LogLevelsDefault, True, textFormatter);
|
||||||
|
|
||||||
FLog.Attach(FFileObserver);
|
FLog.Attach(FFileObserver);
|
||||||
|
|
||||||
@ -371,18 +386,23 @@ end;
|
|||||||
procedure TMainForm.btnRollingFileStartClick(Sender: TObject);
|
procedure TMainForm.btnRollingFileStartClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
days: Integer;
|
days: Integer;
|
||||||
|
textFormatter: IX2LogTextFormatter;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if not Assigned(FRollingFileObserver) then
|
if not Assigned(FRollingFileObserver) then
|
||||||
begin
|
begin
|
||||||
|
textFormatter := nil;
|
||||||
|
if rbFileTextFormatterJson.Checked then
|
||||||
|
textFormatter := TX2LogJsonTextFormatter.Create;
|
||||||
|
|
||||||
days := StrToIntDef(edtRollingDays.Text, 7);
|
days := StrToIntDef(edtRollingDays.Text, 7);
|
||||||
|
|
||||||
if rbRollingProgramData.Checked then
|
if rbRollingProgramData.Checked then
|
||||||
FRollingFileObserver := TX2RollingLogFileObserver.CreateInProgramData(edtFilename.Text, days)
|
FRollingFileObserver := TX2RollingLogFileObserver.CreateInProgramData(edtFilename.Text, days, X2LogLevelsDefault, True, textFormatter)
|
||||||
else if rbRollingUserData.Checked then
|
else if rbRollingUserData.Checked then
|
||||||
FRollingFileObserver := TX2RollingLogFileObserver.CreateInUserAppData(edtFilename.Text, days)
|
FRollingFileObserver := TX2RollingLogFileObserver.CreateInUserAppData(edtFilename.Text, days, X2LogLevelsDefault, True, textFormatter)
|
||||||
else
|
else
|
||||||
FRollingFileObserver := TX2RollingLogFileObserver.Create(edtFilename.Text, days);
|
FRollingFileObserver := TX2RollingLogFileObserver.Create(edtFilename.Text, days, X2LogLevelsDefault, True, textFormatter);
|
||||||
|
|
||||||
FLog.Attach(FRollingFileObserver);
|
FLog.Attach(FRollingFileObserver);
|
||||||
|
|
||||||
|
@ -48,6 +48,12 @@ resourcestring
|
|||||||
}
|
}
|
||||||
LogFileLineDetails = '%0:s (details: %1:s)';
|
LogFileLineDetails = '%0:s (details: %1:s)';
|
||||||
|
|
||||||
|
{ The format of the log message when structured information is present
|
||||||
|
|
||||||
|
0: Message
|
||||||
|
1: Comma-separated key-value pairs
|
||||||
|
}
|
||||||
|
LogFileLineStructured = '%0:s [%1:s]';
|
||||||
|
|
||||||
{
|
{
|
||||||
X2Log.Observer.RollingLogFile
|
X2Log.Observer.RollingLogFile
|
||||||
|
@ -45,6 +45,9 @@ type
|
|||||||
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); virtual; abstract;
|
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); virtual; abstract;
|
||||||
procedure SaveToStream(AStream: TStream); virtual; abstract;
|
procedure SaveToStream(AStream: TStream); virtual; abstract;
|
||||||
|
|
||||||
|
function GetDisplayValue: string; virtual; abstract;
|
||||||
|
|
||||||
|
property DisplayValue: string read GetDisplayValue;
|
||||||
property ValueType: TX2LogValueType read FValueType;
|
property ValueType: TX2LogValueType read FValueType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -80,6 +83,7 @@ type
|
|||||||
{ IX2LogDetailsDictionary }
|
{ IX2LogDetailsDictionary }
|
||||||
function GetKeys: TEnumerable<string>;
|
function GetKeys: TEnumerable<string>;
|
||||||
function GetValueType(const Key: string): TX2LogValueType;
|
function GetValueType(const Key: string): TX2LogValueType;
|
||||||
|
function GetDisplayValue(const Key: string): string;
|
||||||
|
|
||||||
function GetStringValue(const Key: string): string;
|
function GetStringValue(const Key: string): string;
|
||||||
function GetBooleanValue(const Key: string): Boolean;
|
function GetBooleanValue(const Key: string): Boolean;
|
||||||
@ -201,6 +205,8 @@ type
|
|||||||
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
|
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
|
||||||
procedure SaveToStream(AStream: TStream); override;
|
procedure SaveToStream(AStream: TStream); override;
|
||||||
|
|
||||||
|
function GetDisplayValue: string; override;
|
||||||
|
|
||||||
property Value: string read FValue write FValue;
|
property Value: string read FValue write FValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -214,6 +220,8 @@ type
|
|||||||
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
|
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
|
||||||
procedure SaveToStream(AStream: TStream); override;
|
procedure SaveToStream(AStream: TStream); override;
|
||||||
|
|
||||||
|
function GetDisplayValue: string; override;
|
||||||
|
|
||||||
property Value: Boolean read FValue write FValue;
|
property Value: Boolean read FValue write FValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -227,6 +235,8 @@ type
|
|||||||
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
|
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
|
||||||
procedure SaveToStream(AStream: TStream); override;
|
procedure SaveToStream(AStream: TStream); override;
|
||||||
|
|
||||||
|
function GetDisplayValue: string; override;
|
||||||
|
|
||||||
property Value: Int64 read FValue write FValue;
|
property Value: Int64 read FValue write FValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -240,6 +250,8 @@ type
|
|||||||
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
|
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
|
||||||
procedure SaveToStream(AStream: TStream); override;
|
procedure SaveToStream(AStream: TStream); override;
|
||||||
|
|
||||||
|
function GetDisplayValue: string; override;
|
||||||
|
|
||||||
property Value: Extended read FValue write FValue;
|
property Value: Extended read FValue write FValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -253,6 +265,8 @@ type
|
|||||||
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
|
procedure LoadFromStream(AStream: TStream; ASize: Cardinal); override;
|
||||||
procedure SaveToStream(AStream: TStream); override;
|
procedure SaveToStream(AStream: TStream); override;
|
||||||
|
|
||||||
|
function GetDisplayValue: string; override;
|
||||||
|
|
||||||
property Value: TDateTime read FValue write FValue;
|
property Value: TDateTime read FValue write FValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -424,6 +438,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogDictionaryDetails.GetDisplayValue(const Key: string): string;
|
||||||
|
begin
|
||||||
|
Result := FValues[Key].DisplayValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TX2LogDictionaryDetails.GetStringValue(const Key: string): string;
|
function TX2LogDictionaryDetails.GetStringValue(const Key: string): string;
|
||||||
begin
|
begin
|
||||||
Result := (FValues[Key] as TX2LogDictionaryStringValue).Value;
|
Result := (FValues[Key] as TX2LogDictionaryStringValue).Value;
|
||||||
@ -768,6 +788,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogDictionaryStringValue.GetDisplayValue: string;
|
||||||
|
begin
|
||||||
|
Result := Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TX2LogDictionaryBooleanValue }
|
{ TX2LogDictionaryBooleanValue }
|
||||||
constructor TX2LogDictionaryBooleanValue.Create(AValue: Boolean);
|
constructor TX2LogDictionaryBooleanValue.Create(AValue: Boolean);
|
||||||
begin
|
begin
|
||||||
@ -792,6 +818,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogDictionaryBooleanValue.GetDisplayValue: string;
|
||||||
|
begin
|
||||||
|
Result := BoolToStr(Value, True);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TX2LogDictionaryIntValue }
|
{ TX2LogDictionaryIntValue }
|
||||||
constructor TX2LogDictionaryIntValue.Create(AValue: Int64);
|
constructor TX2LogDictionaryIntValue.Create(AValue: Int64);
|
||||||
begin
|
begin
|
||||||
@ -816,6 +848,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogDictionaryIntValue.GetDisplayValue: string;
|
||||||
|
begin
|
||||||
|
Result := IntToStr(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TX2LogDictionaryFloatValue }
|
{ TX2LogDictionaryFloatValue }
|
||||||
constructor TX2LogDictionaryFloatValue.Create(AValue: Extended);
|
constructor TX2LogDictionaryFloatValue.Create(AValue: Extended);
|
||||||
begin
|
begin
|
||||||
@ -840,6 +878,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogDictionaryFloatValue.GetDisplayValue: string;
|
||||||
|
begin
|
||||||
|
Result := FormatFloat('0.########', Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TX2LogDictionaryDateTimeValue }
|
{ TX2LogDictionaryDateTimeValue }
|
||||||
constructor TX2LogDictionaryDateTimeValue.Create(AValue: TDateTime);
|
constructor TX2LogDictionaryDateTimeValue.Create(AValue: TDateTime);
|
||||||
begin
|
begin
|
||||||
@ -864,6 +908,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogDictionaryDateTimeValue.GetDisplayValue: string;
|
||||||
|
begin
|
||||||
|
Result := DateTimeToStr(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
TX2LogDetailsRegistry.Register(StringDetailsSerializerIID, TX2LogStringDetailsSerializer.Create);
|
TX2LogDetailsRegistry.Register(StringDetailsSerializerIID, TX2LogStringDetailsSerializer.Create);
|
||||||
TX2LogDetailsRegistry.Register(DictionaryDetailsSerializerIID, TX2LogDictionaryDetailsSerializer.Create);
|
TX2LogDetailsRegistry.Register(DictionaryDetailsSerializerIID, TX2LogDictionaryDetailsSerializer.Create);
|
||||||
|
@ -25,6 +25,7 @@ type
|
|||||||
function GetKeys: TEnumerable<string>;
|
function GetKeys: TEnumerable<string>;
|
||||||
function GetValueType(const Key: string): TX2LogValueType;
|
function GetValueType(const Key: string): TX2LogValueType;
|
||||||
|
|
||||||
|
function GetDisplayValue(const Key: string): string;
|
||||||
function GetStringValue(const Key: string): string;
|
function GetStringValue(const Key: string): string;
|
||||||
function GetBooleanValue(const Key: string): Boolean;
|
function GetBooleanValue(const Key: string): Boolean;
|
||||||
function GetIntValue(const Key: string): Int64;
|
function GetIntValue(const Key: string): Int64;
|
||||||
@ -33,6 +34,7 @@ type
|
|||||||
|
|
||||||
property Keys: TEnumerable<string> read GetKeys;
|
property Keys: TEnumerable<string> read GetKeys;
|
||||||
property ValueType[const Key: string]: TX2LogValueType read GetValueType;
|
property ValueType[const Key: string]: TX2LogValueType read GetValueType;
|
||||||
|
property DisplayValue[const Key: string]: string read GetDisplayValue;
|
||||||
|
|
||||||
property StringValue[const Key: string]: string read GetStringValue;
|
property StringValue[const Key: string]: string read GetStringValue;
|
||||||
property BooleanValue[const Key: string]: Boolean read GetBooleanValue;
|
property BooleanValue[const Key: string]: Boolean read GetBooleanValue;
|
||||||
|
@ -8,7 +8,8 @@ uses
|
|||||||
|
|
||||||
X2Log.Intf,
|
X2Log.Intf,
|
||||||
X2Log.Observer.Custom,
|
X2Log.Observer.Custom,
|
||||||
X2Log.Observer.CustomThreaded;
|
X2Log.Observer.CustomThreaded,
|
||||||
|
X2Log.TextFormatter.Intf;
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -16,15 +17,17 @@ type
|
|||||||
private
|
private
|
||||||
FOutputFileName: string;
|
FOutputFileName: string;
|
||||||
FLogDetails: Boolean;
|
FLogDetails: Boolean;
|
||||||
|
FTextFormatter: IX2LogTextFormatter;
|
||||||
protected
|
protected
|
||||||
|
function GetTextFormatter: IX2LogTextFormatter; virtual;
|
||||||
function CreateWorkerThread: TX2LogObserverWorkerThread; override;
|
function CreateWorkerThread: TX2LogObserverWorkerThread; override;
|
||||||
|
|
||||||
property OutputFileName: string read FOutputFileName;
|
property OutputFileName: string read FOutputFileName;
|
||||||
property LogDetails: Boolean read FLogDetails;
|
property LogDetails: Boolean read FLogDetails;
|
||||||
public
|
public
|
||||||
constructor Create(const AOutputFileName: string; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True);
|
constructor Create(const AOutputFileName: string; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True; ATextFormatter: IX2LogTextFormatter = nil);
|
||||||
constructor CreateInProgramData(const AOutputFileName: string; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True);
|
constructor CreateInProgramData(const AOutputFileName: string; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True; ATextFormatter: IX2LogTextFormatter = nil);
|
||||||
constructor CreateInUserAppData(const AOutputFileName: string; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True);
|
constructor CreateInUserAppData(const AOutputFileName: string; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True; ATextFormatter: IX2LogTextFormatter = nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -32,14 +35,16 @@ type
|
|||||||
private
|
private
|
||||||
FOutputFileName: string;
|
FOutputFileName: string;
|
||||||
FLogDetails: Boolean;
|
FLogDetails: Boolean;
|
||||||
|
FTextFormatter: IX2LogTextFormatter;
|
||||||
protected
|
protected
|
||||||
function GetFileName(AEntry: TX2LogQueueEntry): string; virtual;
|
function GetFileName(AEntry: TX2LogQueueEntry): string; virtual;
|
||||||
procedure ProcessEntry(AEntry: TX2LogQueueEntry); override;
|
procedure ProcessEntry(AEntry: TX2LogQueueEntry); override;
|
||||||
|
|
||||||
property OutputFileName: string read FOutputFileName;
|
property OutputFileName: string read FOutputFileName;
|
||||||
property LogDetails: Boolean read FLogDetails;
|
property LogDetails: Boolean read FLogDetails;
|
||||||
|
property TextFormatter: IX2LogTextFormatter read FTextFormatter;
|
||||||
public
|
public
|
||||||
constructor Create(const AOutputFileName: string; ALogDetails: Boolean = True);
|
constructor Create(const AOutputFileName: string; ATextFormatter: IX2LogTextFormatter; ALogDetails: Boolean = True);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -51,21 +56,42 @@ uses
|
|||||||
Winapi.SHFolder,
|
Winapi.SHFolder,
|
||||||
Winapi.Windows,
|
Winapi.Windows,
|
||||||
|
|
||||||
X2Log.Constants;
|
X2Log.Constants,
|
||||||
|
X2Log.TextFormatter.Default;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
TX2LogFileTextFormatterHelper = class(TInterfacedObject, IX2LogTextFormatterHelper)
|
||||||
|
private
|
||||||
|
FEntry: TX2LogQueueEntry;
|
||||||
|
FLogFileName: string;
|
||||||
|
FLogDetails: Boolean;
|
||||||
|
protected
|
||||||
|
{ IX2LogTextFormatterHelper }
|
||||||
|
function GetDetailsFilename: string;
|
||||||
|
|
||||||
|
property Entry: TX2LogQueueEntry read FEntry;
|
||||||
|
property LogFileName: string read FLogFileName;
|
||||||
|
property LogDetails: Boolean read FLogDetails;
|
||||||
|
public
|
||||||
|
constructor Create(AEntry: TX2LogQueueEntry; const ALogFileName: string; ALogDetails: Boolean);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TX2LogFileObserver }
|
{ TX2LogFileObserver }
|
||||||
constructor TX2LogFileObserver.Create(const AOutputFileName: string; ALogLevels: TX2LogLevels; ALogDetails: Boolean);
|
constructor TX2LogFileObserver.Create(const AOutputFileName: string; ALogLevels: TX2LogLevels; ALogDetails: Boolean; ATextFormatter: IX2LogTextFormatter);
|
||||||
begin
|
begin
|
||||||
FOutputFileName := AOutputFileName;
|
FOutputFileName := AOutputFileName;
|
||||||
FLogDetails := ALogDetails;
|
FLogDetails := ALogDetails;
|
||||||
|
FTextFormatter := ATextFormatter;
|
||||||
|
if not Assigned(FTextFormatter) then
|
||||||
|
FTextFormatter := TX2LogDefaultTextFormatter.Create;
|
||||||
|
|
||||||
inherited Create(ALogLevels);
|
inherited Create(ALogLevels);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
constructor TX2LogFileObserver.CreateInProgramData(const AOutputFileName: string; ALogLevels: TX2LogLevels; ALogDetails: Boolean);
|
constructor TX2LogFileObserver.CreateInProgramData(const AOutputFileName: string; ALogLevels: TX2LogLevels; ALogDetails: Boolean; ATextFormatter: IX2LogTextFormatter);
|
||||||
var
|
var
|
||||||
path: PWideChar;
|
path: PWideChar;
|
||||||
|
|
||||||
@ -73,14 +99,14 @@ begin
|
|||||||
GetMem(path, MAX_PATH);
|
GetMem(path, MAX_PATH);
|
||||||
try
|
try
|
||||||
OleCheck(SHGetFolderPath(0, CSIDL_COMMON_APPDATA, 0, SHGFP_TYPE_CURRENT, path));
|
OleCheck(SHGetFolderPath(0, CSIDL_COMMON_APPDATA, 0, SHGFP_TYPE_CURRENT, path));
|
||||||
Create(IncludeTrailingPathDelimiter(path) + AOutputFileName, ALogLevels, ALogDetails);
|
Create(IncludeTrailingPathDelimiter(path) + AOutputFileName, ALogLevels, ALogDetails, ATextFormatter);
|
||||||
finally
|
finally
|
||||||
FreeMem(path);
|
FreeMem(path);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
constructor TX2LogFileObserver.CreateInUserAppData(const AOutputFileName: string; ALogLevels: TX2LogLevels; ALogDetails: Boolean);
|
constructor TX2LogFileObserver.CreateInUserAppData(const AOutputFileName: string; ALogLevels: TX2LogLevels; ALogDetails: Boolean; ATextFormatter: IX2LogTextFormatter);
|
||||||
var
|
var
|
||||||
path: PWideChar;
|
path: PWideChar;
|
||||||
|
|
||||||
@ -88,7 +114,7 @@ begin
|
|||||||
GetMem(path, MAX_PATH);
|
GetMem(path, MAX_PATH);
|
||||||
try
|
try
|
||||||
OleCheck(SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, path));
|
OleCheck(SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, path));
|
||||||
Create(IncludeTrailingPathDelimiter(path) + AOutputFileName, ALogLevels, ALogDetails);
|
Create(IncludeTrailingPathDelimiter(path) + AOutputFileName, ALogLevels, ALogDetails, ATextFormatter);
|
||||||
finally
|
finally
|
||||||
FreeMem(path);
|
FreeMem(path);
|
||||||
end;
|
end;
|
||||||
@ -97,15 +123,22 @@ end;
|
|||||||
|
|
||||||
function TX2LogFileObserver.CreateWorkerThread: TX2LogObserverWorkerThread;
|
function TX2LogFileObserver.CreateWorkerThread: TX2LogObserverWorkerThread;
|
||||||
begin
|
begin
|
||||||
Result := TX2LogFileWorkerThread.Create(OutputFileName, LogDetails);
|
Result := TX2LogFileWorkerThread.Create(OutputFileName, GetTextFormatter, LogDetails);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogFileObserver.GetTextFormatter: IX2LogTextFormatter;
|
||||||
|
begin
|
||||||
|
Result := FTextFormatter;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TX2LogFileWorkerThread }
|
{ TX2LogFileWorkerThread }
|
||||||
constructor TX2LogFileWorkerThread.Create(const AOutputFileName: string; ALogDetails: Boolean);
|
constructor TX2LogFileWorkerThread.Create(const AOutputFileName: string; ATextFormatter: IX2LogTextFormatter; ALogDetails: Boolean);
|
||||||
begin
|
begin
|
||||||
FOutputFileName := AOutputFileName;
|
FOutputFileName := AOutputFileName;
|
||||||
FLogDetails := ALogDetails;
|
FLogDetails := ALogDetails;
|
||||||
|
FTextFormatter := ATextFormatter;
|
||||||
|
|
||||||
inherited Create;
|
inherited Create;
|
||||||
end;
|
end;
|
||||||
@ -114,29 +147,62 @@ end;
|
|||||||
procedure TX2LogFileWorkerThread.ProcessEntry(AEntry: TX2LogQueueEntry);
|
procedure TX2LogFileWorkerThread.ProcessEntry(AEntry: TX2LogQueueEntry);
|
||||||
var
|
var
|
||||||
fileName: string;
|
fileName: string;
|
||||||
baseReportFileName: string;
|
line: string;
|
||||||
errorMsg: string;
|
|
||||||
detailsExtension: string;
|
|
||||||
detailsFile: THandle;
|
|
||||||
detailsFileStream: THandleStream;
|
|
||||||
detailsFileName: string;
|
|
||||||
detailsNumber: Integer;
|
|
||||||
writer: TStreamWriter;
|
writer: TStreamWriter;
|
||||||
logDetailsStreamable: IX2LogDetailsStreamable;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
fileName := GetFileName(AEntry);
|
fileName := GetFileName(AEntry);
|
||||||
ForceDirectories(ExtractFilePath(fileName));
|
ForceDirectories(ExtractFilePath(fileName));
|
||||||
|
|
||||||
if Length(AEntry.Category) > 0 then
|
line := TextFormatter.GetText(TX2LogFileTextFormatterHelper.Create(AEntry, fileName, LogDetails),
|
||||||
errorMsg := Format(GetLogResourceString(@LogFileLineCategory), [AEntry.Message, AEntry.Category])
|
AEntry.Level, AEntry.DateTime, AEntry.Message, AEntry.Category, AEntry.Details);
|
||||||
else
|
|
||||||
errorMsg := Format(GetLogResourceString(@LogFileLineNoCategory), [AEntry.Message]);
|
|
||||||
|
|
||||||
if LogDetails and Supports(AEntry.Details, IX2LogDetailsStreamable, logDetailsStreamable) then
|
{ Append line to log file }
|
||||||
|
writer := TFile.AppendText(fileName);
|
||||||
|
try
|
||||||
|
writer.WriteLine(line);
|
||||||
|
finally
|
||||||
|
FreeAndNil(writer);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogFileWorkerThread.GetFileName(AEntry: TX2LogQueueEntry): string;
|
||||||
|
begin
|
||||||
|
Result := FOutputFileName;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TX2LogFileTextFormatterHelper }
|
||||||
|
constructor TX2LogFileTextFormatterHelper.Create(AEntry: TX2LogQueueEntry; const ALogFileName: string; ALogDetails: Boolean);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
|
||||||
|
FEntry := AEntry;
|
||||||
|
FLogFileName := ALogFileName;
|
||||||
|
FLogDetails := ALogDetails;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogFileTextFormatterHelper.GetDetailsFilename: string;
|
||||||
|
var
|
||||||
|
logDetailsStreamable: IX2LogDetailsStreamable;
|
||||||
|
baseReportFileName: string;
|
||||||
|
detailsExtension: string;
|
||||||
|
detailsFile: THandle;
|
||||||
|
detailsFileStream: THandleStream;
|
||||||
|
detailsFileName: string;
|
||||||
|
detailsNumber: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
if not LogDetails then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
if Supports(Entry.Details, IX2LogDetailsStreamable, logDetailsStreamable) then
|
||||||
begin
|
begin
|
||||||
detailsExtension := ExtractFileExt(fileName);
|
detailsExtension := ExtractFileExt(LogFileName);
|
||||||
baseReportFileName := ChangeFileExt(fileName, '_' + FormatDateTime(GetLogResourceString(@LogFileNameDateFormat), AEntry.DateTime));
|
baseReportFileName := ChangeFileExt(LogFileName, '_' + FormatDateTime(GetLogResourceString(@LogFileNameDateFormat), Entry.DateTime));
|
||||||
detailsFileName := baseReportFileName + detailsExtension;
|
detailsFileName := baseReportFileName + detailsExtension;
|
||||||
detailsNumber := 0;
|
detailsNumber := 0;
|
||||||
|
|
||||||
@ -172,29 +238,12 @@ begin
|
|||||||
CloseHandle(detailsFile);
|
CloseHandle(detailsFile);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// ErrorLogs.Add(reportFileName);
|
Result := detailsFileName;
|
||||||
|
|
||||||
errorMsg := Format(GetLogResourceString(@LogFileLineDetails), [errorMsg, ExtractFileName(detailsFileName)]);
|
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
until False;
|
until False;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Append line to log file }
|
|
||||||
writer := TFile.AppendText(fileName);
|
|
||||||
try
|
|
||||||
writer.WriteLine('[' + FormatDateTime(GetLogResourceString(@LogFileLineDateFormat), AEntry.DateTime) + '] ' +
|
|
||||||
GetLogLevelText(AEntry.Level) + ': ' + errorMsg);
|
|
||||||
finally
|
|
||||||
FreeAndNil(writer);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function TX2LogFileWorkerThread.GetFileName(AEntry: TX2LogQueueEntry): string;
|
|
||||||
begin
|
|
||||||
Result := FOutputFileName;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -284,7 +284,7 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm
|
|||||||
Left = 448
|
Left = 448
|
||||||
Top = 48
|
Top = 48
|
||||||
Bitmap = {
|
Bitmap = {
|
||||||
494C01010A004000000110001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
|
494C01010A004000040110001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
|
||||||
0000000000003600000028000000400000003000000001002000000000000030
|
0000000000003600000028000000400000003000000001002000000000000030
|
||||||
0000000000000000000000000000000000000000000000000000000000000000
|
0000000000000000000000000000000000000000000000000000000000000000
|
||||||
0000000000000000000000000000000000000000000000000000000000000000
|
0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
@ -745,25 +745,12 @@ end;
|
|||||||
procedure TX2LogObserverMonitorForm.SetDictionaryDetails(ADetails: IX2LogDetailsDictionary);
|
procedure TX2LogObserverMonitorForm.SetDictionaryDetails(ADetails: IX2LogDetailsDictionary);
|
||||||
var
|
var
|
||||||
key: string;
|
key: string;
|
||||||
displayValue: string;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
vleDetailsDictionary.Strings.Clear;
|
vleDetailsDictionary.Strings.Clear;
|
||||||
|
|
||||||
for key in ADetails.Keys do
|
for key in ADetails.Keys do
|
||||||
begin
|
vleDetailsDictionary.Values[key] := ADetails.DisplayValue[key];
|
||||||
displayValue := '<error>';
|
|
||||||
|
|
||||||
case ADetails.ValueType[key] of
|
|
||||||
StringValue: displayValue := ADetails.StringValue[key];
|
|
||||||
BooleanValue: displayValue := BoolToStr(ADetails.BooleanValue[key], True);
|
|
||||||
IntValue: displayValue := IntToStr(ADetails.IntValue[key]);
|
|
||||||
FloatValue: displayValue := FormatFloat('0.########', ADetails.FloatValue[key]);
|
|
||||||
DateTimeValue: displayValue := DateTimeToStr(ADetails.DateTimeValue[key]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
vleDetailsDictionary.Values[key] := displayValue;
|
|
||||||
end;
|
|
||||||
|
|
||||||
FCopyHandler := CopyDictionaryDetails;
|
FCopyHandler := CopyDictionaryDetails;
|
||||||
SetVisibleDetails(vleDetailsDictionary);
|
SetVisibleDetails(vleDetailsDictionary);
|
||||||
|
@ -6,7 +6,8 @@ uses
|
|||||||
|
|
||||||
X2Log.Intf,
|
X2Log.Intf,
|
||||||
X2Log.Observer.CustomThreaded,
|
X2Log.Observer.CustomThreaded,
|
||||||
X2Log.Observer.LogFile;
|
X2Log.Observer.LogFile,
|
||||||
|
X2Log.TextFormatter.Intf;
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -22,9 +23,9 @@ type
|
|||||||
|
|
||||||
property Days: Integer read FDays;
|
property Days: Integer read FDays;
|
||||||
public
|
public
|
||||||
constructor Create(const AFileName: string; ADays: Integer = X2LogDefaultDays; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True);
|
constructor Create(const AFileName: string; ADays: Integer = X2LogDefaultDays; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True; ATextFormatter: IX2LogTextFormatter = nil);
|
||||||
constructor CreateInProgramData(const AFileName: string; ADays: Integer = X2LogDefaultDays; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True);
|
constructor CreateInProgramData(const AFileName: string; ADays: Integer = X2LogDefaultDays; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True; ATextFormatter: IX2LogTextFormatter = nil);
|
||||||
constructor CreateInUserAppData(const AFileName: string; ADays: Integer = X2LogDefaultDays; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True);
|
constructor CreateInUserAppData(const AFileName: string; ADays: Integer = X2LogDefaultDays; ALogLevels: TX2LogLevels = X2LogLevelsDefault; ALogDetails: Boolean = True; ATextFormatter: IX2LogTextFormatter = nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ type
|
|||||||
property Days: Integer read FDays;
|
property Days: Integer read FDays;
|
||||||
property LastCleanupDate: TDateTime read FLastCleanupDate write FLastCleanupDate;
|
property LastCleanupDate: TDateTime read FLastCleanupDate write FLastCleanupDate;
|
||||||
public
|
public
|
||||||
constructor Create(const AFileName: string; ADays: Integer; ALogDetails: Boolean = True);
|
constructor Create(const AFileName: string; ADays: Integer; ATextFormatter: IX2LogTextFormatter; ALogDetails: Boolean = True);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -59,44 +60,44 @@ uses
|
|||||||
|
|
||||||
|
|
||||||
{ TX2RollingLogFileObserver }
|
{ TX2RollingLogFileObserver }
|
||||||
constructor TX2RollingLogFileObserver.Create(const AFileName: string; ADays: Integer; ALogLevels: TX2LogLevels; ALogDetails: Boolean);
|
constructor TX2RollingLogFileObserver.Create(const AFileName: string; ADays: Integer; ALogLevels: TX2LogLevels; ALogDetails: Boolean; ATextFormatter: IX2LogTextFormatter);
|
||||||
begin
|
begin
|
||||||
FDays := ADays;
|
FDays := ADays;
|
||||||
|
|
||||||
inherited Create(AFileName, ALogLevels, ALogDetails);
|
inherited Create(AFileName, ALogLevels, ALogDetails, ATextFormatter);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
constructor TX2RollingLogFileObserver.CreateInProgramData(const AFileName: string; ADays: Integer; ALogLevels: TX2LogLevels; ALogDetails: Boolean);
|
constructor TX2RollingLogFileObserver.CreateInProgramData(const AFileName: string; ADays: Integer; ALogLevels: TX2LogLevels; ALogDetails: Boolean; ATextFormatter: IX2LogTextFormatter);
|
||||||
begin
|
begin
|
||||||
FDays := ADays;
|
FDays := ADays;
|
||||||
|
|
||||||
inherited CreateInProgramData(AFileName, ALogLevels, ALogDetails);
|
inherited CreateInProgramData(AFileName, ALogLevels, ALogDetails, ATextFormatter);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
constructor TX2RollingLogFileObserver.CreateInUserAppData(const AFileName: string; ADays: Integer; ALogLevels: TX2LogLevels; ALogDetails: Boolean);
|
constructor TX2RollingLogFileObserver.CreateInUserAppData(const AFileName: string; ADays: Integer; ALogLevels: TX2LogLevels; ALogDetails: Boolean; ATextFormatter: IX2LogTextFormatter);
|
||||||
begin
|
begin
|
||||||
FDays := ADays;
|
FDays := ADays;
|
||||||
|
|
||||||
inherited CreateInUserAppData(AFileName, ALogLevels, ALogDetails);
|
inherited CreateInUserAppData(AFileName, ALogLevels, ALogDetails, ATextFormatter);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TX2RollingLogFileObserver.CreateWorkerThread: TX2LogObserverWorkerThread;
|
function TX2RollingLogFileObserver.CreateWorkerThread: TX2LogObserverWorkerThread;
|
||||||
begin
|
begin
|
||||||
Result := TX2RollingLogFileWorkerThread.Create(OutputFileName, Days, LogDetails);
|
Result := TX2RollingLogFileWorkerThread.Create(OutputFileName, Days, GetTextFormatter, LogDetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TX2RollingLogFileWorkerThread }
|
{ TX2RollingLogFileWorkerThread }
|
||||||
constructor TX2RollingLogFileWorkerThread.Create(const AFileName: string; ADays: Integer; ALogDetails: Boolean);
|
constructor TX2RollingLogFileWorkerThread.Create(const AFileName: string; ADays: Integer; ATextFormatter: IX2LogTextFormatter; ALogDetails: Boolean);
|
||||||
begin
|
begin
|
||||||
FDays := ADays;
|
FDays := ADays;
|
||||||
FFormatSettings := TFormatSettings.Create;
|
FFormatSettings := TFormatSettings.Create;
|
||||||
FDateFormat := GetLogResourceString(@RollingLogFileDateFormat);
|
FDateFormat := GetLogResourceString(@RollingLogFileDateFormat);
|
||||||
|
|
||||||
inherited Create(AFileName, ALogDetails);
|
inherited Create(AFileName, ATextFormatter, ALogDetails);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
78
X2Log.TextFormatter.Default.pas
Normal file
78
X2Log.TextFormatter.Default.pas
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
unit X2Log.TextFormatter.Default;
|
||||||
|
|
||||||
|
interface
|
||||||
|
uses
|
||||||
|
X2Log.Details.Intf,
|
||||||
|
X2Log.Intf,
|
||||||
|
X2Log.TextFormatter.Intf;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
TX2LogDefaultTextFormatter = class(TInterfacedObject, IX2LogTextFormatter)
|
||||||
|
protected
|
||||||
|
function GetText(AHelper: IX2LogTextFormatterHelper; ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; const ACategory: string; ADetails: IX2LogDetails): string;
|
||||||
|
|
||||||
|
function GetDictionaryDisplayValues(ADetails: IX2LogDetailsDictionary): string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
uses
|
||||||
|
System.SysUtils,
|
||||||
|
|
||||||
|
X2Log.Constants;
|
||||||
|
|
||||||
|
|
||||||
|
{ TX2LogDefaultTextFormatter }
|
||||||
|
function TX2LogDefaultTextFormatter.GetText(AHelper: IX2LogTextFormatterHelper; ALevel: TX2LogLevel; ADateTime: TDateTime;
|
||||||
|
const AMessage, ACategory: string; ADetails: IX2LogDetails): string;
|
||||||
|
var
|
||||||
|
line: string;
|
||||||
|
dictionaryDetails: IX2LogDetailsDictionary;
|
||||||
|
detailsFileName: string;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Length(ACategory) > 0 then
|
||||||
|
line := Format(GetLogResourceString(@LogFileLineCategory), [AMessage, ACategory])
|
||||||
|
else
|
||||||
|
line := Format(GetLogResourceString(@LogFileLineNoCategory), [AMessage]);
|
||||||
|
|
||||||
|
if Supports(ADetails, IX2LogDetailsDictionary, dictionaryDetails) then
|
||||||
|
begin
|
||||||
|
line := Format(GetLogResourceString(@LogFileLineStructured), [line, GetDictionaryDisplayValues(dictionaryDetails)]);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
detailsFileName := AHelper.GetDetailsFilename;
|
||||||
|
if Length(detailsFileName) > 0 then
|
||||||
|
line := Format(GetLogResourceString(@LogFileLineDetails), [line, ExtractFileName(detailsFileName)]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := '[' + FormatDateTime(GetLogResourceString(@LogFileLineDateFormat), ADateTime) + '] ' +
|
||||||
|
GetLogLevelText(ALevel) + ': ' + line;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX2LogDefaultTextFormatter.GetDictionaryDisplayValues(ADetails: IX2LogDetailsDictionary): string;
|
||||||
|
var
|
||||||
|
displayValues: TStringBuilder;
|
||||||
|
key: string;
|
||||||
|
|
||||||
|
begin
|
||||||
|
displayValues := TStringBuilder.Create;
|
||||||
|
try
|
||||||
|
for key in ADetails.Keys do
|
||||||
|
begin
|
||||||
|
if displayValues.Length > 0 then
|
||||||
|
displayValues.Append(', ');
|
||||||
|
|
||||||
|
displayValues.Append(key).Append(': ').Append(ADetails.DisplayValue[key]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := displayValues.ToString;
|
||||||
|
finally
|
||||||
|
FreeAndNil(displayValues);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
20
X2Log.TextFormatter.Intf.pas
Normal file
20
X2Log.TextFormatter.Intf.pas
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
unit X2Log.TextFormatter.Intf;
|
||||||
|
|
||||||
|
interface
|
||||||
|
uses
|
||||||
|
X2Log.Intf;
|
||||||
|
|
||||||
|
type
|
||||||
|
IX2LogTextFormatterHelper = interface
|
||||||
|
['{D1A1DAD5-0F96-491F-8BD5-0B9D0BE87C32}']
|
||||||
|
function GetDetailsFilename: string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
IX2LogTextFormatter = interface
|
||||||
|
['{C49BE49D-8563-4097-A2B7-0869F27F5EDD}']
|
||||||
|
function GetText(AHelper: IX2LogTextFormatterHelper; ALevel: TX2LogLevel; ADateTime: TDateTime; const AMessage: string; const ACategory: string; ADetails: IX2LogDetails): string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
end.
|
127
X2Log.TextFormatter.Json.pas
Normal file
127
X2Log.TextFormatter.Json.pas
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
unit X2Log.TextFormatter.Json;
|
||||||
|
|
||||||
|
interface
|
||||||
|
uses
|
||||||
|
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.
|
Loading…
Reference in New Issue
Block a user