实现目标:将log4net的相关操作封装成一个 .Net Standard类库

demo地址:https://github.com/PuzzledAlien/log4net_demo/tree/master/DotNetCoreConsole_V2

Step 1 建立解决方案和处理项目相关配置

在当前解决方案下新建项目,选择 .Net Standard类库,命名“MyLogManager”

.Net Core 实践 - 使用log4net记录日志(2)-LMLPHP

nuget引用log4net,添加log4net.config配置,右键点击log4net.config,选择“属性”,修改log4net.config文件属性

刚添加的log4net.config文件属性可能如下图所示(生成操作为无,不复制到输出目录)

.Net Core 实践 - 使用log4net记录日志(2)-LMLPHP

需要修改成如下所示(生成操作 无 改为 内容复制到输出目录 - 选择 如果较新则复制

.Net Core 实践 - 使用log4net记录日志(2)-LMLPHP

.Net Core 实践 - 使用log4net记录日志(2)-LMLPHP

重新生成解决方案后,在生成目录中就能看到log4net.config文件

Step 2 上代码

思路:两个StartLogger方法,在程序启动时启动该方法,一个方法自己配置处理,一个走默认

代码如下

    public class MyLogManager
{
private static ILoggerRepository _loggerRepository; /// <summary>
/// 启动logger
/// </summary>
/// <param name="repository">repository名称</param>
/// <param name="fileName">配置文件名称</param>
public static void StartLogger(string repository, string fileName)
{
_loggerRepository = LogManager.CreateRepository(repository);
XmlConfigurator.ConfigureAndWatch(_loggerRepository, new FileInfo(fileName));
} /// <summary>
/// 启动logger
/// </summary>
public static void StartLogger()
{
_loggerRepository = LogManager.CreateRepository(nameof(MyLogManager));
XmlConfigurator.ConfigureAndWatch(_loggerRepository, new FileInfo("log4net.config"));
} public static ILog GetMyLog<T>(T t)
{
return LogManager.GetLogger(_loggerRepository.Name, t.GetType());
} public static ILog GetMyLog(object obj)
{
return LogManager.GetLogger(_loggerRepository.Name, obj.GetType());
} public static ILog GetMyLog(Type type)
{
return LogManager.GetLogger(_loggerRepository.Name, type);
}
}

封装之后,调用代码会比第一版本的稍微精简

        static void TestV1()
{
MyLogManager.MyLogManager.StartLogger("DotNetCoreConsole_V2", "log4net.config"); var log = MyLogManager.MyLogManager.GetMyLog(typeof(Program)); const int numberOfCycles = 20000; var sw = Stopwatch.StartNew();
for (var i = 0; i < numberOfCycles; i++)
{
log.InfoFormat("testNum: {0} ", i);
}
sw.Stop(); Console.WriteLine();
Console.WriteLine("Ellapsed: {0}, numPerSec: {1}", sw.ElapsedMilliseconds, numberOfCycles / (sw.ElapsedMilliseconds / (double)1000));
Console.ReadKey();
}

代码重构和优化

思考:可不可以去掉StartLogger这行代码呢?可以。

实现如下

    public class NullLogManager
{
private static ILoggerRepository _loggerRepository; private static ILoggerRepository LoggerRepository
{
get
{
if (_loggerRepository != null)
{
return _loggerRepository;
}
_loggerRepository = LogManager.CreateRepository(nameof(NullLogManager));
XmlConfigurator.ConfigureAndWatch(_loggerRepository, new FileInfo("log4net.config"));
return _loggerRepository;
}
} public static ILog GetMyLog<T>(T t)
{
return LogManager.GetLogger(LoggerRepository.Name, t.GetType());
} public static ILog GetMyLog(object obj)
{
return LogManager.GetLogger(LoggerRepository.Name, obj.GetType());
} public static ILog GetMyLog(Type type)
{
return LogManager.GetLogger(LoggerRepository.Name, type);
} public static ILog GetMyLog()
{
return LogManager.GetLogger(LoggerRepository.Name, nameof(GetMyLog));
}
}

调用代码可再次精简

        static void TestNullLogManager()
{
var log = MyLogManager.NullLogManager.GetMyLog(typeof(Program)); const int numberOfCycles = 20000; var sw = Stopwatch.StartNew();
for (var i = 0; i < numberOfCycles; i++)
{
log.InfoFormat("testNum: {0} ", i);
}
sw.Stop(); Console.WriteLine();
Console.WriteLine("Ellapsed: {0}, numPerSec: {1}", sw.ElapsedMilliseconds, numberOfCycles / (sw.ElapsedMilliseconds / (double)1000));
Console.ReadKey();
}
05-02 22:02