Skip to content
This repository was archived by the owner on May 11, 2024. It is now read-only.

Commit 56e8e61

Browse files
committed
fix: improve Windows Event Log messages when logging fails
1 parent 8c4afab commit 56e8e61

File tree

9 files changed

+265
-75
lines changed

9 files changed

+265
-75
lines changed

SMLogging-net35/SMLogging-net35.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@
136136
<Compile Include="..\SMLogging\TraceSourceConverter.cs">
137137
<Link>TraceSourceConverter.cs</Link>
138138
</Compile>
139+
<Compile Include="..\SMLogging\WindowsEventLogTraceListener.cs">
140+
<Link>WindowsEventLogTraceListener.cs</Link>
141+
</Compile>
139142
<Compile Include="Properties\AssemblyInfo.cs" />
140143
</ItemGroup>
141144
<ItemGroup>

SMLogging.Lab.Client/App.config

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
<system.serviceModel>
77
<extensions>
88
<behaviorExtensions>
9-
<add name="requestLogging" type="SMLogging.RequestLoggingBehaviorExtension, SMLogging"/>
10-
<add name="errorLogging" type="SMLogging.ErrorLoggingBehaviorExtension, SMLogging"/>
9+
<!--<add name="requestLogging" type="SMLogging.RequestLoggingBehaviorExtension, SMLogging"/>-->
10+
<!--<add name="errorLogging" type="SMLogging.ErrorLoggingBehaviorExtension, SMLogging"/>-->
1111
</behaviorExtensions>
1212
</extensions>
1313
<behaviors>
1414
<endpointBehaviors>
1515
<behavior>
16-
<requestLogging />
16+
<!--<requestLogging />-->
1717
</behavior>
1818
</endpointBehaviors>
1919
</behaviors>
@@ -82,13 +82,25 @@
8282
<source name="System.ServiceModel.RequestLogging" switchValue="Information">
8383
<listeners>
8484
<remove name="Default" />
85-
<add name="File" type="SMLogging.BackgroundFileTraceListener, SMLogging" initializeData="%SystemDrive%\servicemodel\logs\{AppName}\requests.{DateTime:yyMMdd}.log" rollingMode="DateTime" rollingInterval="Day" />
85+
<add name="File" type="SMLogging.BackgroundFileTraceListener, SMLogging" initializeData="%SystemDrive%\servicemodel\logs\{AppName}\requests.{DateTime:yyMMdd}.log" rollingMode="DateTime" rollingInterval="Day" failTraceSource="System.ServiceModel.RequestLogging.Fail"/>
8686
</listeners>
8787
</source>
88-
<source name="System.ServiceModel.ErrorLogging" switchValue="Error">
88+
<source name="System.ServiceModel.ErrorLogging" switchValue="Error" >
8989
<listeners>
9090
<remove name="Default" />
91-
<add name="File" type="SMLogging.BackgroundFileTraceListener, SMLogging" initializeData="%SystemDrive%\servicemodel\logs\{AppName}\errors.{DateTime:yyMMdd}.log" rollingMode="DateTime" rollingInterval="Day" />
91+
<add name="File" type="SMLogging.BackgroundFileTraceListener, SMLogging" initializeData="%SystemDrive%\servicemodel\logs\{AppName}\errors.{DateTime:yyMMdd}.log" rollingMode="DateTime" rollingInterval="Day" failTraceSource="System.ServiceModel.ErrorLogging.Fail"/>
92+
</listeners>
93+
</source>
94+
<source name="System.ServiceModel.ErrorLogging.Fail" switchValue="Error">
95+
<listeners>
96+
<remove name="Default" />
97+
<add name="EventLog" type="SMLogging.WindowsEventLogTraceListener" initializeData="SMLogging" />
98+
</listeners>
99+
</source>
100+
<source name="System.ServiceModel.RequestLogging.Fail" switchValue="Error">
101+
<listeners>
102+
<remove name="Default" />
103+
<add name="EventLog" type="SMLogging.WindowsEventLogTraceListener, SMLogging" initializeData="SMLogging" />
92104
</listeners>
93105
</source>
94106
</sources>

SMLogging.Lab/Web.config

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
<system.serviceModel>
1212
<extensions>
1313
<behaviorExtensions>
14-
<add name="requestLogging" type="SMLogging.RequestLoggingBehaviorExtension, SMLogging"/>
15-
<add name="errorLogging" type="SMLogging.ErrorLoggingBehaviorExtension, SMLogging"/>
14+
<!--<add name="requestLogging" type="SMLogging.RequestLoggingBehaviorExtension, SMLogging"/>
15+
<add name="errorLogging" type="SMLogging.ErrorLoggingBehaviorExtension, SMLogging"/>-->
1616
</behaviorExtensions>
1717
</extensions>
1818
<behaviors>
@@ -22,8 +22,8 @@
2222
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
2323
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
2424
<serviceDebug includeExceptionDetailInFaults="true"/>
25-
<requestLogging />
26-
<errorLogging />
25+
<!--<requestLogging />
26+
<errorLogging />-->
2727
</behavior>
2828
</serviceBehaviors>
2929
</behaviors>
@@ -104,18 +104,30 @@
104104
</system.webServer>
105105

106106
<system.diagnostics>
107-
<!--<trace autoflush="true"/>-->
107+
<trace autoflush="true"/>
108108
<sources>
109109
<source name="System.ServiceModel.RequestLogging" switchValue="Information">
110110
<listeners>
111111
<remove name="Default" />
112-
<add name="File" type="SMLogging.BackgroundFileTraceListener, SMLogging" initializeData="%SystemDrive%\servicemodel\logs\{AppName}\requests.{DateTime:yyMMdd}.log" rollingMode="DateTime" rollingInterval="Day" />
112+
<add name="File" type="SMLogging.BackgroundFileTraceListener, SMLogging" initializeData="%SystemDrive%\servicemodel\logs\{AppName}\requests.{DateTime:yyMMdd}.log" rollingMode="DateTime" rollingInterval="Day" failTraceSource="System.ServiceModel.RequestLogging.Fail"/>
113113
</listeners>
114114
</source>
115115
<source name="System.ServiceModel.ErrorLogging" switchValue="Error" >
116116
<listeners>
117117
<remove name="Default" />
118-
<add name="File" type="SMLogging.BackgroundFileTraceListener, SMLogging" initializeData="%SystemDrive%\servicemodel\logs\{AppName}\errors.{DateTime:yyMMdd}.log" rollingMode="DateTime" rollingInterval="Day" />
118+
<add name="File" type="SMLogging.BackgroundFileTraceListener, SMLogging" initializeData="%SystemDrive%\servicemodel\logs\{AppName}\errors.{DateTime:yyMMdd}.log" rollingMode="DateTime" rollingInterval="Day" failTraceSource="System.ServiceModel.ErrorLogging.Fail"/>
119+
</listeners>
120+
</source>
121+
<source name="System.ServiceModel.ErrorLogging.Fail" switchValue="Error">
122+
<listeners>
123+
<remove name="Default" />
124+
<add name="EventLog" type="SMLogging.WindowsEventLogTraceListener" initializeData="SMLogging" />
125+
</listeners>
126+
</source>
127+
<source name="System.ServiceModel.RequestLogging.Fail" switchValue="Error">
128+
<listeners>
129+
<remove name="Default" />
130+
<add name="EventLog" type="SMLogging.WindowsEventLogTraceListener, SMLogging" initializeData="SMLogging" />
119131
</listeners>
120132
</source>
121133
</sources>

SMLogging.Setup.CustomActions/CustomActions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ private static void SetupDirectory(string path)
349349
private const string ErrorLoggingFailSourceName = "System.ServiceModel.ErrorLogging.Fail";
350350
private const string ErrorLoggingFailSourceSwitchValue = "Error";
351351
private const string EventLogListenerName = "EventLog";
352-
private const string EventLogTraceListenerType = "System.Diagnostics.EventLogTraceListener";
352+
private const string EventLogTraceListenerType = "SMLogging.WindowsEventLogTraceListener, SMLogging, Version={0}.0, Culture=neutral, PublicKeyToken=ddc81ec55fc35caf";
353353
private const string EventLogSourceName = "SMLogging";
354354

355355
#endregion

SMLogging/BackgroundFileTraceListener.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ private void EnqueueEvent(Event evt, bool force)
204204
if (force)
205205
{
206206
Event oldEvt;
207-
_queue.TryDequeue(out oldEvt);
208207
_queue.Enqueue(evt);
208+
_queue.TryDequeue(out oldEvt);
209209
}
210210

211211
if (!_maxQueueSizeReached)

SMLogging/FileTraceListener.cs

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,9 @@ private string FormatFilePath(string path)
512512
}
513513
namedArgs["DateTime"] = dateTime;
514514
namedArgs["Timestamp"] = DateTime.UtcNow.Ticks;
515-
namedArgs["ProcessId"] = _processId;
516-
namedArgs["ProcessName"] = RemoveInvalidFileNameCharacters(_processName);
517-
namedArgs["AppName"] = RemoveInvalidFileNameCharacters(_appName);
515+
namedArgs["ProcessId"] = ProcessId;
516+
namedArgs["ProcessName"] = RemoveInvalidFileNameCharacters(ProcessName);
517+
namedArgs["AppName"] = RemoveInvalidFileNameCharacters(AppName);
518518

519519
return StringHelpers.NamedFormat(CultureInfo.InvariantCulture, path, namedArgs);
520520
}
@@ -667,22 +667,7 @@ private static string RemoveInvalidFileNameCharacters(string value)
667667
private FileLockHandlerBase _lockHandler;
668668
private FileLockStream _lockStream;
669669
private TextWriter _writer;
670-
671-
private static readonly int _processId;
672-
private static readonly string _processName;
673-
private static readonly string _appName;
674-
675-
static FileTraceListener()
676-
{
677-
using (var process = Process.GetCurrentProcess())
678-
{
679-
_processId = process.Id;
680-
_processName = process.ProcessName;
681-
}
682-
683-
_appName = AppDomain.CurrentDomain.GetFriendlyName();
684-
}
685-
670+
686671
#endregion
687672
}
688673
}

SMLogging/SMLogging.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<Compile Include="EncodingConverter.cs" />
5656
<Compile Include="ErrorLoggingBehavior.cs" />
5757
<Compile Include="ErrorLoggingErrorHandler.cs" />
58+
<Compile Include="WindowsEventLogTraceListener.cs" />
5859
<Compile Include="ExclusiveFileLockHandler.cs" />
5960
<Compile Include="FileLockHandlerBase.cs" />
6061
<Compile Include="FileLockingMode.cs" />

SMLogging/TraceListenerBase.cs

Lines changed: 89 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,21 @@ protected TraceListenerBase(string name)
8080

8181
#endregion
8282

83+
/// <summary>
84+
/// Gets the process identifier.
85+
/// </summary>
86+
protected int ProcessId => _processId;
87+
88+
/// <summary>
89+
/// Gets the name of the process.
90+
/// </summary>
91+
protected string ProcessName => _processName;
92+
93+
/// <summary>
94+
/// Gets the name of the application.
95+
/// </summary>
96+
protected string AppName => _appName;
97+
8398
#region Public Methods
8499

85100
/// <summary>
@@ -97,7 +112,7 @@ public override void TraceData(TraceEventCache eventCache, string source, TraceE
97112

98113
if (ShouldTrace(eventCache, source, eventType, id, null, null, data, null))
99114
{
100-
var message = String.Empty;
115+
var message = string.Empty;
101116
if (data != null)
102117
{
103118
message = data.ToString();
@@ -150,7 +165,7 @@ public override void TraceData(TraceEventCache eventCache, string source, TraceE
150165
[ComVisible(false)]
151166
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id)
152167
{
153-
TraceEvent(eventCache, source, eventType, id, String.Empty);
168+
TraceEvent(eventCache, source, eventType, id, string.Empty);
154169
}
155170

156171
/// <summary>
@@ -188,10 +203,10 @@ public override void TraceEvent(TraceEventCache eventCache, string source, Trace
188203

189204
if (ShouldTrace(eventCache, source, eventType, id, format, args))
190205
{
191-
var message = String.Empty;
206+
var message = string.Empty;
192207
if (args != null)
193208
{
194-
message = String.Format(CultureInfo.InvariantCulture, format, args);
209+
message = string.Format(CultureInfo.InvariantCulture, format, args);
195210
}
196211
else
197212
{
@@ -213,37 +228,7 @@ public virtual void WriteTrace(TraceEventCache eventCache, string source, TraceE
213228
{
214229
WriteLine(FormatTrace(eventCache, source, eventType, id, message));
215230

216-
var includeOptions = ((int)TraceOutputOptionsLevels & (int)eventType) != 0;
217-
if (includeOptions && eventCache != null)
218-
{
219-
IndentLevel++;
220-
if ((TraceOptions.ProcessId & TraceOutputOptions) != TraceOptions.None)
221-
{
222-
WriteLine(String.Format(CultureInfo.InvariantCulture, AssemblyResources.ProcessIdTraceToken, eventCache.ProcessId));
223-
}
224-
if ((TraceOptions.LogicalOperationStack & TraceOutputOptions) != TraceOptions.None)
225-
{
226-
var stack = StringHelpers.Join(", ", eventCache.LogicalOperationStack.ToArray());
227-
WriteLine(String.Format(CultureInfo.InvariantCulture, AssemblyResources.LogicalOperationStackTraceToken, stack));
228-
}
229-
if ((TraceOptions.ThreadId & TraceOutputOptions) != TraceOptions.None)
230-
{
231-
WriteLine(String.Format(CultureInfo.InvariantCulture, AssemblyResources.ThreadIdTraceToken, eventCache.ThreadId));
232-
}
233-
if ((TraceOptions.DateTime & TraceOutputOptions) != TraceOptions.None)
234-
{
235-
WriteLine(String.Format(CultureInfo.InvariantCulture, AssemblyResources.DateTimeTraceToken, eventCache.DateTime));
236-
}
237-
if ((TraceOptions.Timestamp & TraceOutputOptions) != TraceOptions.None)
238-
{
239-
WriteLine(String.Format(CultureInfo.InvariantCulture, AssemblyResources.TimestampTraceToken, eventCache.Timestamp));
240-
}
241-
if ((TraceOptions.Callstack & TraceOutputOptions) != TraceOptions.None)
242-
{
243-
WriteLine(String.Format(CultureInfo.InvariantCulture, AssemblyResources.CallstackTraceToken, eventCache.Callstack));
244-
}
245-
IndentLevel--;
246-
}
231+
WriteTraceOutput(eventCache, eventType);
247232
}
248233

249234
/// <summary>
@@ -308,13 +293,15 @@ protected virtual string FormatTrace(TraceEventCache eventCache, string source,
308293
namedArgs["EventType"] = eventType.ToString();
309294
namedArgs["EventId"] = id;
310295
namedArgs["Message"] = message;
311-
namedArgs["ProcessId"] = eventCache != null ? eventCache.ProcessId : 0;
312-
namedArgs["ThreadId"] = eventCache != null ? eventCache.ThreadId : String.Empty;
296+
namedArgs["ProcessId"] = ProcessId;
297+
namedArgs["ProcessName"] = ProcessName;
298+
namedArgs["AppName"] = AppName;
299+
namedArgs["ThreadId"] = eventCache != null ? eventCache.ThreadId : string.Empty;
313300
namedArgs["ActivityId"] = Trace.CorrelationManager.ActivityId;
314-
namedArgs["LogicalOperationStack"] = String.Join(", ", Trace.CorrelationManager.LogicalOperationStack.ToArray().Select(s => s.ToString()).ToArray());
301+
namedArgs["LogicalOperationStack"] = string.Join(", ", Trace.CorrelationManager.LogicalOperationStack.ToArray().Select(s => s.ToString()).ToArray());
315302
namedArgs["NewLine"] = Environment.NewLine;
316303

317-
var result = String.Empty;
304+
var result = string.Empty;
318305

319306
try
320307
{
@@ -328,6 +315,52 @@ protected virtual string FormatTrace(TraceEventCache eventCache, string source,
328315
return result;
329316
}
330317

318+
/// <summary>
319+
/// Writes the trace output.
320+
/// </summary>
321+
/// <param name="eventCache">The event cache.</param>
322+
/// <param name="eventType">Type of the event.</param>
323+
/// <param name="writeLine">The write line method. Default is <see cref="M:WriteLine"/>.</param>
324+
protected virtual void WriteTraceOutput(TraceEventCache eventCache, TraceEventType eventType, Action<string> writeLine = null)
325+
{
326+
if (writeLine == null)
327+
{
328+
writeLine = WriteLine;
329+
}
330+
331+
var includeOptions = ((int)TraceOutputOptionsLevels & (int)eventType) != 0;
332+
if (includeOptions && eventCache != null)
333+
{
334+
IndentLevel++;
335+
if ((TraceOptions.ProcessId & TraceOutputOptions) != TraceOptions.None)
336+
{
337+
writeLine(string.Format(CultureInfo.InvariantCulture, AssemblyResources.ProcessIdTraceToken, eventCache.ProcessId));
338+
}
339+
if ((TraceOptions.LogicalOperationStack & TraceOutputOptions) != TraceOptions.None)
340+
{
341+
var stack = StringHelpers.Join(", ", eventCache.LogicalOperationStack.ToArray());
342+
writeLine(string.Format(CultureInfo.InvariantCulture, AssemblyResources.LogicalOperationStackTraceToken, stack));
343+
}
344+
if ((TraceOptions.ThreadId & TraceOutputOptions) != TraceOptions.None)
345+
{
346+
writeLine(string.Format(CultureInfo.InvariantCulture, AssemblyResources.ThreadIdTraceToken, eventCache.ThreadId));
347+
}
348+
if ((TraceOptions.DateTime & TraceOutputOptions) != TraceOptions.None)
349+
{
350+
writeLine(string.Format(CultureInfo.InvariantCulture, AssemblyResources.DateTimeTraceToken, eventCache.DateTime));
351+
}
352+
if ((TraceOptions.Timestamp & TraceOutputOptions) != TraceOptions.None)
353+
{
354+
writeLine(string.Format(CultureInfo.InvariantCulture, AssemblyResources.TimestampTraceToken, eventCache.Timestamp));
355+
}
356+
if ((TraceOptions.Callstack & TraceOutputOptions) != TraceOptions.None)
357+
{
358+
writeLine(string.Format(CultureInfo.InvariantCulture, AssemblyResources.CallstackTraceToken, eventCache.Callstack));
359+
}
360+
IndentLevel--;
361+
}
362+
}
363+
331364
/// <summary>
332365
/// Determines if the trace listener should emit a trace statement based on the trace information provided.
333366
/// </summary>
@@ -453,7 +486,7 @@ protected void ApplyConfiguration()
453486
{
454487
if (isRequired)
455488
{
456-
throw new ConfigurationErrorsException(String.Format(CultureInfo.InvariantCulture, AssemblyResources.MissingRequiredAttribute, name));
489+
throw new ConfigurationErrorsException(string.Format(CultureInfo.InvariantCulture, AssemblyResources.MissingRequiredAttribute, name));
457490
}
458491
else if (!defaultValue.Equals(nullValue))
459492
{
@@ -488,7 +521,22 @@ protected void ApplyConfiguration()
488521

489522
private bool _hasConfiguration = false;
490523
private bool _isInitialized = false;
491-
private readonly object _initializeLock = new object();
524+
private readonly object _initializeLock = new object();
525+
526+
private static readonly int _processId;
527+
private static readonly string _processName;
528+
private static readonly string _appName;
529+
530+
static TraceListenerBase()
531+
{
532+
using (var process = Process.GetCurrentProcess())
533+
{
534+
_processId = process.Id;
535+
_processName = process.ProcessName;
536+
}
537+
538+
_appName = AppDomain.CurrentDomain.GetFriendlyName();
539+
}
492540

493541
private const string _defaultTraceFormat = "{DateTime:yyyy-MM-dd} {DateTime:HH:mm:ss.FFF} {Message}";
494542
private const string _defaultTraceDataDelimiter = " ";

0 commit comments

Comments
 (0)