【C#编程最佳实践 二十】日志与日志级别

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【C#编程最佳实践 二十】日志与日志级别

在日常的开发中我们经常会用到日志,最近开发的时候老是听到别的其他开发人员让测试把日志级别从debug降到info或者等等之类的,所以就比较好奇日志级别到底有哪几种以及各种日志级别到底是怎么发挥作用的呢?于是看了下公司的源码,发现我们的log类是继承自log4net的,所以简单学习下该类。

日志级别

在log4Net中有7种日志级别,其中常用的有5种: DEBUG,INFO,WARN,ERROR,FATAL。级别从低到高,依照等级次序决定是否写入。

日志级别 备注
ALL Level ALL Level是最低等级的,用于打开所有日志记录。
DEBUG Level DEBUG Level指出细粒度信息事件对调试应用程序是非常有帮助的。记录系统用于调试的一切信息,内容或者是一些关键数据内容的输出。
INFO level INFO level表明 消息在粗粒度级别上突出强调应用程序的运行过程。
WARN level WARN level表明会出现潜在错误的情形。 记录系统中不影响系统继续运行,但不符合系统运行正常条件,有可能引起系统错误的信息。例如,记录内容为空,数据内容不正确等。
ERROR level ERROR level指出虽然发生错误事件,但仍然不影响系统的继续运行。记录系统中出现的导致系统不稳定,部分功能出现混乱或部分功能失效一类的错误。例如,数据字段为空,数据操作不可完成,操作出现异常等。
FATAL level FATAL level指出每个严重的错误事件将会导致应用程序的退出,记录系统中出现的能使用系统完全失去功能,服务停止,系统崩溃等使系统无法继续运行下去的错误。例如,数据库无法连接,系统出现死循环
OFF Level OFF Level是最高等级的,用于关闭所有日志记录。

高于等级设定值方法都能写入日志, Off所有的写入方法都不写到日志里,ALL则相反。例如当我们设成Info时,logger.Debug就会被忽略而不写入文件,但是FATAL,ERROR,WARN,INFO会被写入,因为他们等级高于INFO。在生产环境,建议把debug的日志级别重新调为warn或者更高,避免产生大量日志

日志配置

日志级别了解后需要在系统内加一个日志的配置文件:Log4Net.config。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>
   <log4net debug="true">
      <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <!--file可以指定具体的路径 eg : d:\\test.log。不指定的话log被生成在项目的bin/Debug 或者 bin/Release目录下 (web的项目 默认生成在根目录下)-->
        <file value="applicationLog.log" />
        <appendToFile value="true" />
        <rollingStyle value="Size" />
        <maxSizeRollBackups value="10" /><!--备份log文件的个数最多10个-->
        <!--每个log文件最大是2M,如果超过2M将重新创建一个新的log文件,并将原来的log文件备份。-->
        <maximumFileSize value="2MB" />
        <staticLogFileName value="true" />
        <layout type="log4net.Layout.PatternLayout"> <!--指定log的格式-->
          <conversionPattern value="[%date]  %thread -- %-5level -- %logger [%M] -- %message%newline" />
        </layout>
      </appender>
      <root>
        <level value="DEBUG" /><!--指定将此级别及以上的log打印到log文件中-->
        <appender-ref ref="RollingLogFileAppender" />
      </root>
   </log4net>
</configuration>

整个步骤其实就是先引入log4net的dll,然后引入到自己的项目中来,然后添加配置到 assemblyinfo.cs文件:

[assembly: log4net.Config.XmlConfigurator(ConfigFile="Log4Net.config", Watch=true)]

log4net源码

部分log4net的源码,不仅仅包括各种异常的定义,也包含一些异常打点的标准格式方法。

// Decompiled with JetBrains decompiler
// Type: log4net.ILog
// Assembly: log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905
// MVID: 4BFEBC64-FD47-43B4-B376-302A10C947E5
// Assembly location: D:\MultiTenant项目\packages\log4net.1.2.10.1\lib\net11\log4net.dll
using log4net.Core;
using System;
namespace log4net
{
  public interface ILog : ILoggerWrapper
  {
    void Debug(object message);
    void Debug(object message, Exception exception);
    void DebugFormat(string format, params object[] args);
    void DebugFormat(IFormatProvider provider, string format, params object[] args);
    void Info(object message);
    void Info(object message, Exception exception);
    void InfoFormat(string format, params object[] args);
    void InfoFormat(IFormatProvider provider, string format, params object[] args);
    void Warn(object message);
    void Warn(object message, Exception exception);
    void WarnFormat(string format, params object[] args);
    void WarnFormat(IFormatProvider provider, string format, params object[] args);
    void Error(object message);
    void Error(object message, Exception exception);
    void ErrorFormat(string format, params object[] args);
    void ErrorFormat(IFormatProvider provider, string format, params object[] args);
    void Fatal(object message);
    void Fatal(object message, Exception exception);
    void FatalFormat(string format, params object[] args);
    void FatalFormat(IFormatProvider provider, string format, params object[] args);
    bool IsDebugEnabled { get; }
    bool IsInfoEnabled { get; }
    bool IsWarnEnabled { get; }
    bool IsErrorEnabled { get; }
    bool IsFatalEnabled { get; }
  }
}

最后总结下关于日志的一些收获:

总而言之,常用的日志级别其实就四种:DEBUG,INFO,WARN,ERROR。然后我们大多数情况下只关心ERROR就可以,如果有时候通过ERROR定位不出问题,name通过修改配置文件将打印的日志级别降低为WARN(可以看WARN,ERROR)或者INFO(可以看INFO,WARN,ERROR)甚至DEBUG(可以看DEBUG,INFO,WARN,ERROR)来获取更多的信息,所以我常听到的开发让测试同学修改日志级别就明白了,调的越低能看到更多的辅助查问题的信息然后来查问题

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
7天前
|
XML JSON 监控
告别简陋:Java日志系统的最佳实践
【10月更文挑战第19天】 在Java开发中,`System.out.println()` 是最基本的输出方法,但它在实际项目中往往被认为是不专业和不足够的。本文将探讨为什么在现代Java应用中应该避免使用 `System.out.println()`,并介绍几种更先进的日志解决方案。
24 1
|
18天前
|
安全 C# 数据安全/隐私保护
实现C#编程文件夹加锁保护
【10月更文挑战第16天】本文介绍了两种用 C# 实现文件夹保护的方法:一是通过设置文件系统权限,阻止普通用户访问;二是使用加密技术,对文件夹中的文件进行加密,防止未授权访问。提供了示例代码和使用方法,适用于不同安全需求的场景。
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
39 2
|
2月前
|
API C#
C# 一分钟浅谈:文件系统编程
在软件开发中,文件系统操作至关重要。本文将带你快速掌握C#中文件系统编程的基础知识,涵盖基本概念、常见问题及解决方法。文章详细介绍了`System.IO`命名空间下的关键类库,并通过示例代码展示了路径处理、异常处理、并发访问等技巧,还提供了异步API和流压缩等高级技巧,帮助你写出更健壮的代码。
37 2
|
2月前
|
SQL 开发框架 安全
并发集合与任务并行库:C#中的高效编程实践
在现代软件开发中,多核处理器普及使多线程编程成为提升性能的关键。然而,传统同步模型在高并发下易引发死锁等问题。为此,.NET Framework引入了任务并行库(TPL)和并发集合,简化并发编程并增强代码可维护性。并发集合允许多线程安全访问,如`ConcurrentQueue&lt;T&gt;`和`ConcurrentDictionary&lt;TKey, TValue&gt;`,有效避免数据不一致。TPL则通过`Task`类实现异步操作,提高开发效率。正确使用这些工具可显著提升程序性能,但也需注意任务取消和异常处理等常见问题。
45 1
|
2月前
|
安全 程序员 编译器
C#一分钟浅谈:泛型编程基础
在现代软件开发中,泛型编程是一项关键技能,它使开发者能够编写类型安全且可重用的代码。C# 自 2.0 版本起支持泛型编程,本文将从基础概念入手,逐步深入探讨 C# 中的泛型,并通过具体实例帮助理解常见问题及其解决方法。泛型通过类型参数替代具体类型,提高了代码复用性和类型安全性,减少了运行时性能开销。文章详细介绍了如何定义泛型类和方法,并讨论了常见的易错点及解决方案,帮助读者更好地掌握这一技术。
61 11
|
2月前
|
开发者 Python
基于Python的日志管理与最佳实践
日志是开发和调试过程中的重要工具,然而,如何高效地管理和利用日志常常被忽略。本文通过Python中的logging模块,探讨如何使用日志来进行调试、分析与问题排查,并提出了一些实际应用中的优化建议和最佳实践。
|
2月前
|
安全 数据库连接 API
C#一分钟浅谈:多线程编程入门
在现代软件开发中,多线程编程对于提升程序响应性和执行效率至关重要。本文从基础概念入手,详细探讨了C#中的多线程技术,包括线程创建、管理及常见问题的解决策略,如线程安全、死锁和资源泄露等,并通过具体示例帮助读者理解和应用这些技巧,适合初学者快速掌握C#多线程编程。
74 0
|
21天前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
139 3
|
22天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1585 14