From 5353d1bc60b4cfe5f424a1ac13130ebaf3c57499 Mon Sep 17 00:00:00 2001 From: Jens Fudickar Date: Sun, 2 Jun 2024 15:19:26 +0200 Subject: [PATCH 1/2] StringListAppender added --- LoggerPro.StringlistAppender.pas | 121 ++++++++++++++++++ .../05_vcl_appenders/VCLAppendersFormU.dfm | 29 ++++- .../05_vcl_appenders/VCLAppendersFormU.pas | 7 +- 3 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 LoggerPro.StringlistAppender.pas diff --git a/LoggerPro.StringlistAppender.pas b/LoggerPro.StringlistAppender.pas new file mode 100644 index 0000000..0c54064 --- /dev/null +++ b/LoggerPro.StringlistAppender.pas @@ -0,0 +1,121 @@ +// *************************************************************************** } +// +// LoggerPro +// +// Copyright (c) 2010-2024 Daniele Teti +// +// https://github.com/danieleteti/loggerpro +// +// *************************************************************************** +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// *************************************************************************** + +unit LoggerPro.StringListAppender; + +interface + +uses + LoggerPro, + System.Classes, + System.SyncObjs; + +type + { @abstract(Appends formatted @link(TLogItem) to a TMemo in a VCL application) } + TStringListLogAppender = class(TLoggerProAppenderBase) + private + fStringList: TStrings; + FMaxLogLines: Word; + FClearOnStartup: Boolean; + FCriticalSection: TCriticalSection; + public + constructor Create(aStringList: TStrings; aMaxLogLines: Word = 100; + aClearOnStartup: Boolean = False; aLogItemRenderer: ILogItemRenderer = + nil); reintroduce; + destructor Destroy; override; + procedure Setup; override; + procedure TearDown; override; + procedure WriteLog(const aLogItem: TLogItem); override; + end; + +implementation + +uses + System.SysUtils, + Winapi.Windows, + Winapi.Messages; + +{ TStringListLogAppender } + +constructor TStringListLogAppender.Create(aStringList: TStrings; aMaxLogLines: + Word = 100; aClearOnStartup: Boolean = False; aLogItemRenderer: + ILogItemRenderer = nil); +begin + inherited Create(aLogItemRenderer); + fStringList := aStringList; + FMaxLogLines := aMaxLogLines; + FClearOnStartup := aClearOnStartup; + FCriticalSection := TCriticalSection.Create(); +end; + +destructor TStringListLogAppender.Destroy; +begin + FCriticalSection.Free; + inherited Destroy; +end; + +procedure TStringListLogAppender.Setup; +begin + inherited; + if FClearOnStartup then + begin + TThread.Synchronize(nil, + procedure + begin + fStringList.Clear; + end); + end; +end; + +procedure TStringListLogAppender.TearDown; +begin + // do nothing +end; + +procedure TStringListLogAppender.WriteLog(const aLogItem: TLogItem); +var + lText: string; +begin + lText := FormatLog(aLogItem); + TThread.Queue(nil, + procedure + begin + FCriticalSection.Acquire; + try + fStringList.BeginUpdate; + try + if FMaxLogLines > 0 then + while fStringList.Count > FMaxLogLines do + fStringList.Delete(0); + fStringList.Add(lText) + finally + fStringList.EndUpdate; + end; + finally + FCriticalSection.Release; + end; + end); +end; + +end. diff --git a/samples/05_vcl_appenders/VCLAppendersFormU.dfm b/samples/05_vcl_appenders/VCLAppendersFormU.dfm index 2ccc2a6..7d25a2f 100644 --- a/samples/05_vcl_appenders/VCLAppendersFormU.dfm +++ b/samples/05_vcl_appenders/VCLAppendersFormU.dfm @@ -66,7 +66,7 @@ object MainForm: TMainForm Top = 134 Width = 818 Height = 393 - ActivePage = tsListViewAppender + ActivePage = tsStringListAppender Anchors = [akLeft, akTop, akRight, akBottom] TabOrder = 5 ExplicitWidth = 814 @@ -98,14 +98,35 @@ object MainForm: TMainForm ParentFont = False TabOrder = 0 ViewStyle = vsReport - ExplicitWidth = 806 - ExplicitHeight = 364 end end object tsMemoAppender: TTabSheet Caption = 'Memo Appender DEMO' ImageIndex = 1 - object Memo1: TMemo + object MemoAppenderMemo: TMemo + Left = 0 + Top = 0 + Width = 810 + Height = 365 + Align = alClient + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Courier New' + Font.Style = [] + ParentFont = False + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 0 + WordWrap = False + ExplicitWidth = 806 + ExplicitHeight = 364 + end + end + object tsStringListAppender: TTabSheet + Caption = 'Stringlist Appender DEMO' + ImageIndex = 2 + object StringListAppenderMemo: TMemo Left = 0 Top = 0 Width = 810 diff --git a/samples/05_vcl_appenders/VCLAppendersFormU.pas b/samples/05_vcl_appenders/VCLAppendersFormU.pas index a1b45e7..888780a 100644 --- a/samples/05_vcl_appenders/VCLAppendersFormU.pas +++ b/samples/05_vcl_appenders/VCLAppendersFormU.pas @@ -28,9 +28,11 @@ TMainForm = class(TForm) PageControl1: TPageControl; tsListViewAppender: TTabSheet; tsMemoAppender: TTabSheet; - Memo1: TMemo; + MemoAppenderMemo: TMemo; ListView1: TListView; Button6: TButton; + tsStringListAppender: TTabSheet; + StringListAppenderMemo: TMemo; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); @@ -51,6 +53,7 @@ TMainForm = class(TForm) implementation uses + LoggerPro.StringListAppender, LoggerPro.VCLMemoAppender, LoggerPro.VCLListViewAppender; @@ -115,7 +118,7 @@ procedure TMainForm.Button6Click(Sender: TObject); procedure TMainForm.FormCreate(Sender: TObject); begin // Let's create the local loggers for this form - FLog := BuildLogWriter([TVCLListViewAppender.Create(ListView1), TVCLMemoLogAppender.Create(Memo1)]) + FLog := BuildLogWriter([TVCLListViewAppender.Create(ListView1), TVCLMemoLogAppender.Create(MemoAppenderMemo), TStringListLogAppender.Create(StringListAppenderMemo.Lines, 0)]) end; function TMainForm.Log: ILogWriter; From 6e77221bb824a1c1fe027fc39064308c14496c94 Mon Sep 17 00:00:00 2001 From: Jens Fudickar Date: Fri, 14 Jun 2024 19:48:59 +0200 Subject: [PATCH 2/2] Adding the option to have daily rotation for the FileAppender . --- LoggerPro.FileAppender.pas | 155 +++++++++++++----- LoggerPro.JSONLFileAppender.pas | 4 +- samples/02_file_appender/LoggerProConfig.pas | 26 ++- .../09_jsonl_appender/jsonl_appender.dproj | 28 +--- 4 files changed, 138 insertions(+), 75 deletions(-) diff --git a/LoggerPro.FileAppender.pas b/LoggerPro.FileAppender.pas index 9c45089..cba910a 100644 --- a/LoggerPro.FileAppender.pas +++ b/LoggerPro.FileAppender.pas @@ -64,20 +64,34 @@ interface Do not use this class directly, but one of TLoggerProFileAppender or TLoggerProSimpleFileAppender. Check the sample @code(file_appender.dproj) } + + TLoggerProStreamWriter = class(TStreamWriter) + private + FFileCreationDate: TDateTime; + public + property FileCreationDate: TDateTime read FFileCreationDate write FFileCreationDate; + end; + TLoggerProFileAppenderBase = class(TLoggerProAppenderBase) private fMaxBackupFileCount: Integer; + fMaxBackupFileCountLength : Integer; fMaxFileSizeInKiloByte: Integer; fLogFileNameFormat: string; fLogsFolder: string; fEncoding: TEncoding; + fDailyRotate : Boolean; + function RotateLogNeeded(aLogWriter: TStreamWriter): Boolean; function CreateWriter(const aFileName: string): TStreamWriter; + function GetFileDate(const aFileName: string): TDateTime; + function GetFileDateFormatted(const aFileName: string): string; + function FindLogFileByNumber(const aTag: string; const aFileNumber: Integer): string; procedure RetryMove(const aFileSrc, aFileDest: string); protected procedure CheckLogFileNameFormat(const LogFileNameFormat: String); virtual; procedure EmitStartRotateLogItem(aWriter: TStreamWriter); virtual; procedure EmitEndRotateLogItem(aWriter: TStreamWriter); virtual; - function GetLogFileName(const aTag: string; const aFileNumber: Integer): string; virtual; + function GetLogFileName(const aTag, aFileDate: string; const aFileNumber: Integer): string; virtual; procedure WriteToStream(const aStreamWriter: TStreamWriter; const aValue: string); inline; procedure RotateFile(const aLogTag: string; out aNewFileName: string); virtual; procedure InternalWriteLog(const aStreamWriter: TStreamWriter; const aLogItem: TLogItem); @@ -92,6 +106,7 @@ TLoggerProFileAppenderBase = class(TLoggerProAppenderBase) } DEFAULT_FILENAME_FORMAT = '{module}.{number}.{tag}.log'; DEFAULT_FILENAME_FORMAT_WITH_PID = '{module}.{number}.{pid}.{tag}.log'; + DEFAULT_FILENAME_DAILY_ROTATE_FORMAT = '{module}.{date}.{number}.{tag}.log'; { @abstract(Defines number of log file set to maintain during logs rotation) } DEFAULT_MAX_BACKUP_FILE_COUNT = 5; { @abstract(Defines the max size of each log file) @@ -101,14 +116,14 @@ TLoggerProFileAppenderBase = class(TLoggerProAppenderBase) RETRY_DELAY = 200; { @abstract(How many times do we have to retry if the file is locked?. } RETRY_COUNT = 5; - constructor Create( - aMaxBackupFileCount: Integer = TLoggerProFileAppenderBase.DEFAULT_MAX_BACKUP_FILE_COUNT; - aMaxFileSizeInKiloByte: Integer = TLoggerProFileAppenderBase.DEFAULT_MAX_FILE_SIZE_KB; - aLogsFolder: string = ''; - aLogFileNameFormat: string = TLoggerProFileAppenderBase.DEFAULT_FILENAME_FORMAT; - aLogItemRenderer: ILogItemRenderer = nil; - aEncoding: TEncoding = nil); - reintroduce; virtual; + DEFAULT_DAILYROTATE_FILEDATE_FORMAT = 'yyyy-mm-dd'; + constructor Create(aMaxBackupFileCount: Integer = TLoggerProFileAppenderBase.DEFAULT_MAX_BACKUP_FILE_COUNT; + aMaxFileSizeInKiloByte: Integer = TLoggerProFileAppenderBase.DEFAULT_MAX_FILE_SIZE_KB; + aLogsFolder: string = ''; + aLogFileNameFormat: string = TLoggerProFileAppenderBase.DEFAULT_FILENAME_FORMAT; + aLogItemRenderer: ILogItemRenderer = nil; + aEncoding: TEncoding = nil); + reintroduce; virtual; procedure Setup; override; end; @@ -120,7 +135,7 @@ TLoggerProFileAppender = class(TLoggerProFileAppenderBase) private fWritersDictionary: TObjectDictionary; procedure AddWriter(const aLogTag: string; var aWriter: TStreamWriter; var aLogFileName: string); - procedure RotateLog(const aLogTag: string; aWriter: TStreamWriter); + procedure RotateLog(const aLogTag: string; var aWriter: TStreamWriter); public procedure Setup; override; procedure TearDown; override; @@ -163,6 +178,7 @@ implementation System.IOUtils, System.StrUtils, System.Math, + System.DateUtils, idGlobal {$IF Defined(Android), System.SysUtils} ,Androidapi.Helpers @@ -199,12 +215,14 @@ procedure TLoggerProFileAppenderBase.CheckLogFileNameFormat(const LogFileNameFor { TLoggerProFileAppenderBase } -function TLoggerProFileAppenderBase.GetLogFileName(const aTag: string; const aFileNumber: Integer): string; +function TLoggerProFileAppenderBase.GetLogFileName(const aTag, aFileDate: + string; const aFileNumber: Integer): string; var // lExt: string; lModuleName: string; lPath: string; lFormat: string; + lFileDate: string; begin {$IF Defined(Android)} lModuleName := TAndroidHelper.ApplicationTitle.Replace(' ', '_', [rfReplaceAll]); @@ -218,9 +236,14 @@ function TLoggerProFileAppenderBase.GetLogFileName(const aTag: string; const aFi lFormat := fLogFileNameFormat; lPath := fLogsFolder; + if aFileDate = '' then + lFileDate := '0' + else + lFileDate := aFileDate; lFormat := lFormat .Replace('{module}', lModuleName, [rfReplaceAll]) - .Replace('{number}', aFileNumber.ToString.PadLeft(2,'0') , [rfReplaceAll]) + .Replace('{date}', lFileDate, [rfReplaceAll]) + .Replace('{number}', aFileNumber.ToString.PadLeft(fMaxBackupFileCountLength,'0') , [rfReplaceAll]) .Replace('{tag}', aTag, [rfReplaceAll]) .Replace('{pid}', CurrentProcessId.ToString.PadLeft(8,'0'), [rfReplaceAll]); Result := TPath.Combine(lPath, lFormat); @@ -290,37 +313,39 @@ procedure TLoggerProFileAppenderBase.RotateFile(const aLogTag: string; out aNewF I: Integer; lCurrentFileName: string; begin - aNewFileName := GetLogFileName(aLogTag, 0); + aNewFileName := GetLogFileName(aLogTag, '', 0); // remove the last file of backup set - lRenamedFile := GetLogFileName(aLogTag, fMaxBackupFileCount - 1); - if TFile.Exists(lRenamedFile) then - TFile.Delete(lRenamedFile); + lCurrentFileName := FindLogFileByNumber(aLogTag, fMaxBackupFileCount - 1); + if lCurrentFileName <> '' then + TFile.Delete(lCurrentFileName); // shift the files names for I := fMaxBackupFileCount - 1 downto 1 do begin - lCurrentFileName := GetLogFileName(aLogTag, I); - lRenamedFile := GetLogFileName(aLogTag, I + 1); - if TFile.Exists(lCurrentFileName) then - RetryMove(lCurrentFileName, lRenamedFile); + lCurrentFileName := FindLogFileByNumber(aLogTag, I); + if lCurrentFileName = '' then + Continue; + lRenamedFile := GetLogFileName(aLogTag, GetFileDateFormatted(lCurrentFileName), I + 1); + RetryMove(lCurrentFileName, lRenamedFile); end; - lRenamedFile := GetLogFileName(aLogTag, 1); + lRenamedFile := GetLogFileName(aLogTag, GetFileDateFormatted(aNewFileName), 1); RetryMove(aNewFileName, lRenamedFile); end; -constructor TLoggerProFileAppenderBase.Create( - aMaxBackupFileCount: Integer; - aMaxFileSizeInKiloByte: Integer; - aLogsFolder: string; - aLogFileNameFormat: string; - aLogItemRenderer: ILogItemRenderer; - aEncoding: TEncoding); +constructor TLoggerProFileAppenderBase.Create(aMaxBackupFileCount: Integer = TLoggerProFileAppenderBase.DEFAULT_MAX_BACKUP_FILE_COUNT; + aMaxFileSizeInKiloByte: Integer = TLoggerProFileAppenderBase.DEFAULT_MAX_FILE_SIZE_KB; + aLogsFolder: string = ''; + aLogFileNameFormat: string = TLoggerProFileAppenderBase.DEFAULT_FILENAME_FORMAT; + aLogItemRenderer: ILogItemRenderer = nil; + aEncoding: TEncoding = nil); begin inherited Create(aLogItemRenderer); fLogsFolder := aLogsFolder; fMaxBackupFileCount:= Max(1, aMaxBackupFileCount); + fMaxBackupFileCountLength := Max(2, (fMaxBackupFileCount-1).ToString.Length); fMaxFileSizeInKiloByte := aMaxFileSizeInKiloByte; CheckLogFileNameFormat(aLogFileNameFormat); fLogFileNameFormat := aLogFileNameFormat; + fDailyRotate := fLogFileNameFormat.IndexOf('{date}') >= 0; if Assigned(aEncoding) then fEncoding := aEncoding else @@ -348,9 +373,10 @@ function TLoggerProFileAppenderBase.CreateWriter(const aFileName: string): TStre lFileStream := TFileStream.Create(aFileName, lFileAccessMode); try lFileStream.Seek(0, TSeekOrigin.soEnd); - Result := TStreamWriter.Create(lFileStream, fEncoding, 32); + Result := TLoggerProStreamWriter.Create(lFileStream, fEncoding, 32); Result.AutoFlush := true; Result.OwnStream; + TLoggerProStreamWriter(Result).FileCreationDate := GetFileDate(aFileName); Break; except lFileStream.Free; @@ -374,11 +400,22 @@ function TLoggerProFileAppenderBase.CreateWriter(const aFileName: string): TStre procedure TLoggerProFileAppender.AddWriter(const aLogTag:string; var aWriter: TStreamWriter; var aLogFileName: string); begin - aLogFileName := GetLogFileName(aLogTag, 0); + aLogFileName := GetLogFileName(aLogTag, '',0); aWriter := CreateWriter(aLogFileName); fWritersDictionary.Add(aLogTag, aWriter); end; +function TLoggerProFileAppenderBase.RotateLogNeeded(aLogWriter: TStreamWriter): + Boolean; +begin + if ((fMaxFileSizeInKiloByte> 0) and (aLogWriter.BaseStream.Size > fMaxFileSizeInKiloByte * 1024)) + or ((fDailyRotate) and (not TLoggerProStreamWriter(aLogWriter).FileCreationDate.IsSameDay(Now()))) + then + Result := True + else + Result := False; +end; + procedure TLoggerProFileAppenderBase.EmitEndRotateLogItem(aWriter: TStreamWriter); begin WriteToStream(aWriter, '#[ROTATE LOG ' + datetimetostr(Now, FormatSettings) + ']'); @@ -389,19 +426,54 @@ procedure TLoggerProFileAppenderBase.EmitStartRotateLogItem(aWriter: TStreamWrit WriteToStream(aWriter, '#[START LOG ' + datetimetostr(Now, FormatSettings) + ']'); end; -procedure TLoggerProFileAppender.RotateLog(const aLogTag: string; aWriter: TStreamWriter); +function TLoggerProFileAppenderBase.GetFileDate(const aFileName: string): TDateTime; +begin + Result := 0; + if not fDailyRotate then + Exit; + try + Result := TFile.GetCreationTime (aFileName); + except + Result := 0; + end; +end; + +function TLoggerProFileAppenderBase.GetFileDateFormatted(const aFileName: string): string; +var Date : tDateTime; +begin + Result := ''; + Date := GetFileDate(aFileName); + if Date <= 0 then + Exit; + Result := FormatDateTime (DEFAULT_DAILYROTATE_FILEDATE_FORMAT, Date); +end; + +function TLoggerProFileAppenderBase.FindLogFileByNumber(const aTag: string; const aFileNumber: Integer): string; +var + SearchRec: TSearchRec; +begin + Result := GetLogFileName(aTag, '*', aFileNumber); + if findfirst (Result, faAnyFile, SearchRec) = 0 then + Result := TPath.GetDirectoryName (Result) + PathDelim + SearchRec.Name + else + Result := ''; + FindClose (SearchRec); + if Result <> '' then + Exit; +end; + +procedure TLoggerProFileAppender.RotateLog(const aLogTag: string; var aWriter: + TStreamWriter); var lLogFileName: string; begin EmitEndRotateLogItem(aWriter); - //WriteToStream(aWriter, '#[ROTATE LOG ' + datetimetostr(Now, FormatSettings) + ']'); // remove the writer during rename fWritersDictionary.Remove(aLogTag); RotateFile(aLogTag, lLogFileName); // re-create the writer AddWriter(aLogTag, aWriter, lLogFileName); EmitStartRotateLogItem(aWriter); - //WriteToStream(aWriter, '#[START LOG ' + datetimetostr(Now, FormatSettings) + ']'); end; procedure TLoggerProFileAppender.Setup; @@ -426,12 +498,11 @@ procedure TLoggerProFileAppender.WriteLog(const aLogItem: TLogItem); AddWriter(aLogItem.LogTag, lWriter, lLogFileName); end; + if RotateLogNeeded(lWriter) then + RotateLog(aLogItem.LogTag, lWriter); + InternalWriteLog(lWriter, aLogItem); - if lWriter.BaseStream.Size > fMaxFileSizeInKiloByte * 1024 then - begin - RotateLog(aLogItem.LogTag, lWriter); - end; end; { TLoggerProSimpleFileAppender } @@ -473,14 +544,14 @@ procedure TLoggerProSimpleFileAppender.RotateLog; fFileWriter.Free; RotateFile('', lLogFileName); // re-create the writer - fFileWriter := CreateWriter(GetLogFileName('', 0)); + fFileWriter := CreateWriter(GetLogFileName('', '', 0)); EmitStartRotateLogItem(fFileWriter); end; procedure TLoggerProSimpleFileAppender.Setup; begin inherited; - fFileWriter := CreateWriter(GetLogFileName('', 0)); + fFileWriter := CreateWriter(GetLogFileName('', '', 0)); end; procedure TLoggerProSimpleFileAppender.TearDown; @@ -491,11 +562,9 @@ procedure TLoggerProSimpleFileAppender.TearDown; procedure TLoggerProSimpleFileAppender.WriteLog(const aLogItem: TLogItem); begin - InternalWriteLog(fFileWriter, aLogItem); - if fFileWriter.BaseStream.Size > fMaxFileSizeInKiloByte * 1024 then - begin + if RotateLogNeeded(fFileWriter) then RotateLog; - end; + InternalWriteLog(fFileWriter, aLogItem); end; end. diff --git a/LoggerPro.JSONLFileAppender.pas b/LoggerPro.JSONLFileAppender.pas index 986e1cb..29155bb 100644 --- a/LoggerPro.JSONLFileAppender.pas +++ b/LoggerPro.JSONLFileAppender.pas @@ -40,7 +40,7 @@ interface } TLoggerProJSONLFileAppender = class(TLoggerProSimpleFileAppender) protected - function GetLogFileName(const aTag: string; const aFileNumber: Integer): string; override; + function GetLogFileName(const aTag, aFileDate: string; const aFileNumber: Integer): string; override; procedure EmitStartRotateLogItem(aWriter: TStreamWriter); override; procedure EmitEndRotateLogItem(aWriter: TStreamWriter); override; public @@ -102,7 +102,7 @@ procedure TLoggerProJSONLFileAppender.EmitStartRotateLogItem(aWriter: TStreamWri // do nothing end; -function TLoggerProJSONLFileAppender.GetLogFileName(const aTag: string; const aFileNumber: Integer): string; +function TLoggerProJSONLFileAppender.GetLogFileName(const aTag, aFileDate: string; const aFileNumber: Integer): string; var lOrigFName, lOrigExt: string; begin diff --git a/samples/02_file_appender/LoggerProConfig.pas b/samples/02_file_appender/LoggerProConfig.pas index 5608b8f..375306d 100644 --- a/samples/02_file_appender/LoggerProConfig.pas +++ b/samples/02_file_appender/LoggerProConfig.pas @@ -52,17 +52,25 @@ initialization // )]); // // Creates logs in the ..\..\ folder using the default filename +// The FilteringFileAppender selects the 'TAG1' and 'TAG2' log messages into a separate file +// _Log := BuildLogWriter([ +// TLoggerProFileAppender.Create(10, 5, '..\..', +// TLoggerProFileAppender.DEFAULT_FILENAME_FORMAT, +// TLogItemRendererNoTag.Create), +// TLoggerProFilter.Build( +// TLoggerProSimpleFileAppender.Create(10, 5, '..\..'), +// function(ALogItem: TLogItem): boolean +// begin +// Result := (ALogItem.LogTag = 'TAG1') or (ALogItem.LogTag = 'TAG2'); +// end) +// ]); + +// Creates logs in the ..\..\ folder using the default filename using the date rotation // The FilteringFileAppender selects the 'TAG1' and 'TAG2' log messages into a separate file _Log := BuildLogWriter([ - TLoggerProFileAppender.Create(10, 5, '..\..', - TLoggerProFileAppender.DEFAULT_FILENAME_FORMAT, - TLogItemRendererNoTag.Create), - TLoggerProFilter.Build( - TLoggerProSimpleFileAppender.Create(10, 5, '..\..'), - function(ALogItem: TLogItem): boolean - begin - Result := (ALogItem.LogTag = 'TAG1') or (ALogItem.LogTag = 'TAG2'); - end) + TLoggerProFileAppender.Create(10, 1000, '..\..', + TLoggerProFileAppender.DEFAULT_FILENAME_DAILY_ROTATE_FORMAT, + TLogItemRendererNoTag.Create) ]); end. diff --git a/samples/09_jsonl_appender/jsonl_appender.dproj b/samples/09_jsonl_appender/jsonl_appender.dproj index 947e8ca..07eaa78 100644 --- a/samples/09_jsonl_appender/jsonl_appender.dproj +++ b/samples/09_jsonl_appender/jsonl_appender.dproj @@ -4,7 +4,7 @@ jsonl_appender.dpr True Debug - 32897 + 1 Application VCL 20.1 @@ -13,11 +13,6 @@ true - - true - Base - true - true Base @@ -44,12 +39,6 @@ Base true - - true - Cfg_2 - true - true - true Cfg_2 @@ -68,10 +57,6 @@ 1040 CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= - - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - activity-1.7.2.dex.jar;annotation-experimental-1.3.0.dex.jar;annotation-jvm-1.6.0.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-6.0.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.10.1.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.10.1.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.1.dex.jar;lifecycle-livedata-2.6.1.dex.jar;lifecycle-livedata-core-2.6.1.dex.jar;lifecycle-runtime-2.6.1.dex.jar;lifecycle-service-2.6.1.dex.jar;lifecycle-viewmodel-2.6.1.dex.jar;lifecycle-viewmodel-savedstate-2.6.1.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.1.0.dex.jar;play-services-basement-18.1.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.0.2.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) Debug @@ -107,9 +92,6 @@ true true - - Debug - PerMonitorV2 true @@ -154,8 +136,6 @@ - True - True True False @@ -198,6 +178,12 @@ 1 + + + library\lib\armeabi-v7a + 1 + + library\lib\armeabi