diff --git a/src/Essential.Diagnostics.RollingFileTraceListener/Diagnostics/RollingFileTraceListener.cs b/src/Essential.Diagnostics.RollingFileTraceListener/Diagnostics/RollingFileTraceListener.cs
index 1417dd8..f69d72d 100644
--- a/src/Essential.Diagnostics.RollingFileTraceListener/Diagnostics/RollingFileTraceListener.cs
+++ b/src/Essential.Diagnostics.RollingFileTraceListener/Diagnostics/RollingFileTraceListener.cs
@@ -37,10 +37,16 @@ public class RollingFileTraceListener : TraceListenerBase
{
"template", "Template",
"convertWriteToEvent", "ConvertWriteToEvent",
+ "createSubdirectories", "CreateSubdirectories"
};
TraceFormatter traceFormatter = new TraceFormatter();
private RollingTextWriter rollingTextWriter;
+ // Indicate whether all subdirectories in full file path
+ // should be checked for existence and re-created if missed
+ // before opening the file
+ private bool? createSubdirectories;
+
///
/// Constructor. Writes to a rolling text file using the default name.
///
@@ -111,6 +117,42 @@ public bool ConvertWriteToEvent
}
}
+ ///
+ /// Gets or sets the value indicating whether all subdirectories in full file path
+ /// should be checked for existence and re-created if missed
+ /// before opening the file. Default value is False.
+ ///
+ [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Boolean.TryParse(System.String,System.Boolean@)", Justification = "Default value is acceptable if conversion fails.")]
+ public bool CreateSubdirectories
+ {
+ get
+ {
+ if (createSubdirectories.HasValue)
+ {
+ return createSubdirectories.Value;
+ }
+
+ if (Attributes.ContainsKey("createSubdirectories"))
+ {
+ bool parsed;
+ if (bool.TryParse(Attributes["createSubdirectories"], out parsed))
+ {
+ createSubdirectories = parsed;
+ return createSubdirectories.Value;
+ }
+ }
+
+ // Default behaviour is do NOT check and fail if any of
+ // the subdirectories in log file path are not exists.
+ return false;
+ }
+ set
+ {
+ createSubdirectories = value;
+ Attributes["createSubdirectories"] = value.ToString(CultureInfo.InvariantCulture);
+ }
+ }
+
///
/// Gets or sets the file system to use; this defaults to an adapter for System.IO.File.
///
@@ -218,6 +260,7 @@ protected override void Write(string category, string message, object data)
}
else
{
+ rollingTextWriter.FileSystem.CreateSubdirectories = CreateSubdirectories;
rollingTextWriter.Write(null, message);
}
}
@@ -235,6 +278,7 @@ protected override void WriteLine(string category, string message, object data)
}
else
{
+ rollingTextWriter.FileSystem.CreateSubdirectories = CreateSubdirectories;
rollingTextWriter.WriteLine(null, message);
}
}
@@ -266,6 +310,7 @@ protected override void WriteTrace(TraceEventCache eventCache, string source, Tr
relatedActivityId,
data
);
+ rollingTextWriter.FileSystem.CreateSubdirectories = CreateSubdirectories;
rollingTextWriter.WriteLine(eventCache, output);
}
diff --git a/src/Essential.Diagnostics.RollingFileTraceListener/IO/FileSystem.cs b/src/Essential.Diagnostics.RollingFileTraceListener/IO/FileSystem.cs
index c1deb7b..46a59e9 100644
--- a/src/Essential.Diagnostics.RollingFileTraceListener/IO/FileSystem.cs
+++ b/src/Essential.Diagnostics.RollingFileTraceListener/IO/FileSystem.cs
@@ -7,6 +7,13 @@ namespace Essential.IO
///
public class FileSystem : IFileSystem
{
+ ///
+ /// Gets or sets the value indicating whether all subdirectories in full file path
+ /// should be checked for existence and re-created if missed
+ /// before opening the file. Default value is False.
+ ///
+ public bool CreateSubdirectories { get; set; }
+
///
/// Opens a System.IO.FileStream on the specified path,
/// having the specified mode with read, write, or read/write access
@@ -19,6 +26,13 @@ public class FileSystem : IFileSystem
///
public Stream Open(string path, FileMode mode, FileAccess access, FileShare share)
{
+ if (CreateSubdirectories)
+ {
+ // Making sure that all subdirectories in file path exists
+ var directory = Path.GetDirectoryName(path);
+ Directory.CreateDirectory(directory);
+ }
+
return File.Open(path, mode, access, share);
}
}
diff --git a/src/Essential.Diagnostics.RollingFileTraceListener/IO/IFileSystem.cs b/src/Essential.Diagnostics.RollingFileTraceListener/IO/IFileSystem.cs
index 7459f9f..f0d1a0b 100644
--- a/src/Essential.Diagnostics.RollingFileTraceListener/IO/IFileSystem.cs
+++ b/src/Essential.Diagnostics.RollingFileTraceListener/IO/IFileSystem.cs
@@ -7,6 +7,13 @@ namespace Essential.IO
///
public interface IFileSystem
{
+ ///
+ /// Gets or sets the value indicating whether all subdirectories in full file path
+ /// should be checked for existence and re-created if missed
+ /// before opening the file. Default value is False.
+ ///
+ bool CreateSubdirectories { get; set; }
+
///
/// Opens a System.IO.FileStream on the specified path,
/// having the specified mode with read, write, or read/write access
diff --git a/src/Tests/Essential.Diagnostics.RollingFileTraceListener.Tests/Utility/MockFileSystem.cs b/src/Tests/Essential.Diagnostics.RollingFileTraceListener.Tests/Utility/MockFileSystem.cs
index 96cb8e2..44081c9 100644
--- a/src/Tests/Essential.Diagnostics.RollingFileTraceListener.Tests/Utility/MockFileSystem.cs
+++ b/src/Tests/Essential.Diagnostics.RollingFileTraceListener.Tests/Utility/MockFileSystem.cs
@@ -7,6 +7,8 @@ namespace Essential.Diagnostics.Tests.Utility
{
public class MockFileSystem : IFileSystem
{
+ public bool CreateSubdirectories { get; set; }
+
public IList> OpenedItems = new List>();
public Stream Open(string path, FileMode mode, FileAccess access, FileShare share)