Lab 1: Add Logging to an Application 实验1:给一个应用程序添加日志
In this lab, you will add logging and tracing to an existing application. To begin this exercise, open the EnoughPI.sln file located in the ex01\begin folder. 在这个实验中,你将添加日志和追踪到一个已有的程序中。要开始这个练习,请打开在ex01\begin文件夹中的EnoughPI.sln文件。
Note: This exercise involves writing to the event log. The event log trace listener used in this application automatically registers a new event source, but this requires you to run Visual Studio with elevated permissions. Please run Visual Studio as Administrator for this lab.
注意:这个练习包含写入事件日志。在这个程序中使用的事件日志trace监听器自动注册一个新的事件源,但这个要求你用更高的权限运行Visual Studio。在本实验中请使用管理员身份运行Visual Studio。
To learn about the application 了解这个程序
1.Select the Debug | Start Without Debugging menu command to run the application. 选择 调试|开始执行(不调试) 菜单命令来运行程序。
The EnoughPI application calculates the digits of pi (π, the ratio of the circumference of a circle to its diameter). Enter your desired precision via the NumericUpDown control and click the Calculate button. Be prepared to wait if you want more than 500 digits of precision. EnoughPI程序计算pi的数(π,圆的周长与直径的比例)。输入或使用界面上的上下按钮来确定你想要的精度,然后单击计算按钮。如果你想要超过500位的精度,请稍等一段时间。
To add logging to the application 给程序添加日志
Add the following namespace inclusions at the top of the file: 在文件头部添加下面的命名空间:
using System.Diagnostics;
using EnoughPI.Logging; using Microsoft.Practices.EnterpriseLibrary.Logging; using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters; using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;
To configure the application 配置程序
1 private static LoggingConfiguration BuildProgrammaticConfig() 2 { 3 4 // Formatter 5 TextFormatter formatter = new TextFormatter( 6 @"Timestamp:{timestamp(local)}{newline}Message: 7 {message}{newline}Category: {category}{newline}Priority: 8 {priority}{newline}EventId: {eventid}{newline}ActivityId: 9 {property(ActivityId)}{newline}Severity: 10 {severity}{newline}Title:{title}{newline}"); 11 12 // Trace Listeners 13 var eventLog = new EventLog("Application", ".", "EnoughPI"); 14 var eventLogTraceListener = new FormattedEventLogTraceListener( 15 eventLog, 16 formatter 17 ); 18 // Build Configuration 19 var config = new LoggingConfiguration(); 20 config.AddLogSource( 21 Category.General, 22 SourceLevels.All, 23 true).AddTraceListener(eventLogTraceListener); 24 return config; 25 }
This LoggingConfiguration consists of a collection of LogSources. Each LogSource specifies a name for the source, the SourceLevel of logs to include, and a Boolean indicating whether or not to enable auto-flush. Adding a TraceListener to the LogSource enables that listener to receive logs from the LogSource and write them to the specified destination with the selected format. For this application, the EventLog source name is set to "EnoughPI." This is the name you will see for log entries when they appear in the Windows Event Log. The LoggingConfiguration specifies that these logs will be listed under the "General" category and that all SourceLevels should be logged. Finally, a LogSource is added to the configuration and the
EventLogTraceListener you just created is set to listen to that LogSource.
LoggingConfiguration 由一个LogSources集合构成,每个LogSource为源指定一个名称、日志的SourceLevel和一个Boolean指示是否自动刷新。添加一个TraceListener到LogSource中使得监听器可以接受来自LogSource的的日志并将日志通过选中的格式化方法写到指定的目的地。在这个程序中,EventLog源的名称被设定为"EnoughPI"。这是你将在Windows事件日志中看到的条目的名称。LoggingConfiguration指定了这些日志将被列在"General"级别下,这样,所有的SourceLevels都将被记录。最后,一个LogSource被添加到了配置中而你刚刚创建的EventLogTraceListener将被设置来监听LogSource。
1 static void Main() 2 { 3 Application.ThreadException += 4 new System.Threading.ThreadExceptionEventHandler( 5 Application_ThreadException); 6 Logger.SetLogWriter(new LogWriter(BuildProgrammaticConfig())); 7 Form entryForm = new MainForm(); 8 Application.EnableVisualStyles(); 9 Application.Run(entryForm); 10 // shut down the logger to flush all buffers 11 Logger.Reset(); 12 }
The Logger fa?ade is a singleton, so setting it in the EntryPoint enables the same Log Writer instance to be used in all other classes in this project that require logging (for example, The Calculator class) without configuring it more than once. Logger是一个单例,所以在入口点设置就能让在这个项目中的其他需要记录日志的类(例如Calculator类)中使用相同的日志记录器实例,而不用每次使用都做配置。
Note: Using the Logger fa?ade is the simplest use of the Logging Application Block, especially when having only one instance of the LogWriter class, which is the most common case. Nevertheless, in applications that use an Inversion of Control (IoC) Container, you might consider registering the instance of LogWriter directly, so that it can be injected in dependent objects as opposed to those dependent objects using the static fa?ade.
注意:使用Logger静态类是使用日志应用程序块的最简单方法,特别是当只用一个LogWriter类的实例是如此,同时也是最常用的方法。然而,在使用控制反转容器的程序中,你可能要考虑直接注册LogWriter的实例,这样它可以被注入到以来的对象来避免以来的对象使用静态类。
using Microsoft.Practices.EnterpriseLibrary.Logging;
You have used constants for the Category and Priority rather than use hard-coded tags and integers (see Constants.cs in the EnoughPI.Logging project). This is not required but it is useful for consistency throughout your entire application.
使用常量比硬编码标签或整数(见EnoughPI.Logging项目的Constants.cs文件)更好。这不是强求的但是对你的整个程序一致性方面是有用的。
Log the calculation progress by adding the following code to the OnCalculating method in the Calculator.cs file. 通过在OnCalculating方法中添加下面代码来记录计算过程日志。
protected void OnCalculating(CalculatingEventArgs args) { // TODO: Log progress Logger.Write( string.Format("Calculating next 9 digits from {0}", args.StartingAt), Category.General, Priority.Low, 100); if (Calculating != null) Calculating(this, args); if (args.Cancel == true) { // TODO: Log cancellation Logger.Write("Calculation cancelled by user!", Category.General, Priority.High, 100); } } |
protected void OnCalculatorException(CalculatorExceptionEventArgs args) { // TODO: Log exception if (!(args.Exception is ConfigurationErrorsException)) { Logger.Write(args.Exception, Category.General, Priority.High, 100); } if (CalculatorException != null) CalculatorException(this, args); } |
You must test that the exception type is not a ConfigurationErrorsException as you would not be able to use the Logger if it has not been correctly configured. 你必须测试异常类型不是ConfigurationErrorsException,否则如果有任何不正确配置你就不能使用Looger。
You would normally use the Enterprise Library Exception Handling Application Block to create a consistent strategy for processing exceptions. 你可以简单的使用企业库异常处理应用程序块来创建一个一致的策略来处理异常。
To run the application 运行程序
Note: Sources used in the event log trace listener must be registered with the event log. The event log trace listener automatically registers a new source the first time it is used, but this requires administrative privileges, so running the application as an administrator the first time is necessary.
注意:在事件日志追踪监听器中使用的源,必须被注册到事件记录。事件记录追踪监听器在其第一次被调用时自动注册一个新的源,但是这需要管理员权限,所以在第一次运行程序的是有需要使用管理员身份运行。
Often, you would like to time the execution of sections of your application. The Logging Application Block includes tracing, which allows you to bookend a section of code and log the execution time. 通常,你会设定你的程序在不同场景的运行用时。在日志应用程序块中包含了tracing,它允许你定义一个代码场景和记录执行用时间
To add tracing to the application 向程序添加tracing追踪
public Calculator() {
} |
public string Calculate(int digits) { StringBuilder pi = new StringBuilder("3", digits + 2); string result = null; try { if (digits > 0) { // TODO: Add Tracing around the calculation using (Tracer trace = traceMgr.StartTrace(Category.Trace)) { pi.Append("."); for (int i = 0; i < digits; i += 9) { CalculatingEventArgs args; args = new CalculatingEventArgs(pi.ToString(), i+1); OnCalculating(args); // Break out if cancelled if (args.Cancel == true) break; // Calculate next 9 digits int nineDigits = NineDigitsOfPi.StartingAt(i+1); int digitCount = Math.Min(digits - i, 9); string ds = string.Format("{0:D9}", nineDigits); pi.Append(ds.Substring(0, digitCount)); } } } result = pi.ToString(); // Tell the world I‘ve finished! OnCalculated(new CalculatedEventArgs(result)); } catch (Exception ex) { // Tell the world I‘ve crashed! OnCalculatorException(new CalculatorExceptionEventArgs(ex)); } return result; } |
The tracer will stop timing, and log its end trace message, when it is disposed. The using block guarantees that Dispose will be called on the tracer at the end of the block. Allowing the garbage collector to dispose of the tracer will result in incorrect timings. Tracer将会停止计时,然后当它被回收时,将消息记录在trace消息的结尾。Using块保证了在块结束的时候会调用tracer的Dispose。允许垃圾回收器回收tracer将会返回计算的时间。
private static LoggingConfiguration BuildProgrammaticConfig() { // Formatter TextFormatter formatter = new TextFormatter("Timestamp: {timestamp(local)}{newline}Message: {message}{newline}Category: {category}{newline}Priority: {priority}{newline}EventId: {eventid}{newline}ActivityId: {property(ActivityId)}{newline}Severity: {severity}{newline}Title:{title}{newline}");
// Trace Listeners var eventLog = new EventLog("Application", ".", "EnoughPI"); var eventLogTraceListener = new FormattedEventLogTraceListener(eventLog, formatter); // Build Configuration var config = new LoggingConfiguration(); config.AddLogSource(Category.General, SourceLevels.All,
true).AddTraceListener(eventLogTraceListener); return config; } |
private static LoggingConfiguration BuildProgrammaticConfig() { // Formatter TextFormatter formatter = new TextFormatter("Timestamp: {timestamp(local)}{newline}Message: {message}{newline}Category: {category}{newline}Priority: {priority}{newline}EventId: {eventid}{newline}ActivityId: {property(ActivityId)}{newline}Severity: {severity}{newline}Title:{title}{newline}");
// Trace Listeners var eventLog = new EventLog("Application", ".", "EnoughPI"); var eventLogTraceListener = new FormattedEventLogTraceListener(eventLog, formatter);
// Build Configuration var config = new LoggingConfiguration(); | ||||||||||||||||||
config.AddLogSource(Category.General, SourceLevels.All, true).AddTraceListener(eventLogTraceListener);
config.IsTracingEnabled = true;
return config; } |
This Flat File Trace Listener will use the same Text Formatter utilized in the Event Log. The event source added is called "Trace", utilizing the constant Category name Trace 这个Flat File Trace监听器将会使用与Event Log相同的文本格式器。事件源添加这个叫做"Trace",利用常量分类名Trace(见EnoughPI.Logging项目的Constants.cs文件)。
(see Constants.cs in the EnoughPI.Logging project). Using the ActivityTracing source level will restrict the trace logging to the start and end log entries only.使用ActivityTracing源级别将会约束trace仅仅记录开始和结束的日志条目。
To run the application with tracing 在tracing下运行应用程序
---------------------------------------- Timestamp: 13/12/2005 6:08:01 AM Message: Start Trace: Activity ‘8c07ce3b-235b-4a51-bdcc-83a5997c989e‘ in method ‘Calculate‘ at 71661842482 ticks Category: Trace Priority: 5 EventId: 1 Severity: Start Title:TracerEnter Machine: ########## Application Domain: EnoughPI.exe Process Id: 6016 Process Name: C:\Program Files\Microsoft Enterprise Library\labs\cs\Logging\exercises\ex01\begin\EnoughPI\bin\EnoughPI.exe Win32 Thread Id: 6092 Thread Name: Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 13/12/2005 6:08:01 AM Message: End Trace: Activity ‘8c07ce3b-235b-4a51-bdcc-83a5997c989e‘ in method ‘Calculate‘ at 71662624219 ticks (elapsed time: 0.218 seconds) Category: Trace Priority: 5 EventId: 1 |
Severity: Stop
Title:TracerExit
Machine: ##########
Application Domain: EnoughPI.exe
Process Id: 6016
Process Name: C:\Program Files\Microsoft Enterprise
Library\labs\cs\Logging\exercises\ex01\begin\EnoughPI\bin\EnoughPI.exe Win32 Thread Id: 6092
Thread Name:
Extended Properties:
----------------------------------------
Your file should look similar to the above output, though will have different values for the GUID, machine name, and other process-specific details. 你的文件看起来跟上面的输出相似,不过会有一些不同的值,例如GUID,机器名和其他处理细节信息。
3.Close the application and Visual Studio. 关闭程序和Visual Studio。
To verify that you have completed the exercise correctly, you can use the solution provided in the ex01\end folder. 要验证你是否正确的完成了练习,你可打开提供的ex01\end文件夹的项目,对比你的练习结果。
原文:http://www.cnblogs.com/Arnu/p/loggingblock1.html