ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

原生实现.NET5.0+ 自定义日志

2022-06-28 17:36:17  阅读:133  来源: 互联网

标签:string 自定义 NET5.0 template var 日志 configuration public


一、定义一个静态类 声明一个 ReaderWriterLockSlim 对象 用于并发控制

 1     /// <summary>
 2     /// IO锁
 3     /// </summary>
 4     public static class Lock
 5     {
 6 
 7         /// <summary>
 8         /// 文件读写锁
 9         /// </summary>
10         public static readonly ReaderWriterLockSlim _fileLockSlim = null;
11 
12         /// <summary>
13         /// 构造方法
14         /// </summary>
15         static Lock()
16         {
17             _fileLockSlim = new ReaderWriterLockSlim();
18         }
19     }

二、实现ILoggerProvider 接口

 1     /// <summary>
 2     /// 文件记录器提供商
 3     /// </summary>
 4     public class FileLoggerProvider : ILoggerProvider
 5     {
 6 
 7         /// <summary>
 8         /// 配置
 9         /// </summary>
10         private readonly IConfiguration _configuration;
11 
12         /// <summary>
13         /// 日志对象缓存
14         /// </summary>
15         private readonly ConcurrentDictionary<string, FileLogger> _loggers = new ConcurrentDictionary<string, FileLogger>();
16 
17         /// <summary>
18         /// 构造方法
19         /// </summary>
20         /// <param name="configuration">配置</param>
21         public FileLoggerProvider(IConfiguration configuration)
22         {
23             _configuration = configuration;
24         }
25 
26         /// <summary>
27         /// 创建记录器
28         /// </summary>
29         /// <param name="categoryName">类别名称</param>
30         /// <returns></returns>
31         public ILogger CreateLogger(string categoryName)
32         {
33             return _loggers.GetOrAdd(categoryName, k =>
34             {
35                 return new FileLogger(_configuration, k);
36             });
37         }
38 
39         /// <summary>
40         /// 释放方法
41         /// </summary>
42         public void Dispose()
43         {
44             _loggers.Clear();
45             GC.SuppressFinalize(this);
46         }
47     }

三、实现 ILogger 接口

  1 /// <summary>
  2     /// 文件记录器
  3     /// </summary>
  4     public class FileLogger : ILogger
  5     {
  6 
  7         /// <summary>
  8         /// 配置
  9         /// </summary>
 10         private readonly IConfiguration _configuration;
 11 
 12         /// <summary>
 13         /// 类别名称
 14         /// </summary>
 15         private readonly string _categoryName;
 16 
 17         /// <summary>
 18         /// 构造方法
 19         /// </summary>
 20         /// <param name="configuration">配置</param>
 21         /// <param name="categoryName">类别名称</param>
 22         public FileLogger(IConfiguration configuration, string categoryName)
 23         {
 24             _configuration = configuration;
 25             _categoryName = categoryName;
 26         }
 27 
 28         /// <summary>
 29         /// 开始范围
 30         /// </summary>
 31         /// <typeparam name="TState">状态类型</typeparam>
 32         /// <param name="state">状态</param>
 33         /// <returns></returns>
 34         public IDisposable BeginScope<TState>(TState state)
 35         {
 36             return null;
 37         }
 38 
 39         /// <summary>
 40         /// 是否使用
 41         /// </summary>
 42         /// <param name="logLevel">日志级别</param>
 43         /// <returns></returns>
 44         public bool IsEnabled(LogLevel logLevel)
 45         {
 46             var list = new List<IConfigurationSection>();
 47             list.AddRange(_configuration.GetSection("Logging:LogLevel").GetChildren());
 48             list.AddRange(_configuration.GetSection("Logging:FileLog:LogLevel").GetChildren());
 49 
 50             var category = list.LastOrDefault(f => _categoryName.StartsWith(f.Key));
 51 
 52             if (category == null)
 53             {
 54                 category = list.LastOrDefault(f => f.Key == "Default");
 55             }
 56 
 57             if (category != null && Enum.TryParse(typeof(LogLevel), category.Value, out var level))
 58             {
 59                 return (int)(LogLevel)level <= (int)logLevel;
 60             }
 61             return 2 <= (int)logLevel;
 62         }
 63 
 64         /// <summary>
 65         /// 日志
 66         /// </summary>
 67         /// <typeparam name="TState">状态类型</typeparam>
 68         /// <param name="logLevel">日志级别</param>
 69         /// <param name="eventId">事件ID</param>
 70         /// <param name="state">状态</param>
 71         /// <param name="exception">异常</param>
 72         /// <param name="formatter">格式化委托</param>
 73         public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
 74         {
 75             if (IsEnabled(logLevel))
 76             {
 77                 try
 78                 {
 79                     Lock._fileLockSlim.EnterWriteLock();
 80                     var baseDirectory = _configuration.GetSection("Logging:FileLog:BaseDirectory").Value;
 81                     var fileName = _configuration.GetSection("Logging:FileLog:FileName").Value;
 82                     var extensionName = _configuration.GetSection("Logging:FileLog:ExtensionName").Value;
 83 
 84                     var directory = Path.Combine(AppContext.BaseDirectory, string.IsNullOrWhiteSpace(baseDirectory) ? "app_log" : baseDirectory);
 85 
 86                     directory = Path.Combine(directory, logLevel.ToString());//拼接子目录
 87 
 88                     if (!Directory.Exists(directory))
 89                     {
 90                         Directory.CreateDirectory(directory);
 91                     }
 92                     if (string.IsNullOrWhiteSpace(fileName))
 93                     {
 94                         fileName = DateTime.Now.ToString("yyyy-MM-dd");
 95                     }
 96                     else
 97                     {
 98                         fileName = DateTime.Now.ToString(fileName);
 99                     }
100                     extensionName = string.IsNullOrWhiteSpace(extensionName) ? ".log" : extensionName;
101 
102                     var path = Path.Combine(directory, $"{fileName}{extensionName}");
103                     var flag = true;
104                     if (File.Exists(path))
105                     {
106                         var maxSize = _configuration.GetSection("Logging:FileLog:MaxFileSize").Value;
107                         var fileInfo = new FileInfo(path);
108                         flag = fileInfo.Length / 1024.00 > (string.IsNullOrWhiteSpace(maxSize) ? 2048.00 : Convert.ToDouble(maxSize));
109                     }
110 
111                     var streamWrite = flag ? File.CreateText(path) : File.AppendText(path);
112                     var dateTimeFormart = _configuration.GetSection("Logging:FileLog:DateTimeFormat").Value;
113 
114                     var logTime = DateTime.Now.ToString((string.IsNullOrWhiteSpace(dateTimeFormart) ? "yyyy-MM-dd HH:mm:ss.fff" : dateTimeFormart));
115                     var message = formatter(state, exception);
116 
117                     var stackTrace = exception?.StackTrace;
118 
119                     var template = _configuration.GetSection("Logging:FileLog:Template").Value;
120 
121                     if (string.IsNullOrWhiteSpace(template))
122                     {
123                         streamWrite.WriteLine($"日志时间:{logTime}  类别名称:{_categoryName}[{eventId.Id}]  日志级别:{logLevel}  消息:{message}");
124 
125                         if (!string.IsNullOrWhiteSpace(stackTrace))
126                         {
127                             streamWrite.WriteLine(stackTrace);
128                         }
129                     }
130                     else
131                     {
132                         template = template.Replace("{logTime}", logTime, StringComparison.OrdinalIgnoreCase);
133                         template = template.Replace("{catetoryName}", _categoryName, StringComparison.OrdinalIgnoreCase);
134                         template = template.Replace("{eventId}", eventId.Id.ToString(), StringComparison.OrdinalIgnoreCase);
135                         template = template.Replace("{eventName}", eventId.Name, StringComparison.OrdinalIgnoreCase);
136                         template = template.Replace("{logLevel}", logLevel.ToString(), StringComparison.OrdinalIgnoreCase);
137                         template = template.Replace("{message}", message, StringComparison.OrdinalIgnoreCase);
138                         template = template.Replace("{stackTrace}", stackTrace, StringComparison.OrdinalIgnoreCase);
139                         template = template.Trim();
140                         streamWrite.WriteLine(template);
141                     }
142 
143                     streamWrite.WriteLine();
144                     streamWrite.Close();
145 
146                     var directoryInfo = new DirectoryInfo(directory);
147                     var fileInfos = directoryInfo.GetFiles();
148                     var fileCount = Convert.ToInt32(_configuration.GetSection("Logging:FileLog:MaxFileCount").Value);
149                     if (fileInfos.Length > fileCount && fileCount > 0)
150                     {
151                         var removeFileInfo = fileInfos.OrderBy(o => o.CreationTime).ThenBy(o => o.LastWriteTime).SkipLast(fileCount);
152                         foreach (var item in removeFileInfo)
153                         {
154                             File.Delete(item.FullName);
155                         }
156                     }
157                 }
158                 catch (Exception ex)
159                 {
160                     Console.WriteLine($"写入文件日志异常:{ex.Message}");
161                     Console.WriteLine(ex.StackTrace);
162                 }
163                 finally
164                 {
165                     Lock._fileLockSlim.ExitWriteLock();
166                 }
167             }
168         }
169     }

四、创建一个静态类增加一个扩展方法 注册服务 

 1 /// <summary>
 2     /// 日志生成器扩展类
 3     /// </summary>
 4     public static class ILoggingBuilderExtensions
 5     {
 6 
 7         /// <summary>
 8         /// 添加文件日志
 9         /// </summary>
10         /// <param name="loggingBuilder">日志构建</param>
11         public static ILoggingBuilder AddFileLog(this ILoggingBuilder loggingBuilder)
12         {
13             loggingBuilder.Services.AddSingleton<FileLoggerProvider>();
14             var sevices = loggingBuilder.Services.BuildServiceProvider();
15             return loggingBuilder.AddProvider(sevices.GetService<FileLoggerProvider>());
16         }
17 
18     }

五、使用方式 .NET6.0为例

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddFileLog();//添加文件日志

 

标签:string,自定义,NET5.0,template,var,日志,configuration,public
来源: https://www.cnblogs.com/China-Mr-zhong/p/16420357.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有