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

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

二.跟踪活动并记录上下文信息:
跟踪应用系统的活动是一项常见的功能,我们需要把活动的起始时间和结束时间以及活动的其他的信息记录下来。日志和监测应用程序块支持通过活动 ID 来跟踪一项活动,活动 ID 可以在代码中指定,也可以通过程序块来自动生成,程序块自动记录活动的起始时间和结束时间。活动跟踪由 Tracer 类来提供。示例代码如下:
1 using ( new  Tracer( " UI Events " ))
2              {
3                Logger.Write("Troubleshooting message");
4            }
输出后的文本:同样我们用了 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 using  Microsoft.Practices.EnterpriseLibrary.Configuration;
2 using  Microsoft.Practices.EnterpriseLibrary.Logging;
3 using  Microsoft.Practices.EnterpriseLibrary.Logging.Sinks;
4 using  Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
3 .编写代码:
我们的自定义 Sink 要继承 LogSink 这个基类,同时要重载Initialize()和SendMessageCore()这两个抽象方法
 1 using  System;
 2 using  Microsoft.Practices.EnterpriseLibrary.Configuration;
 3 using  Microsoft.Practices.EnterpriseLibrary.Logging;
 4 using  Microsoft.Practices.EnterpriseLibrary.Logging.Sinks;
 5 using  Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
 6
 7 namespace  EnterpriseLogging
 8 {
 9    /// <summary>
10    /// 功能说明:自定义Sink
11    /// </summary>

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

33}

34
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 using  System.Globalization;
2 using  System.IO;
3 using  System.Xml;
4 using  Microsoft.Practices.EnterpriseLibrary.Configuration;
5 using  Microsoft.Practices.EnterpriseLibrary.Logging;
6 using  Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
7 using  Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
2 .以 Hands On Lab 里面的 XmlFormatter 为例,在自定义 Formatter 时我们需要继承ConfigurationProvider类和实现 IlogFormatter接口,并且需要重载Initialize()这个抽象方法。
 1 using  System;
 2 using  System.Globalization;
 3 using  System.IO;
 4 using  System.Xml;
 5 using  Microsoft.Practices.EnterpriseLibrary.Configuration;
 6 using  Microsoft.Practices.EnterpriseLibrary.Logging;
 7 using  Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
 8 using  Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
 9
10 namespace  LoggingSink
11 {
12    /// <summary>
13    /// 功能说明:自定义Formatter
14    /// </summary>

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

50        }
 
51    }

52}

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















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





相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2月前
|
机器学习/深度学习 存储 监控
Elasticsearch 在日志分析中的应用
【9月更文第2天】随着数字化转型的推进,日志数据的重要性日益凸显。日志不仅记录了系统的运行状态,还提供了宝贵的洞察,帮助企业改进产品质量、优化用户体验以及加强安全防护。Elasticsearch 作为一个分布式搜索和分析引擎,因其出色的性能和灵活性,成为了日志分析领域的首选工具之一。本文将探讨如何使用 Elasticsearch 作为日志分析平台的核心组件,并详细介绍 ELK(Elasticsearch, Logstash, Kibana)栈的搭建和配置流程。
270 4
|
3月前
|
Java API 开发者
你的应用是不是只有service_stdout.log?
本文记录了logback-spring.xml文件不生效问题的整体排查思路。
|
14天前
|
存储 SQL 监控
|
14天前
|
自然语言处理 监控 数据可视化
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
46 2
|
3月前
|
Java 应用服务中间件 HSF
Java应用结构规范问题之配置Logback以仅记录错误级别的日志到一个滚动文件中的问题如何解决
Java应用结构规范问题之配置Logback以仅记录错误级别的日志到一个滚动文件中的问题如何解决
|
3月前
|
数据库 Java 监控
Struts 2 日志管理化身神秘魔法师,洞察应用运行乾坤,演绎奇幻篇章!
【8月更文挑战第31天】在软件开发中,了解应用运行状况至关重要。日志管理作为 Struts 2 应用的关键组件,记录着每个动作和决策,如同监控摄像头,帮助我们迅速定位问题、分析性能和使用情况,为优化提供依据。Struts 2 支持多种日志框架(如 Log4j、Logback),便于配置日志级别、格式和输出位置。通过在 Action 类中添加日志记录,我们能在开发过程中获取详细信息,及时发现并解决问题。合理配置日志不仅有助于调试,还能分析用户行为,提升应用性能和稳定性。
57 0
|
15天前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
128 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
1月前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
231 3
|
1月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1636 14