Enterprise Library Step By Step系列(八):日志和监测应用程序块——进阶篇

简介:
写在前面:最近一段时间项目比较紧,所以这篇随笔出来的晚一些。今天写的是在日志里面包含名 - 值对的字典,跟踪活动并记录上下文信息,过滤事件,定制日志消息的格式,自定义 Sink ,自定义 Formatter 等。
一.在日志里面包含名 - 值对的字典:
在日志消息里面,我们可以包含名 - 值对这样的字典。这时首先需要创建一个 Hashtable ,通过 Key-Value 的方式把要记录的内容传入。示例代码如下:
 1 ExpandedBlockStart.gif ///创建一个日志项
 2 None.gif             LogEntry log  =   new  LogEntry();
 3 None.gif            
 4 ExpandedBlockStart.gif             ///创建名-值对
 5 None.gif             Hashtable logtable  =   new  Hashtable();
 6 None.gif            logtable[ " key1 " =   " value1 " ;
 7 None.gif            logtable[ " key2 " =   " value2 " ;
 8 None.gif            logtable[ " key3 " =   " value3 " ;
 9 None.gif            
10 None.gif            log.Message  =   this .txt_LogMessage.Text;
11 None.gif            log.Category  =  Category.General;
12 None.gif            log.Priority  =  Priority.Normal;
13 None.gif            
14 ExpandedBlockStart.gif             ///写入日志
15 None.gif             Logger.Write(log,logtable);
输出后的文本:在这里我们用了 Text Formatter

二.跟踪活动并记录上下文信息:
跟踪应用系统的活动是一项常见的功能,我们需要把活动的起始时间和结束时间以及活动的其他的信息记录下来。日志和监测应用程序块支持通过活动 ID 来跟踪一项活动,活动 ID 可以在代码中指定,也可以通过程序块来自动生成,程序块自动记录活动的起始时间和结束时间。活动跟踪由 Tracer 类来提供。示例代码如下:
1 None.gif using ( new  Tracer( " UI Events " ))
2 ExpandedBlockStart.gif             {
3InBlock.gif                Logger.Write("Troubleshooting message");
4ExpandedBlockEnd.gif            }
输出后的文本:同样我们用了 Text Formatter
三.过滤事件:
在日志和监测应用程序块里面,支持两种方式的过滤事件:基于优先级过滤事件和基于类别过滤事件。过滤的过程发生在日志项传递给分发策略之前。在入门篇里我们知道,每个日志消息都会有一个优先级,我们可以在代码中指定或默认值为 -1 。我们可以通过配置  Client Setting 使低于某个优先级的消息被过滤掉,只记录某个类别的消息或者过滤掉具有某个类别的日志项。
在下面的图中,日志项为 0 1 的消息将不被记录。

Client Setting
CategoryFilterSettings 属性决定某个类别的日志是被记录还是被过滤掉。我们可以自行进行设置:

在下图中,
”UI Events” 类别的日志将不被记录。

四.定制日志消息的格式:
Formatter 接受一个日志项的并返回一个格式化的字符串,应用程序块格式化将字符串传给 Sink Text Formatter  使用模版生成格式化字符串,在应用配置中可以有多个  Text Formatters ,每个有自己的模版同时我们也可以定制自己的  Formatter
日志项根据其类别导向到目的地目的地规定了  Formatter 和接收格式化日志项的 Sink

Text Formatter 
有一个模版配置属性。
模版编辑器定制日志项的格式,  { 参数 } 由日志项的值填充。

五.创建和使用自定义
Sink
在日志和监测应用应用程序块里面,允许我们自定义一个 Sink ,而且使用方法要比其它的应用程序块中的自定义简单的多。下面我们具体看一下:
1 .添加对应用程序块的引用:
Microsoft.Practices.EnterpriseLibrary.Configuration.dll
Microsoft.Practices.EnterpriseLibrary.Logging.dll
2 .添加命名空间:
1 None.gif using  Microsoft.Practices.EnterpriseLibrary.Configuration;
2 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging;
3 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging.Sinks;
4 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
3 .编写代码:
我们的自定义 Sink 要继承 LogSink 这个基类,同时要重载Initialize()和SendMessageCore()这两个抽象方法
 1 None.gif using  System;
 2 None.gif using  Microsoft.Practices.EnterpriseLibrary.Configuration;
 3 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging;
 4 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging.Sinks;
 5 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
 6 None.gif
 7 None.gif namespace  EnterpriseLogging
 8 ExpandedBlockStart.gif {
 9ExpandedSubBlockStart.gif    /// <summary>
10InBlock.gif    /// 功能说明:自定义Sink
11ExpandedSubBlockEnd.gif    /// </summary>

12InBlock.gif    public class ConsoleSink:  LogSink
13ExpandedSubBlockStart.gif    {
14InBlock.gif        private LoggingConfigurationView configView;
15InBlock.gif 
16InBlock.gif        public override void Initialize(ConfigurationView configurationView)
17ExpandedSubBlockStart.gif        {
18InBlock.gif            this.configView = configurationView as LoggingConfigurationView;
19ExpandedSubBlockEnd.gif        }
 
20InBlock.gif 
21InBlock.gif        protected override void SendMessageCore(LogEntry logEntry)
22ExpandedSubBlockStart.gif        {
23InBlock.gif            CustomSinkData sinkData;
24InBlock.gif            sinkData = (CustomSinkData) this.configView.GetSinkData(this.ConfigurationName); 
25InBlock.gif 
26ExpandedSubBlockStart.gif            /// Delimit each log entry
27InBlock.gif            Console.WriteLine((string) sinkData.Attributes["delimiter"]); 
28InBlock.gif 
29ExpandedSubBlockStart.gif            /// Write the formatted log entry to the Console
30InBlock.gif            Console.WriteLine(FormatEntry(logEntry));
31ExpandedSubBlockEnd.gif        }
 
32ExpandedSubBlockEnd.gif    }

33ExpandedBlockEnd.gif}

34 None.gif
4 .打开配置工具,并打开配置文件。在 Sink 节点上,我们选择 Custom Sink 。同时起名为 Console Sink

5
.单击 TypeName 右边的省略号,打开 Type Selector 对话框。单击Load an Assembly …,并浏览选择我们工程文件的DLL。最后选择Console Sink类。

6
.单击Attributes 打开NameValueItem Collection Editor。单击Add创建一个新的NameValueItem,起名为delimiter,并设置它的Value值(这个值可以随意设置,比如我们设置************************)。

7.选择General,创建一个Destination,并设置下列属性:
·   Formatter = Text Formatter,
·   Name = Console Destination
·   Sink = Console Sink
8 .把程序输出的方式设为控制台的方式,运行程序。
六.创建和使用自定义 Formatter
1 .添加如下的命名空间:
1 None.gif using  System.Globalization;
2 None.gif using  System.IO;
3 None.gif using  System.Xml;
4 None.gif using  Microsoft.Practices.EnterpriseLibrary.Configuration;
5 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging;
6 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
7 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
2 .以 Hands On Lab 里面的 XmlFormatter 为例,在自定义 Formatter 时我们需要继承ConfigurationProvider类和实现 IlogFormatter接口,并且需要重载Initialize()这个抽象方法。
 1 None.gif using  System;
 2 None.gif using  System.Globalization;
 3 None.gif using  System.IO;
 4 None.gif using  System.Xml;
 5 None.gif using  Microsoft.Practices.EnterpriseLibrary.Configuration;
 6 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging;
 7 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
 8 None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
 9 None.gif
10 None.gif namespace  LoggingSink
11 ExpandedBlockStart.gif {
12ExpandedSubBlockStart.gif    /// <summary>
13InBlock.gif    /// 功能说明:自定义Formatter
14ExpandedSubBlockEnd.gif    /// </summary>

15InBlock.gif    public class XmlFormatter : ConfigurationProvider, ILogFormatter
16ExpandedSubBlockStart.gif    {
17InBlock.gif        private LoggingConfigurationView configView = null;
18InBlock.gif 
19InBlock.gif        public override void Initialize(ConfigurationView configurationView)
20ExpandedSubBlockStart.gif        {
21InBlock.gif            this.configView = (LoggingConfigurationView) configurationView;
22ExpandedSubBlockEnd.gif        }
 
23InBlock.gif 
24InBlock.gif        public string Format(LogEntry log)
25ExpandedSubBlockStart.gif        {
26InBlock.gif            using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
27ExpandedSubBlockStart.gif            {
28InBlock.gif                XmlTextWriter w = new XmlTextWriter(sw);
29InBlock.gif                w.Formatting = Formatting.Indented;
30InBlock.gif                w.Indentation = 2
31InBlock.gif                w.WriteStartDocument(true);
32InBlock.gif                w.WriteStartElement("logEntry");
33InBlock.gif                w.WriteAttributeString("Category", log.Category);
34InBlock.gif                w.WriteAttributeString("Priority", log.Priority.ToString(CultureInfo.InvariantCulture)); 
35InBlock.gif                w.WriteElementString("Timestamp", log.TimeStampString);
36InBlock.gif                w.WriteElementString("Message", log.Message);
37InBlock.gif                w.WriteElementString("EventId", log.EventId.ToString(CultureInfo.InvariantCulture));
38InBlock.gif                w.WriteElementString("Severity", log.Severity.ToString(CultureInfo.InvariantCulture));
39InBlock.gif                w.WriteElementString("Title", log.Title);
40InBlock.gif                w.WriteElementString("Machine", log.MachineName);
41InBlock.gif                w.WriteElementString("AppDomain", log.AppDomainName);
42InBlock.gif                w.WriteElementString("ProcessId", log.ProcessId);
43InBlock.gif                w.WriteElementString("ProcessName", log.ProcessName);
44InBlock.gif                w.WriteElementString("Win32ThreadId", log.Win32ThreadId);
45InBlock.gif                w.WriteElementString("ThreadName", log.ManagedThreadName);
46InBlock.gif                w.WriteEndElement();
47InBlock.gif                w.WriteEndDocument(); 
48InBlock.gif                return sw.ToString();
49ExpandedSubBlockEnd.gif            }

50ExpandedSubBlockEnd.gif        }
 
51ExpandedSubBlockEnd.gif    }

52ExpandedBlockEnd.gif}

53 None.gif
对于自定义的Formatter我们就介绍到这儿了,它的使用和一般的Formatter没有大的区别,只不过在创建Formatter时我们需要创建一个Custom Formatter,在这里我就不多写了。
  结束语:这篇日志和监测应用程序块的进阶篇文章就到这里了,希望能给初学的朋友一些帮助。后面我会写缓存应用程序块的使用。















本文转自lihuijun51CTO博客,原文链接: http://blog.51cto.com/terrylee/67610  ,如需转载请自行联系原作者





相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3小时前
|
存储 运维 监控
【Flume】flume 日志管理中的应用
【4月更文挑战第4天】【Flume】flume 日志管理中的应用
|
3小时前
|
监控 Serverless 数据库
Serverless 应用引擎常见问题之biphon-education-配置了SLS后一直重启如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
29 5
|
3小时前
|
监控 安全 数据可视化
中间件应用日志记录和监控
【5月更文挑战第1天】中间件应用日志记录和监控
23 3
中间件应用日志记录和监控
|
3小时前
|
Dubbo Java Serverless
Serverless 应用引擎操作报错合集之Nacos中nacos启动正常,访问白页,启动日志显示正常如何解决
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
25 0
Serverless 应用引擎操作报错合集之Nacos中nacos启动正常,访问白页,启动日志显示正常如何解决
|
3小时前
|
监控 JavaScript Java
|
3小时前
|
存储 Prometheus 监控
Flask监控与日志记录:掌握应用运行状况
【4月更文挑战第16天】本文介绍了在Flask应用中实现监控和日志记录的方法,以确保应用稳定性和问题排查。推荐使用Prometheus、Grafana、New Relic或Flask-MonitoringDashboard等工具进行监控,并通过Python的logging模块记录日志。监控集成涉及安装配置工具、添加监控代码,而日志管理则需要集中存储和使用分析工具。安全是关键,要防止未授权访问和数据泄露,避免记录敏感信息。监控和日志记录有助于提升应用性能和用户体验。
|
3小时前
|
存储 SQL Serverless
Serverless 应用引擎常见问题之应用下的【应用事件】以及企业级特性下的【事件中心】没有日志如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
34 0
|
3小时前
|
C++
JNI Log 日志输出
JNI Log 日志输出
18 1
|
3小时前
|
存储 运维 大数据
聊聊日志硬扫描,阿里 Log Scan 的设计与实践
泛日志(Log/Trace/Metric)是大数据的重要组成,伴随着每一年业务峰值的新脉冲,日志数据量在快速增长。同时,业务数字化运营、软件可观测性等浪潮又在对日志的存储、计算提出更高的要求。
|
3小时前
|
XML Java Maven
Springboot整合与使用log4j2日志框架【详解版】
该文介绍了如何在Spring Boot中切换默认的LogBack日志系统至Log4j2。首先,需要在Maven依赖中排除`spring-boot-starter-logging`并引入`spring-boot-starter-log4j2`。其次,创建`log4j2-spring.xml`配置文件放在`src/main/resources`下,配置包括控制台和文件的日志输出、日志格式和文件切分策略。此外,可通过在不同环境的`application.yml`中指定不同的log4j2配置文件。最后,文章提到通过示例代码解释了日志格式中的各种占位符含义。