You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Multifile settings does not accept 'Max days' value #735
When turning on Multifile, Max days field in Multifile settings is not accepted. Tested on three files (app.log, app.log.1, app.log.2), every file has different date in weeks, setting value Max days =3. All files were loaded regardless max days value entered.
@Pr0metheus2 your analysis is correct, and the "fixed" verdict on #185 was wrong. Max days has never filtered files by age. It only sets how many consecutive calendar days without a file LogExpert accepts when walking back through a $D(...) date pattern. Index patterns ($I / $J) ignore it completely. We're treating this as an enhancement: a separate file-age limit, plus a clearer name for the existing setting.
Category: enhancement Summary: Add a "max file age" limit to MultiFile mode that works for index and date patterns, and rename the existing Max days so its gap-tolerance meaning is clear
Current behavior: RolloverFilenameHandler.GetNameList builds the MultiFile list newest-to-oldest:
Index patterns: the index is increased for as long as a file exists.
Date patterns: the date is decremented, and the walk gives up after MultiFileOptions.MaxDayTry consecutive days without a file.
No file's age is ever checked. A user with app.log, app.log.1, app.log.2 spread over several weeks and Max days = 3 gets all three loaded. The UI shows the setting only as "Max days:", which reads as an age limit.
Desired behavior:
A new MultiFile option, max file age in days, with 0 meaning off. 0 is the default so existing behavior is unchanged.
When it is greater than 0, MultiFile collection stops at the first rollover file whose last-modified time is older than now minus N days. That file and every older one are left out, so the loaded sequence stays contiguous.
This applies the same way to index patterns, date patterns and mixed patterns.
The file the user opened (the newest one, first in the walk) always loads, whatever its age.
If a file system cannot report a last-modified time, that file's age counts as unknown and the file is included. Unknown age never excludes a file.
The existing MaxDayTry behavior is kept exactly as it is, but its UI label and help text are renamed to say what it does, for example "Max day gap" with the tooltip/help "For $D patterns: how many consecutive days without a log file to skip before giving up". The pattern-syntax help in the MultiFile dialog mentions both settings.
The new option exists wherever MaxDayTry does:
in the global default (Settings → MultiFile)
in the per-window MultiFile dialog
in the per-window Session File state, round-tripped through SessionSnapshot, SessionFileComposer and PersistenceData, the same way MultiFileMaxDays is
Session Files and settings written before this change load with the new option at 0 (off).
Key interfaces:
MultiFileOptions: new int property for the age limit, next to MaxDayTry (default 0).
RolloverFilenameHandler.GetNameList: applies the cutoff during the walk. Make "now" injectable (a TimeProvider or a clock parameter) so tests are deterministic.
ILogFileInfo (ColumnizerLib, public plugin API): needs a way to report the last-modified time. Add it as a default interface member returning "unknown" (for example DateTime? LastWriteTimeUtc => null), so third-party file system plugins still compile and load. Implement it for the local file system and the built-in SFTP file system plugin.
This changes the ColumnizerLib SDK, so bump its own version in ColumnizerLib.csproj, as decided in the packaging issue.
SessionSnapshot / PersistenceData / SessionFileComposer: carry the new value in both directions. Legacy XML session files default to 0.
MultiFile dialog and Settings dialog: a new numeric field and the relabelled MaxDayTry field. Strings go in LogExpert.Resources for every existing language file, following the existing localization pattern.
Acceptance criteria:
Index pattern *$J(.) with app.log (today), app.log.1 (2 days old), app.log.2 (10 days old) and max age 5 loads app.log and app.log.1 only
Same files with max age 0 load all three (unchanged behavior)
A contiguity test: app.log.1 is 10 days old and app.log.2 is 1 day old, with max age 5. Only app.log loads, because the walk stops at app.log.1
The opened file loads even when it is older than the limit
Date pattern $D(...): the existing MaxDayTry gap tests still pass unchanged, and a new test shows the age limit cutting off old dated files
A file whose ILogFileInfo reports no last-modified time is included
The value round-trips through a Session File, and an older Session File without the field loads as 0
The value is editable in both the per-window MultiFile dialog and Settings, and the global default seeds new windows
All logic tests run in Core against a fake file system and an injected clock, with no real file timestamps or sleeps
Full test suite passes
Out of scope:
Changing what MaxDayTry does (only its label and help text change)
Age filtering anywhere outside MultiFile collection, such as the file-open dialog or tail-follow of the current file
Re-evaluating age while a MultiFile window is already open. The limit is applied when the list is built (load or reload).
An upper limit on how many rollover files are loaded
Activity
[-]Multifile settngs does not accept Max days value[/-][+]Multifile settings does not accept Max days value[/+][-]Multifile settings does not accept Max days value[/-][+]Multifile settings does not accept 'Max days' value[/+]Pr0metheus2 commentedon Oct 19, 2026
The Max days setting only controlls how many previous calendar dates were searched when the MultiFile mask contained a $D date placeholder.
It do check the last-modified date of files found using index patterns such as:
As a result, indexed rollover files are loaded regardless of their age.
Hirogen commentedon Oct 19, 2026
@Pr0metheus2 your analysis is correct, and the "fixed" verdict on #185 was wrong.
Max dayshas never filtered files by age. It only sets how many consecutive calendar days without a file LogExpert accepts when walking back through a$D(...)date pattern. Index patterns ($I/$J) ignore it completely. We're treating this as an enhancement: a separate file-age limit, plus a clearer name for the existing setting.Category: enhancement
Summary: Add a "max file age" limit to MultiFile mode that works for index and date patterns, and rename the existing
Max daysso its gap-tolerance meaning is clearCurrent behavior:
RolloverFilenameHandler.GetNameListbuilds the MultiFile list newest-to-oldest:MultiFileOptions.MaxDayTryconsecutive days without a file.No file's age is ever checked. A user with
app.log,app.log.1,app.log.2spread over several weeks andMax days = 3gets all three loaded. The UI shows the setting only as "Max days:", which reads as an age limit.Desired behavior:
0meaning off.0is the default so existing behavior is unchanged.MaxDayTrybehavior is kept exactly as it is, but its UI label and help text are renamed to say what it does, for example "Max day gap" with the tooltip/help "For$Dpatterns: how many consecutive days without a log file to skip before giving up". The pattern-syntax help in the MultiFile dialog mentions both settings.MaxDayTrydoes:SessionSnapshot,SessionFileComposerandPersistenceData, the same wayMultiFileMaxDaysis0(off).Key interfaces:
MultiFileOptions: new int property for the age limit, next toMaxDayTry(default0).RolloverFilenameHandler.GetNameList: applies the cutoff during the walk. Make "now" injectable (aTimeProvideror a clock parameter) so tests are deterministic.ILogFileInfo(ColumnizerLib, public plugin API): needs a way to report the last-modified time. Add it as a default interface member returning "unknown" (for exampleDateTime? LastWriteTimeUtc => null), so third-party file system plugins still compile and load. Implement it for the local file system and the built-in SFTP file system plugin.ColumnizerLib.csproj, as decided in the packaging issue.SessionSnapshot/PersistenceData/SessionFileComposer: carry the new value in both directions. Legacy XML session files default to0.MaxDayTryfield. Strings go inLogExpert.Resourcesfor every existing language file, following the existing localization pattern.Acceptance criteria:
*$J(.)withapp.log(today),app.log.1(2 days old),app.log.2(10 days old) and max age 5 loadsapp.logandapp.log.1only0load all three (unchanged behavior)app.log.1is 10 days old andapp.log.2is 1 day old, with max age 5. Onlyapp.logloads, because the walk stops atapp.log.1$D(...): the existingMaxDayTrygap tests still pass unchanged, and a new test shows the age limit cutting off old dated filesILogFileInforeports no last-modified time is included0Out of scope:
MaxDayTrydoes (only its label and help text change)Pr0metheus2 commentedon Oct 19, 2026
I have already released a PR, do you want me to change anything? Let me know in PR, please.
Pr0metheus2 commentedon Nov 2, 2026
Done by #737