程序与技术分享:Catel帮助手册

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 程序与技术分享:Catel帮助手册

1,简介


从2.2版本开始,Catel使用了一个自定义的日志系统,这种方式,针对log4net的引用可以被移除,做这个修改主要是为了不强迫用户使用log4net,同时,log4net看起来很长时间不更新了,其他的日志系统如NLog看起来在增长,新的日志系统将允许许多基础的日志,这样,日志将将非常简单,并且如果他需要,真正的日志将被用户执行。


1.1 Log和ILog


所有的日志将通过ILog接口。这个接口被自动的注册到Catel中的所有对象上作为Log字段,ILog接口仅仅有一个实现,每个对象能够调用Log自动的方法来记录任何信息。


在Catel中,仅仅有一个类继承与ILog接口,那就是Log类,这个类确保了日志消息能够正确的格式化,并且在消息写入日志的时候会触发LogMessage事件。


Cate内部创建了一个独立的Log类型,这样,开发者能够在许多日志中筛选它自己感兴趣的日志。


1.2 LogManager


LogManager是一个管理类,它将为类型创建新的日志,但是也跟踪所有的日志和日志监听,为了返回一个指定类的日志,可以使用如下代码。


private static readonly ILog Log = LogManager.GetCurrentClassLogger();


1.3 用代码记录日志


使用代码记录日志,ILog接口实现一些基础的方法来记录信息和一些额外数据选项,有一些扩展方法可以记录异常,字符串格式,等等,下面是记录履历的例子:


Log.Warning("Customer '{0}' does not exist", customerId);


或者,如果异常有效,也能写入到日志中。


Log.Error(ex, "Failed to delete file '{0}'", fileName);


1.4 记录到output窗口或者console中


默认情况下,Catel并不增加任何监听,然后,它包含一个立即可用的实现将日志写入到output窗口或者console中,这个就是DebugLogListener,为了注册这个监听,可以使用如下代码。


#if DEBUG


LogManager.AddDebugListener();


#endif


在Catel3.8之前,使用的是LogManager.RegisterDebugListener()


1.5 重写全局的标记级别


从3.8开始可以针对所有的监听重写全区日志标记,如果要这样做,在LogManager上设置一直的值,例如,在所有的监听上强制显示调试履历,使用如下代码:


LogManager.IsDebugEnabled = //代码效果参考:http://www.lyjsj.net.cn/wx/art_24207.html

true;

要重写设置override,设置值为空:


LogManager.IsDebugEnabled = null;


2,自定义监听


每一个监听都可以自定义来返回监听者感兴趣的日志,这样,监听者如果不感兴趣,可以不返回事件,例如,仅仅返回错误,创建一个新的监听如下:


var listener = new MyLogListener();


listener.IsDebugEnabled = false;


listener.IsInfoEnabled = false;


listener.IsWarningEnabled = false;


listener.IsErrorEnabled = true;


默认情况下,所有的日志都会被监听。


3,批量日志监听


批量日志监听是继承IBatchLogListener接口的类(大部分可能继承与BatchLogListenerBase),这个接口增加了一个Flushmethod方法,允许监听者被清理掉,进一步的是日志监听写了一个较慢的监听存储。这个将不会访问每一个源头,而只是批量处理。


3.1 Flushing所有的监听者


当使用批量日志监听者时,当应用程序异常或者是退出时清理所有监听者时很重要的,这是因为有些重要的日志没有持久化到文件中的会丢失掉。


要flushing所有的监听者需要使用如下代码


LogManager.FlushAll();


3.2 实现一个自定义的IBatchLogListener


当实现一个通用的批量日志监听者,常用的方式是继承BatchLogListenerBase类,这个有如下优点:


1,//代码效果参考:http://www.lyjsj.net.cn/wx/art_24205.html

BatchLogListenerBase是线程安全的

2,BatchLogListenerBase每5秒钟会自动的flushes监听者。


你只需要实现WriteLog方法来决定持久化存储的入口,下面是例子:


public class FileLogListener : BatchLogListenerBase


{


private readonly string _filePath;


private readonly int _maxSizeInKiloBytes;


public FileLogListener(string filePath, int maxSizeInKiloBytes)


{


Argument.IsNotNullOrWhitespace(() => filePath);


_filePath = filePath;


_maxSizeInKiloBytes = maxSizeInKiloBytes;


}


protected override void WriteBatch(System.Collections.Generic.List batchEntries)


{//代码效果参考:http://www.lyjsj.net.cn/wz/art_24203.html


try


{


var fileInfo = new FileInfo(_filePath);


if (fileInfo.Exists && (fileInfo.Length / 1024 >= _maxSizeInKiloBytes))


{


CreateCopyOfCurrentLogFile(_filePath);


}


using (var fileStream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.Read))


{


using (var writer = new StreamWriter(fileStream))


{


foreach (var batchEntry in batchEntries)


{


var message = FormatLogEvent(batchEntry.Log, batchEntry.Message, batchEntry.LogEvent, batchEntry.ExtraData);


writer.WriteLine(message);


}


}


}


}


catch (Exception)


{


// Swallow


}


}


private void CreateCopyOfCurrentLogFile(string filePath)


{


for (int i = 1; i < 999; i++)


{


var possibleFilePath = string.Format("{0}.{1:000}", filePath, i);


if (!File.Exists(possibleFilePath))


{


File.Move(filePath, possibleFilePath);


}


}


}


}


5,集成第三方日志功能


Catel中的日志默认并不写任何输出,这个给了开发者自由,可以使用任何最终的日志机制来处理它。例如Catel可以很容易的使用log4net或者NLOG来集成,通常,下面步骤需要来执行去集成日志。


1,创建自己的或者使用LogListenerBase创建一个自定义的ILogListener


2, 使用LogManager.AddListener将其注册进去。


5.1 集成Log4net方法


下面的例子为Log4net提供了一个ILogListener,但是有些额外的Log库可以被使用。


5.1.1 创建Listener


通过继承LogListenerBase来创建一个新的类:


public class Log4netListener : LogListenerBase


{


protected override void Debug(ILog log, string message, object extraData)


{


var finalLog = log4net.LogManager.GetLogger(log.TargetType);


finalLog.Debug(message);


}


protected override void Info(ILog log, string message, object extraData)


{


var finalLog = log4net.LogManager.GetLogger(log.TargetType);


finalLog.Info(message);


}


protected override void Warning(ILog log, string message, object extraData)


{


var finalLog = log4net.LogManager.GetLogger(log.TargetType);


finalLog.Warn(message);


}


protected override void Error(ILog log, string message, object extraData)


{


var finalLog = log4net.LogManager.GetLogger(log.TargetType);


finalLog.Error(message);


}


}


5.1.2 注册一个监听


最后同样重要的,去注册这个监听


LogManager.AddListener(new Log4netListener());


5.1.3 配置log4net


注意,这仅仅是一个简单的配置,请查看log4net文档看所有的选项:


1,增加log4net的引用


2,增加【assembly: log4net.Config.XmlConfigurator(Watch = true)】 到AssemblyInfo.cs


3,在app.config中配置log4net的实际数据


5.2继承NLog方法


下面的例子为NLog提供了一个ILogListener,但是有些额外的Log库可以被使用。


5.2.1 创建Listener


通过继承LogListenerBase来创建一个新的类:


public class NLogListener : LogListenerBase


{


protected override void Debug(ILog log, string message, object extraData)


{


var finalLog = NLog.LogManager.GetLogger(log.TargetType.ToString());


finalLog.Debug(message);


}


protected override void Info(ILog log, string message, object extraData)


{


var finalLog = NLog.LogManager.GetLogger(log.TargetType.ToString());


finalLog.Info(message);


}


protected override void Warning(ILog log, string message, object extraData)


{


var finalLog = NLog.LogManager.GetLogger(log.TargetType.ToString());


finalLog.Warn(message);


}


protected override void Error(ILog log, string message, object extraData)


{


var finalLog = NLog.LogManager.GetLogger(log.TargetType.ToString());


finalLog.Error(message);


}


}


5.1.2 注册一个监听


最后同样重要的,去注册这个监听


LogManager.AddListener(new NLogListener());


6,将日志写入到磁盘


Catel也支持非常轻量监听来允许其他的外部库,创建一个监听,先创建一个新的类来继承与ILogListener,下一步,将其注册到LogManager中。


ILogListener针对每个LogEvent有一个独立的方法,但是也有一个共享的方法来调用,例如,如果debug信息被写入日志中,Write和Debug方法都会在ILogListener上被调用。


注意:要看批量写入磁盘的例子,可以看前面的日志更新


注意:Catel已经包含了一个FileLogListener,不需要重写这个类,它作为一个例子是很容易理解的。


6.1创建一个监听


可以写一个新的类继承于LogListenerBase。


public class FileLogListener : LogListenerBase


{


private readonly TextWriter _textWriter;


public FileLogListener(string fileName)


{


Argument.IsNotNullOrWhitespace("fileName", fileName);


FileName = fileName;


_textWriter = new StreamWriter(fileName, true);


}


public string FileName { get; private set; }


public override void Write(ILog log, string message, LogEvent logEvent)


{


_textWriter.WriteLine(message);


}


}


6.2 注册监听


最后同样重要的注册这个监听


LogManager.AddListener(new FileLogListener(""));


7,通过配置文件来创建监听


从3.8开始,可以通过配置文件初始化LogListener,下面是一个例子


[/span>configSections

[/span>sectionGroup name="catel"

[/span>section name="logging" type="Catel.Logging.LoggingConfigurationSection, Catel.Core" />




[/span>catel

[/span>logging

[/span>listeners

[/span>listener type="Catel.Logging.FileLogListener" FilePath="CatelLogging.txt" IgnoreCatelLogging="true" IsDebugEnabled="false" IsInfoEnabled="true" IsWarningEnabled="true" IsErrorEnabled="true"/>





上面Logging节点,需要保护一个没有限制数量的监听,每个监听中至少要提供类型的命名空间


[/span>listener type="Catel.Logging.FileLogListener" />


其他的属性是自定义的,者意味着可以自定义每个加入进来的监听,下面是注册FileLogListener的配置


[/span>listener type="Catel.Logging.FileLogListener" FilePath="CatelLogging.txt" IgnoreCatelLogging="true"


IsDebugEnabled="false" IsInfoEnabled="true" IsWarningEnabled="true" IsErrorEnabled="true"/>


ILogListenr属性(IsDebugEnabled, IsInfoEnabled, IsWarningEnabled and IsErrorEnabled)是对所有的监听有效的,其他的选项依赖于具体的监听类,这样可以提高运行时的灵活性。


8,Antor.Catel.Fody


日志对应用程序是非常重要的,他在应用程序已经部署了很多客户端后,提供了应用程序运行的细节信息。这也是为什么日志是Catel框架中的第一个类。


通常日志通过定义一个继承ILog类的事例来完成。


private static readonly ILog Log = LogManager.GetCurrentClassLogger();


然后通过如下方式来进行调用


Log.Info("This is a logging with a format '{0}'", "test");


写日志定义是无聊和重复的,幸运的是Simon Cropp作为这个的一个解决方案出现了,称之为Antor.Catel.Fody,通过Anotar的实现,引用将被加入到解决方案中,然后在编译了程序集后会被移除,所有针对Log调用的类将会被Catel中实际的类所替换。


8.1 如何使用Antor


使用Antor非常简单,只需要调用LogTo类的静态方法,如下所示:


LogTo.Info("This is a logging with a format '{0}'", "test");


注意,再不需要Log字段了,它将被Anotar自动添加,除了它非常好用外,它执行效率非常高,GetCurrentClassLogger类使用反射来确定当前类,第一次(只会执行一次,因为是静态的)被使用的时候不太影响效率。Anotar通过如下的方式替换调用实现。


private static readonly ILog Log = LogManager.GetLogger(typeof(MyClass));


8.2 附加属性


8.2.1 不显示方法名和行号


通过默认的Anotar记录时会显示方法名和行号


03:58:11:858 => 【DEBUG】 【AnotarDemo.Program】 Method: 'Void Main(String【】)'. Line: ~19. this is a test


如果你不想要这样输出,你可以增加如下特性:


【assembly: LogMinimalMessage】


那么输出文件会显示成如下信息


03:59:36:344 => 【DEBUG】 【AnotarDemo1.Program】 this is a test

相关实践学习
日志服务之数据清洗与入湖
本教程介绍如何使用日志服务接入NGINX模拟数据,通过数据加工对数据进行清洗并归档至OSS中进行存储。
相关文章
|
2月前
|
前端开发 Linux Shell
|
2月前
|
网络协议 Linux Shell
|
2月前
|
网络协议 Linux 开发工具
linux常用命令三
linux常用命令三
21 4
|
2月前
|
Web App开发 Java Linux
linux常用命令一
linux常用命令一
35 4
|
2月前
|
Linux 网络安全
Linux常用命令
Linux常用命令
|
2月前
|
运维 Linux Shell
Linux常用命令(非常详细!)
Linux常用命令(非常详细!)
24 0
|
4天前
|
存储 Windows
技术好文共享:(翻译)libusb
技术好文共享:(翻译)libusb
12 0
|
4天前
|
传感器 Unix 5G
技术心得记录:关于灰度的一些知识(转)
技术心得记录:关于灰度的一些知识(转)
|
4天前
|
JSON Java API
技术笔记:springboot项目使用拦截器实现一个简单的网关请求透传
技术笔记:springboot项目使用拦截器实现一个简单的网关请求透传
|
4天前
|
编译器 API 数据库
技术好文共享:(xxxx)十一:SQLite3的db数据库解密(三)数据库在线备份
技术好文共享:(xxxx)十一:SQLite3的db数据库解密(三)数据库在线备份