Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class RollingFileTraceListener : TraceListenerBase
{
"template", "Template",
"convertWriteToEvent", "ConvertWriteToEvent",
"newStreamOnError", "NewStreamOnError"
};
TraceFormatter traceFormatter = new TraceFormatter();
private RollingTextWriter rollingTextWriter;
Expand Down Expand Up @@ -111,6 +112,36 @@ public bool ConvertWriteToEvent
}
}

private bool? _newStreamOnError = null;
Comment thread
alex-grigoras marked this conversation as resolved.
/// <summary>
/// Gets or sets whether errors writing to the file should cause a new file stream to be instantiated.
/// Useful when the drive containing the file has a transient fault (usb stick removed and reinserted, network outage of mapped drive, etc.)
/// </summary>
[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Boolean.TryParse(System.String,System.Boolean@)", Justification = "Default value is acceptable if conversion fails.")]
public bool NewStreamOnError
{
get
{
if (_newStreamOnError.HasValue)
{
return _newStreamOnError.Value;
}

// Default behaviour is to convert Write to event.
Comment thread
alex-grigoras marked this conversation as resolved.
Outdated
var newStreamOnError = false;
if (Attributes.ContainsKey("newStreamOnError"))
{
bool.TryParse(Attributes["newStreamOnError"], out newStreamOnError);
}
_newStreamOnError = newStreamOnError;
return newStreamOnError;
}
set
{
Attributes["newStreamOnError"] = value.ToString(CultureInfo.InvariantCulture);
Comment thread
alex-grigoras marked this conversation as resolved.
}
}

/// <summary>
/// Gets or sets the file system to use; this defaults to an adapter for System.IO.File.
/// </summary>
Expand Down Expand Up @@ -194,7 +225,7 @@ public string FilePathTemplate
/// </summary>
public override void Flush()
{
rollingTextWriter.Flush();
rollingTextWriter.Flush(NewStreamOnError);
Comment thread
alex-grigoras marked this conversation as resolved.
Outdated
}

/// <summary>
Expand All @@ -218,7 +249,7 @@ protected override void Write(string category, string message, object data)
}
else
{
rollingTextWriter.Write(null, message);
rollingTextWriter.Write(null, message, NewStreamOnError);
Comment thread
alex-grigoras marked this conversation as resolved.
Outdated
}
}

Expand All @@ -235,7 +266,7 @@ protected override void WriteLine(string category, string message, object data)
}
else
{
rollingTextWriter.WriteLine(null, message);
rollingTextWriter.WriteLine(null, message, NewStreamOnError);
}
}

Expand Down Expand Up @@ -266,7 +297,7 @@ protected override void WriteTrace(TraceEventCache eventCache, string source, Tr
relatedActivityId,
data
);
rollingTextWriter.WriteLine(eventCache, output);
rollingTextWriter.WriteLine(eventCache, output, NewStreamOnError);
}

protected override void Dispose(bool disposing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,34 +74,67 @@ public IFileSystem FileSystem
}
}

public void Flush()
public void Flush(bool clearWriterOnError)
{
lock (_fileLock)
{
if (_currentWriter != null)
{
_currentWriter.Flush();
try
{
_currentWriter.Flush();
}
catch
{
if (clearWriterOnError)
{
DestroyCurrentWriter();
}
throw;
}
}
}
}

public void Write(TraceEventCache eventCache, string value)
public void Write(TraceEventCache eventCache, string value, bool clearWriterOnError)
{
string filePath = GetCurrentFilePath(eventCache);
lock (_fileLock)
{
EnsureCurrentWriter(filePath);
_currentWriter.Write(value);
try
{
_currentWriter.Write(value);
}
catch
{
if(clearWriterOnError)
{
DestroyCurrentWriter();
}
throw;
}
}
}

public void WriteLine(TraceEventCache eventCache, string value)
public void WriteLine(TraceEventCache eventCache, string value, bool clearWriterOnError)
{
string filePath = GetCurrentFilePath(eventCache);
lock (_fileLock)
{
EnsureCurrentWriter(filePath);
_currentWriter.WriteLine(value);
try
{
_currentWriter.WriteLine(value);
}
catch
{
if (clearWriterOnError)
{
DestroyCurrentWriter();
}
throw;
}
}
}

Expand Down Expand Up @@ -148,6 +181,18 @@ private void EnsureCurrentWriter(string path)
}
}

private void DestroyCurrentWriter()
{
// NOTE: This is called inside lock(_fileLock)
if (_currentWriter != null)
{
_currentWriter.Close();
_currentWriter.Dispose();
_currentWriter = null;
_currentPath = null;
}
}

static string getFullPath(string path, int num)
{
var extension = Path.GetExtension(path);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Text;
Expand Down Expand Up @@ -41,7 +42,8 @@ public class RollingXmlTraceListener : TraceListenerBase
// Default format matches Microsoft.VisualBasic.Logging.FileLogTraceListener
private const string _defaultFilePathTemplate = "{ApplicationName}-{DateTime:yyyy-MM-dd}.svclog";
private static string[] _supportedAttributes = new string[]
{
{
"newStreamOnError", "NewStreamOnError"
};
TraceFormatter traceFormatter = new TraceFormatter();

Expand Down Expand Up @@ -125,12 +127,42 @@ public string FilePathTemplate
get { return rollingTextWriter.FilePathTemplate; }
}

private bool? _newStreamOnError = null;
/// <summary>
/// Gets or sets whether errors writing to the file should cause a new file stream to be instantiated.
/// Useful when the drive containing the file has a transient fault (usb stick removed and reinserted, network outage of mapped drive, etc.)
/// </summary>
[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Boolean.TryParse(System.String,System.Boolean@)", Justification = "Default value is acceptable if conversion fails.")]
public bool NewStreamOnError
{
get
{
if(_newStreamOnError.HasValue)
{
return _newStreamOnError.Value;
}

// Default behaviour is to convert Write to event.
var newStreamOnError = false;
if (Attributes.ContainsKey("newStreamOnError"))
{
bool.TryParse(Attributes["newStreamOnError"], out newStreamOnError);
}
_newStreamOnError = newStreamOnError;
return newStreamOnError;
}
set
{
Attributes["newStreamOnError"] = value.ToString(CultureInfo.InvariantCulture);
}
}

/// <summary>
/// Flushes the output buffer.
/// </summary>
public override void Flush()
{
rollingTextWriter.Flush();
rollingTextWriter.Flush(NewStreamOnError);
}

/// <summary>
Expand Down Expand Up @@ -170,7 +202,7 @@ protected override void WriteTrace(TraceEventCache eventCache, string source, Tr

AppendFooter(output, eventCache);

rollingTextWriter.WriteLine(eventCache, output.ToString());
rollingTextWriter.WriteLine(eventCache, output.ToString(), NewStreamOnError);
}

private static void AppendData(StringBuilder output, object data)
Expand Down