ApplicationLog.cs
10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
namespace SysFramework
{
using System;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.EnterpriseServices;
/// <summary>
/// Logging class to provide tracing and logging support.
/// <remarks>
/// There are four different logging levels (error, warning, info, trace)
/// that produce output to either the system event log or a tracing
/// file as specified in the current ApplicationConfiguration settings.
/// </remarks>
/// </summary>
[Transaction(TransactionOption.Disabled)]
public class ApplicationLog
{
//
// Shared member variables
//
// TraceSwitch for changing which values are actually written to the
// trace output file.
private static TraceSwitch debugSwitch;
//This object is added as a debug listener.
private static StreamWriter debugWriter;
//EventLog variables used for the trace level if the event log is specified.
private static TraceLevel eventLogTraceLevel;
/// <summary>
/// Write at the Error level to the event log and/or tracing file.
/// <param name="message">The text to write to the log file or event log.</param>
/// </summary>
public static void WriteError(String message)
{
//Defer to the helper function to log the message.
WriteLog(TraceLevel.Error, message);
}
/// <summary>
/// Write at the Warning level to the event log and/or tracing file.
/// <param name="message">The text to write to the log file or event log.</param>
/// </summary>
public static void WriteWarning(String message)
{
//Defer to the helper function to log the message.
WriteLog(TraceLevel.Warning, message);
}
/// <summary>
/// Write at the Info level to the event log and/or tracing file.
/// <param name="message">The text to write to the log file or event log.</param>
/// </summary>
public static void WriteInfo(String message)
{
//Defer to the helper function to log the message.
WriteLog(TraceLevel.Info, message);
}
/// <summary>
/// Write at the Verbose level to the event log and/or tracing file.
/// <param name="message">The text to write to the log file or event log.</param>
/// </summary>
public static void WriteTrace(String message)
{
//Defer to the helper function to log the message.
WriteLog(TraceLevel.Verbose, message);
}
/// <summary>
/// Write at the Verbose level to the event log and/or tracing file.
/// <param name="ex">The Exception object to format</param>
/// <param name="catchInfo">The string to prepend to the exception information.</param>
/// <retvalue>
/// <para>A nicely format exception string, including message and StackTrace information.</para>
/// </retvalue>
/// </summary>
public static String FormatException(Exception ex, String catchInfo)
{
StringBuilder strBuilder = new StringBuilder();
if (catchInfo != String.Empty)
{
strBuilder.Append(catchInfo).Append("\r\n");
}
strBuilder.Append(ex.Message).Append("\r\n").Append(ex.StackTrace);
return strBuilder.ToString();
}
/// <summary>
/// Determine where a string needs to be written based on the
/// configuration settings and the error level.
/// <param name="level">The severity of the information to be logged.</param>
/// <param name="messageText">The string to be logged.</param>
/// </summary>
private static void WriteLog(TraceLevel level, String messageText)
{
//
// Be very careful by putting a Try/Catch around the entire routine.
// We should never throw an exception while logging.
//
try
{
//
// Write the message to the trace file
//
//Make sure a tracing file is specified.
if (debugWriter != null)
{
//Log based on switch level.
if (level <= debugSwitch.Level)
{
lock(debugWriter)
{
Debug.WriteLine(messageText);
debugWriter.Flush();
}
}
}
//
// Write the message to the system event log. We only write the message
// if the configuration settings say it is severe enough to warrant
// an entry in the event log.
//
if (level <= eventLogTraceLevel)
{
//
// Map the trace level to the corresponding event log attribute.
// Note that EventLogEntryType = 2 ^ (level - 1), but it is generally not
// considered good style to apply arithmetic operations to enum values.
EventLogEntryType LogEntryType;
switch (level)
{
case TraceLevel.Error:
LogEntryType = EventLogEntryType.Error;
break;
case TraceLevel.Warning:
LogEntryType = EventLogEntryType.Warning;
break;
case TraceLevel.Info:
LogEntryType = EventLogEntryType.Information;
break;
case TraceLevel.Verbose:
LogEntryType = EventLogEntryType.SuccessAudit;
break;
default:
LogEntryType = EventLogEntryType.SuccessAudit;
break;
}
EventLog eventLog = new EventLog("Application", ApplicationConfiguration.EventLogMachineName, ApplicationConfiguration.EventLogSourceName );
//Write the entry to the event log
eventLog.WriteEntry(messageText, LogEntryType);
}
}
catch {} //Ignore any exceptions.
}
/// <summary>
/// Constructor for ApplicationLog.
/// <remarks>Initialize all shared variables based on the ApplicationConfigurationsettings.
/// Called when this class is first loaded.
/// </remarks>
/// </summary>
static ApplicationLog()
{
//
// Read the current settings from the configuration file to determine
// whether we need trace file support, event logging, or both.
//
//Get the class object in order to take the initialization lock
Type myType = typeof(ApplicationLog);
//Protect thread locks with Try/Catch to guarantee that we let go of the lock.
try
{
//See if anyone else is using the lock, grab it if they//re not
if (!Monitor.TryEnter(myType))
{
//Just wait until the other thread finishes processing, then leave if
// the lock was already in use.
Monitor.Enter(myType);
return;
}
//See if there is a debug configuration file specified and set up the
// tracing variables.
bool clearSettings = true;
try
{
//Check if we're enabled
if (ApplicationConfiguration.TracingEnabled)
{
//Make sure we have a TraceSettings file.
String tracingFile = ApplicationConfiguration.TracingTraceFile;
if (tracingFile != String.Empty)
{
//Read in the tracing switch name and create the switch.
String switchName = ApplicationConfiguration.TracingSwitchName;
//Create the new switch
if (switchName != String.Empty)
{
//Create a debug listener and add it as a debug listener
FileInfo file = new FileInfo(tracingFile);
debugWriter = new StreamWriter(file.Open(FileMode.Append, FileAccess.Write, FileShare.ReadWrite));
Debug.Listeners.Add(new TextWriterTraceListener(debugWriter));
debugSwitch = new TraceSwitch(switchName, ApplicationConfiguration.TracingSwitchDescription);
debugSwitch.Level = ApplicationConfiguration.TracingTraceLevel;
}
clearSettings = false;
}
}
}
catch
{
//Ignore the error
}
//Use default (empty) values if something went wrong
if (clearSettings)
{
//Tracing information is off or not properly specified, clear it
debugSwitch = null;
debugWriter = null;
}
if(ApplicationConfiguration.EventLogEnabled)
eventLogTraceLevel = ApplicationConfiguration.EventLogTraceLevel;
else
eventLogTraceLevel = TraceLevel.Off;
}
finally
{
//Remove the lock from the class object
Monitor.Exit(myType);
}
}
} //class ApplicationLog
} //namespace T1.SystemFramework