Repository navigation
Add MultiFile max file age option - #737
Conversation
- Added the file’s UTC last-write timestamp to ILogFileInfo. - Implemented timestamp retrieval for: - Local files - SFTP files - Applied the Max days limit when MultiFile companion files are discovered. - The file explicitly opened by the user is always retained. - MaxDayTry = 0 preserves the previous unlimited behavior. - Filesystem plugins that cannot provide a timestamp retain the previous behavior and their files are not excluded.
EN, DE, CNs
|
hi, i added an analyses to the issue, its not really a bug |
|
The PR doesn't do what the #735 spec asks. The spec wants a new, separate max-file-age option. The PR instead turns the existing MaxDayTry setting into an age limit. Because MaxDayTry still defaults to 3, every existing user with an index pattern like *$J(.) will silently lose rollover files older than 3 days. The spec lists exactly that change as out of scope. Standards Bugs
Repo standards (judgement calls, none hard)
Smells (judgement calls)
Minor:
Spec (maintainer triage comment on #735) Missing or partial
Scope creep
Implemented but wrong
Summary: 10 standards findings, the worst being the "0 = unlimited" hint, which actually loads no files for $D patterns. 12 spec findings, the worst being that the PR changes MaxDayTry instead of adding a separate option that defaults to off. The fix the spec points to is a new MaxFileAgeDays option (default 0) with an injected clock, carried through Settings and the Session File, plus a ColumnizerLib version bump. |
|
OK I will try to make your proposal as you require. |
|
2 Bugs left:
New:
Remaining:
|
|
Hirogen
left a comment
There was a problem hiding this comment.
Thanks @Pr0metheus2 — everything from the last round is in. The overflow is capped and clamped, with int.MaxValue regression tests. The culture-dependent assert is gone. You were right about the Settings label keys: GenerateTextMapFromNaming picks them up by control name. The SFTP cache is cleared on failure, and each property keeps its old exception behaviour. The dead XML read is removed, and there's a seeding test. I also re-checked the spec from #735: default 0 leaves $D/MaxDayTry unchanged, the walk stops at the first file that's too old, and a null timestamp means the file is included. The clock is injected, the Session File round-trips with old files loading as 0, and the relabel is in all three languages. Functionally this is done.
A few small things before merge:
Description and title
- The description still describes the first version: "Applied the Max days limit…
MaxDayTry = 0preserves the previous unlimited behavior" and "withMaxDayTry = 3". Please rewrite it around the newMaxFileAgeDaysoption (default 0 = off, separate from "Max day gap"). - Title: "Enahancement" → e.g. "Add MultiFile max file age option".
Cleanup
PersisterXML.cs: the only change left is an added final newline. Please revert the file. The same goes for the other trailing-newline-only edits, if your editor added them.ColumnizerLib.csproj: please drop<PackageVersion>1.22.0</PackageVersion>. My mistake in the spec: the build passesPackageVersionto the pack step itself (Build.cs), so this line is ignored in CI and only confuses local builds.MultifileOptions.cs:13-15: the new XML docs on the existingMaxDayTryaren't needed for this change.RolloverFilenameHandler.cs:147: theDateTime.MinValueunderflow guard can't trigger once the value is clamped to 3650, so it can go.MultiFileMaskDialog.Designer.cs:114: a bare//instead of the generated//. Letting the designer regenerate the file will also fix the duplicate TabIndex values.
Optional
MultiFileAgeSettingsTestspins the dialog maximum atMAX_FILE_AGE_DAYS. Doing the same for the Settings up-down would keep the two3650literals in sync.
Once the description is updated and PersisterXML.cs and the version line are reverted, this is good to merge. Thanks for sticking with it!
SummaryAdds a separate MultiFile Max file age (days) option.
This is independent of Max day gap (
|
Hirogen
left a comment
There was a problem hiding this comment.
Thanks @Pr0metheus2 — the round-4 cleanup is all in: PersisterXML.cs and the PackageVersion line are reverted, the MaxDayTry docs and the MinValue guard are gone, the designer comments are fixed, and the Settings maximum is now pinned in a test too. I re-checked the #735 spec: default 0, stop at the first file that's too old, null timestamp means include, injected clock, the 3650 clamp, Session File round-trip, seeding, relabel, the opened file always kept, and mixed $D+$J. Everything holds. Build adds no warnings, and the Core/Persister/UI tests pass.
Two small things before merge:
1. PR description
The title is updated, but the description on GitHub is still the first version ("Applied the Max days limit…", "MaxDayTry = 0 preserves the previous unlimited behavior", "with MaxDayTry = 3"). The good summary you wrote is only in a comment. Please replace the description with it, describing the new MaxFileAgeDays option (default 0 = off, separate from "Max day gap"), the injected clock, the Settings/Session File round-trip and the ILogFileInfo.LastWriteTimeUtc addition.
2. Duplicate TabIndex values
These are still there (keyboard Tab order jumps around):
MultiFileMaskDialog.Designer.cs:fileNamePatternTextBoxmoved to 2 (clashes withlabelFileNamePattern),labelMaxFileAgeDays=6 clashes withSettings,labelMaxFileAgeDaysHint=7 clashes withsyntaxHelpLabel.SettingsDialog.Designer.cs:upDownMultifileMaxFileAgeDays=2 clashes withlabelPattern.
In VS: View → Tab Order on each dialog, click through the controls once, and save. That regenerates the values.
Optional, non-blocking
Resources.Designer.cslooks hand-edited (blank lines without the generated indent, and theSettingsDialog_UI_NumericUpDown_ToolTip_*accessors out of order). If you run Custom Tool onResources.resx, please use an English VS UI so the comments stay English.Math.Clamp(x, 0, MultiFileOptions.MAX_FILE_AGE_DAYS)appears three times (handler and both dialogs). A clamped getter onMultiFileOptionswould keep that in one place.
With 1 and 2 done, this is good to merge. Thanks for sticking with it — it came together really nicely!
|
Implemented the required tab-order fix and verified a clean build: 0 warnings, 0 errors. Changed:
The optional Resources.Designer.cs regeneration and Math.Clamp refactor were intentionally not changed. |
|
Completed the optional clamp cleanup. Math.Clamp(...) now exists in one place:
The rollover handler and both dialogs use that shared logic. |
|
Optional regeneration of resource accessors - Resources.Designer.cs |
Hirogen
left a comment
There was a problem hiding this comment.
Thanks @Pr0metheus2 — both items are done. The description now covers the new option properly, and every TabIndex is unique. SettingsDialog tabs top to bottom (pattern → max day gap → max file age). I re-checked the #735 spec after the last three commits and everything still holds: default 0 = off, stop at the first file that's too old, a missing timestamp counts as include, injected clock, 3650 clamp, Session File round-trip, global seeding, and the opened file is always kept. Thanks for the clamp cleanup and the English regeneration too. The regeneration also put the HighlightDialog_UI_Button_ToolTip_* block back into generator order, which is a nice side effect.
One small fix before merge
MultiFileOptions.ClampedMaxFileAgeDays is a public get-only property, and ConfigManager serializes MultiFileOptions with Newtonsoft without a contract resolver. So every settings save will now write "ClampedMaxFileAgeDays": N into settings.json. The simplest fix is to drop the property and call the static helper at all three sites:
MultiFileOptions.ClampMaxFileAgeDays(options.MaxFileAgeDays)
Alternatively, put [Newtonsoft.Json.JsonIgnore] / [System.Text.Json.Serialization.JsonIgnore] on it, like Preferences.cs does for its computed members.
Optional, non-blocking
MultiFileMaskDialog: Tab still goes max day gap (y=55) → pattern textbox (y=25) → max file age (y=85). That order was already on Development, so it's not from your PR. If you're in View → Tab Order anyway, swapping 3 and 4 would make it top to bottom.- Description: "Rollover files older than the configured age are excluded". Maybe add that collection stops at the first file that's too old, so a newer file after an old one isn't loaded either. That's the behaviour we agreed on in #735; it just isn't obvious from the sentence.
Resources.Designer.csnow saysGeneratedCodeAttribute(…, "17.0.0.0")(Development has 18.0.0.0). No need to do anything: I'm regenerating that file after the current batch of PRs anyway.
With the settings.json fix, this is good to merge. Thanks for sticking with it through all the rounds!
|
Implemented the required fix and both optional requests. Required fix:
Optional 1:
Optional 2:
|
Hirogen
left a comment
There was a problem hiding this comment.
Thanks @Pr0metheus2 — round 5 does it. ClampedMaxFileAgeDays is gone, all three call sites use MultiFileOptions.ClampMaxFileAgeDays(...), and nothing computed ends up in settings.json anymore. The tab order in MultiFileMaskDialog now runs top to bottom, and the description explains the stop-at-first-too-old behaviour. I re-checked #735 once more: default 0 = off, stop at the first file that's too old, opened file always kept, missing timestamp = include, UTC with the injected clock, 3650 clamp, Session File round-trip and global seeding all still hold. The Rollover/MultiFile/Persister/SessionFileComposer tests pass (176/176).
Approving. A few nits, none of them blocking — fix them here if you like, otherwise I'll pick them up after merging:
SftpLogFileInfo.cs:1-3:using System.Diagnostics.CodeAnalysis;should come beforeusing ColumnizerLib;(dotnet_sort_system_directives_firstinsrc/.editorconfig).Serialize_DoesNotWriteComputedMaxFileAgeDayschecks a property that no longer exists, so it can't really fail. Asserting thatMultiFileOptionsserializes to exactlyFormatPattern,MaxDayTryandMaxFileAgeDays(ideally with ConfigManager's serializer settings) would make it a real guard. Dropping it is fine too.TryGetFile(out file, bool catchSshException, bool catchArgumentNullException): every caller passes the same value for both flags, so oneboolis enough.
Thanks for sticking with this through all the rounds!
|
Small fix update:
|
Hirogen
left a comment
There was a problem hiding this comment.
Thanks @Pr0metheus2 — all three nits are done. The using order is fixed, TryGetFile is down to one flag with the same behaviour, and the serialization test now uses ConfigManager's real _jsonSettings and checks the exact key set. That's a proper guard now. The SFTP plugin builds without new warnings, and the MultiFile/Rollover tests pass (24/24).
If you touch it again (not needed for merge): the last line of the when clause in TryGetFile is indented one space too far.
Approving and merging. Thanks for all the work on this one!

This is a proposed fix for the Issue #735 and #185
Problem
The Max days setting only controlled how many previous calendar dates were searched when the MultiFile mask contained a $D date placeholder.
It did not check the last-modified date of files found using index patterns such as:
As a result, all indexed rollover files were loaded regardless of their age.
Summary
Adds a separate MultiFile Max file age (days) option.
0, which disables the age limit and preserves existing behavior.MaxDayTry), which controls only how many missing consecutive dates may be skipped while searching$Ddate-pattern files.ILogFileInfo.LastWriteTimeUtcsupplies the timestamp for local and SFTP files.Verification