diff --git a/src/LogExpert.Core/Classes/Log/RolloverFilenameBuilder.cs b/src/LogExpert.Core/Classes/Log/RolloverFilenameBuilder.cs index 3b8f1061..e449884b 100644 --- a/src/LogExpert.Core/Classes/Log/RolloverFilenameBuilder.cs +++ b/src/LogExpert.Core/Classes/Log/RolloverFilenameBuilder.cs @@ -238,9 +238,10 @@ private string EscapeNonvarRegions (string formatString) } } + _ = result.Append(Regex.Escape(segment.ToString())); fmt = result.ToString().Replace('\xFFFD', '*'); return fmt; } #endregion -} \ No newline at end of file +} diff --git a/src/LogExpert.Resources/Resources.de.resx b/src/LogExpert.Resources/Resources.de.resx index e0e19567..3852c64c 100644 --- a/src/LogExpert.Resources/Resources.de.resx +++ b/src/LogExpert.Resources/Resources.de.resx @@ -1680,12 +1680,16 @@ Ein ausgewähltes Tool erscheint in der Iconbar. Alle anderen verfügbaren Tools Muster syntax: * = alle Zeichen (wildcard) -$D(&lt;date&gt;) = Datumsmuster +$D(<date>) = Datumsmuster $I = Dateiindexnummer $J = Dateiindexnummer, versteckt wenn 09 -$J(&lt;prefix&gt;) = Wie $J, jedoch wird ein &lt;prefix&gt; hinzugefügt when es nicht 0 ist +$J(<prefix>) = Wie $J, jedoch wird ein <prefix> hinzugefügt when es nicht 0 ist -&lt;date&gt;: +Beispiele: +*$J(.) → app.log, app.log.1, app.log.2 +*$J(.).log → app.log, app.1.log, app.2.log + +<date>: DD = Tag MM = Monat YY[YY] = Jahr diff --git a/src/LogExpert.Resources/Resources.resx b/src/LogExpert.Resources/Resources.resx index a08b755c..70d5e60d 100644 --- a/src/LogExpert.Resources/Resources.resx +++ b/src/LogExpert.Resources/Resources.resx @@ -1743,12 +1743,16 @@ Checked tools will appear in the icon bar. All other tools are available in the Pattern syntax: * = any characters (wildcard) -$D(&lt;date&gt;) = Date pattern +$D(<date>) = Date pattern $I = File index number $J = File index number, hidden when zero -$J(&lt;prefix&gt;) = Like $J, but adding &lt;prefix&gt; when non-zero +$J(<prefix>) = Like $J, but adding <prefix> when non-zero -&lt;date&gt;: +Examples: +*$J(.) → app.log, app.log.1, app.log.2 +*$J(.).log → app.log, app.1.log, app.2.log + +<date>: DD = day MM = month YY[YY] = year diff --git a/src/LogExpert.Resources/Resources.zh-CN.resx b/src/LogExpert.Resources/Resources.zh-CN.resx index f4af56f5..826db482 100644 --- a/src/LogExpert.Resources/Resources.zh-CN.resx +++ b/src/LogExpert.Resources/Resources.zh-CN.resx @@ -1554,6 +1554,10 @@ $I = 文件索引编号 $J = 文件索引编号,为零时隐藏 $J(<前缀>) = 类似 $J,但在非零时添加 <前缀> +示例: +*$J(.) → app.log, app.log.1, app.log.2 +*$J(.).log → app.log, app.1.log, app.2.log + <日期>: DD = 日 MM = 月 diff --git a/src/LogExpert.Tests/LogExpert.Tests.csproj b/src/LogExpert.Tests/LogExpert.Tests.csproj index addb6a7a..2ead6531 100644 --- a/src/LogExpert.Tests/LogExpert.Tests.csproj +++ b/src/LogExpert.Tests/LogExpert.Tests.csproj @@ -112,6 +112,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/src/LogExpert.Tests/RollingNameTest.cs b/src/LogExpert.Tests/RollingNameTest.cs index a85f94b4..8f0a079c 100644 --- a/src/LogExpert.Tests/RollingNameTest.cs +++ b/src/LogExpert.Tests/RollingNameTest.cs @@ -32,6 +32,7 @@ public void TestFilename1(string expectedResult, string formatString) [TestCase("engine.log", "engine1.log","engine$J.log")] [TestCase("engine1.log", "engine2.log","engine$J.log")] [TestCase("engine.log", "engine.log.1","*$J(.)")] + [TestCase("engine.log", "engine.1.log", "*$J(.).log")] [TestCase("engine_2010-06-12.log", "engine_2010-06-12.log.1", "*$D(yyyy-MM-dd).log$J(.)")] public void TestFilenameAnd1(string fileName, string expectedResult, string formatString) { @@ -45,6 +46,7 @@ public void TestFilenameAnd1(string fileName, string expectedResult, string form [Test] [TestCase("engine.log", "engine.log.2","*$J(.)")] [TestCase("engine.log", "engine.log.2","*.log$J(.)")] + [TestCase("engine.log", "engine.2.log", "*$J(.).log")] public void TestFilenameAnd2(string fileName, string expectedResult, string formatString) { RolloverFilenameBuilder fnb = new(formatString); @@ -65,4 +67,4 @@ public void TestFilenameMinus1(string fileName, string expectedResult, string fo var name = fnb.BuildFileName(); Assert.That(name, Is.EqualTo("engine.log")); } -} \ No newline at end of file +} diff --git a/src/LogExpert.Tests/StreamReaderTests/LogfileReaderMultiFileFlagTests.cs b/src/LogExpert.Tests/StreamReaderTests/LogfileReaderMultiFileFlagTests.cs index 5522313d..ab3edd74 100644 --- a/src/LogExpert.Tests/StreamReaderTests/LogfileReaderMultiFileFlagTests.cs +++ b/src/LogExpert.Tests/StreamReaderTests/LogfileReaderMultiFileFlagTests.cs @@ -26,6 +26,8 @@ public void SetUp () File.Copy(Path.Combine(_testDataDirectory, "app.log"), _logFile); File.Copy(Path.Combine(_testDataDirectory, "app.log.1"), _logFile + ".1"); + File.Copy(Path.Combine(_testDataDirectory, "app.1.log"), Path.Combine(_testDirectory, "app.1.log")); + File.Copy(Path.Combine(_testDataDirectory, "app.2.log"), Path.Combine(_testDirectory, "app.2.log")); _ = PluginRegistry.PluginRegistry.Create(_testDirectory, 500); } @@ -68,6 +70,22 @@ public void SingleFileCtor_MultiFileTrue_ExpandsRollover () }); } + [Test] + public void SingleFileCtor_MultiFileTrue_LoadsIndexBeforeExtension () + { + var options = new MultiFileOptions { FormatPattern = "*$J(.).log" }; + using var reader = CreateSingleFileReader(multiFile: true, options); + + reader.ReadFiles(); + + Assert.Multiple(() => + { + Assert.That(reader.IsMultiFile, Is.True); + Assert.That(reader.GetLogFileInfoList().Select(file => Path.GetFileName(file.FullName)), + Is.EqualTo(new[] { "app.2.log", "app.1.log", "app.log" })); + }); + } + [Test] public void MultiFileCtor_AlwaysMultiFile () { @@ -91,7 +109,7 @@ public void MultiFileCtor_AlwaysMultiFile () }); } - private LogfileReader CreateSingleFileReader (bool multiFile) + private LogfileReader CreateSingleFileReader (bool multiFile, MultiFileOptions? options = null) { return new LogfileReader( _logFile, @@ -99,7 +117,7 @@ private LogfileReader CreateSingleFileReader (bool multiFile) multiFile, bufferCount: 40, linesPerBuffer: 50, - new MultiFileOptions(), + options ?? new MultiFileOptions(), ReaderType.System, PluginRegistry.PluginRegistry.Instance, maximumLineLength: 500, diff --git a/src/LogExpert.Tests/TestData/app.1.log b/src/LogExpert.Tests/TestData/app.1.log new file mode 100644 index 00000000..dc4e726a --- /dev/null +++ b/src/LogExpert.Tests/TestData/app.1.log @@ -0,0 +1 @@ +app.1.log \ No newline at end of file diff --git a/src/LogExpert.Tests/TestData/app.2.log b/src/LogExpert.Tests/TestData/app.2.log new file mode 100644 index 00000000..67dfe9df --- /dev/null +++ b/src/LogExpert.Tests/TestData/app.2.log @@ -0,0 +1 @@ +app.2.log \ No newline at end of file diff --git a/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.designer.cs b/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.designer.cs index c7d64109..add47f8c 100644 --- a/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.designer.cs +++ b/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.designer.cs @@ -269,9 +269,9 @@ private void InitializeComponent () // // multiFileEnabledStripMenuItem // - multiFileEnabledStripMenuItem.BackColor = SystemColors.Control; + // multiFileEnabledStripMenuItem.BackColor = SystemColors.Control; multiFileEnabledStripMenuItem.CheckOnClick = true; - multiFileEnabledStripMenuItem.ForeColor = SystemColors.ControlDarkDark; + // multiFileEnabledStripMenuItem.ForeColor = SystemColors.ControlDarkDark; multiFileEnabledStripMenuItem.Name = "multiFileEnabledStripMenuItem"; multiFileEnabledStripMenuItem.Size = new Size(165, 22); multiFileEnabledStripMenuItem.Text = "Enable MultiFile"; @@ -279,8 +279,8 @@ private void InitializeComponent () // // multifileMaskToolStripMenuItem // - multifileMaskToolStripMenuItem.BackColor = SystemColors.Control; - multifileMaskToolStripMenuItem.ForeColor = SystemColors.ControlDarkDark; + // multifileMaskToolStripMenuItem.BackColor = SystemColors.Control; + // multifileMaskToolStripMenuItem.ForeColor = SystemColors.ControlDarkDark; multifileMaskToolStripMenuItem.Name = "multifileMaskToolStripMenuItem"; multifileMaskToolStripMenuItem.Size = new Size(165, 22); multifileMaskToolStripMenuItem.Text = "File name mask..."; diff --git a/src/LogExpert.UI/Dialogs/MultiFileMaskDialog.Designer.cs b/src/LogExpert.UI/Dialogs/MultiFileMaskDialog.Designer.cs index d57d7e64..18763c3b 100644 --- a/src/LogExpert.UI/Dialogs/MultiFileMaskDialog.Designer.cs +++ b/src/LogExpert.UI/Dialogs/MultiFileMaskDialog.Designer.cs @@ -121,7 +121,7 @@ private void InitializeComponent() // this.syntaxHelpLabel.Location = new System.Drawing.Point(15, 140); this.syntaxHelpLabel.Name = "syntaxHelpLabel"; - this.syntaxHelpLabel.Size = new System.Drawing.Size(402, 194); + this.syntaxHelpLabel.Size = new System.Drawing.Size(402, 254); this.syntaxHelpLabel.TabIndex = 7; this.syntaxHelpLabel.Text = "Syntax Help Label"; // @@ -129,7 +129,7 @@ private void InitializeComponent() // this.buttonOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK; - this.buttonOk.Location = new System.Drawing.Point(261, 347); + this.buttonOk.Location = new System.Drawing.Point(261, 407); this.buttonOk.Name = "buttonOk"; this.buttonOk.Size = new System.Drawing.Size(75, 23); this.buttonOk.TabIndex = 8; @@ -141,7 +141,7 @@ private void InitializeComponent() // this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.buttonCancel.Location = new System.Drawing.Point(342, 347); + this.buttonCancel.Location = new System.Drawing.Point(342, 407); this.buttonCancel.Name = "buttonCancel"; this.buttonCancel.Size = new System.Drawing.Size(75, 23); this.buttonCancel.TabIndex = 9; @@ -152,7 +152,7 @@ private void InitializeComponent() // this.AcceptButton = this.buttonOk; this.CancelButton = this.buttonCancel; - this.ClientSize = new System.Drawing.Size(434, 386); + this.ClientSize = new System.Drawing.Size(434, 446); this.Controls.Add(this.buttonCancel); this.Controls.Add(this.buttonOk); this.Controls.Add(this.syntaxHelpLabel); @@ -162,7 +162,7 @@ private void InitializeComponent() this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(329, 420); + this.MinimumSize = new System.Drawing.Size(329, 480); this.Name = "MultiFileMaskDialog"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "MultiFile settings"; @@ -188,4 +188,4 @@ private void InitializeComponent() private System.Windows.Forms.Label syntaxHelpLabel; private System.Windows.Forms.Button buttonOk; private System.Windows.Forms.Button buttonCancel; - } \ No newline at end of file + }