当前位置:网站首页>Native implementation Net 5.0+ custom log

Native implementation Net 5.0+ custom log

2022-06-28 21:29:00 China-Mr-zhong

One 、 Define a static class Make a statement  ReaderWriterLockSlim object For concurrency control

 1     /// <summary>
 2     /// IO lock 
 3     /// </summary>
 4     public static class Lock
 5     {
 6 
 7         /// <summary>
 8         ///  File read / write lock 
 9         /// </summary>
10         public static readonly ReaderWriterLockSlim _fileLockSlim = null;
11 
12         /// <summary>
13         ///  Construction method 
14         /// </summary>
15         static Lock()
16         {
17             _fileLockSlim = new ReaderWriterLockSlim();
18         }
19     }

Two 、 Realization ILoggerProvider Interface

 1     /// <summary>
 2     ///  Document recorder provider 
 3     /// </summary>
 4     public class FileLoggerProvider : ILoggerProvider
 5     {
 6 
 7         /// <summary>
 8         ///  To configure 
 9         /// </summary>
10         private readonly IConfiguration _configuration;
11 
12         /// <summary>
13         ///  Log object cache 
14         /// </summary>
15         private readonly ConcurrentDictionary<string, FileLogger> _loggers = new ConcurrentDictionary<string, FileLogger>();
16 
17         /// <summary>
18         ///  Construction method 
19         /// </summary>
20         /// <param name="configuration"> To configure </param>
21         public FileLoggerProvider(IConfiguration configuration)
22         {
23             _configuration = configuration;
24         }
25 
26         /// <summary>
27         ///  Create a recorder 
28         /// </summary>
29         /// <param name="categoryName"> Category name </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         ///  Release method 
41         /// </summary>
42         public void Dispose()
43         {
44             _loggers.Clear();
45             GC.SuppressFinalize(this);
46         }
47     }

3、 ... and 、 Realization ILogger Interface

  1 /// <summary>
  2     ///  File recorder 
  3     /// </summary>
  4     public class FileLogger : ILogger
  5     {
  6 
  7         /// <summary>
  8         ///  To configure 
  9         /// </summary>
 10         private readonly IConfiguration _configuration;
 11 
 12         /// <summary>
 13         ///  Category name 
 14         /// </summary>
 15         private readonly string _categoryName;
 16 
 17         /// <summary>
 18         ///  Construction method 
 19         /// </summary>
 20         /// <param name="configuration"> To configure </param>
 21         /// <param name="categoryName"> Category name </param>
 22         public FileLogger(IConfiguration configuration, string categoryName)
 23         {
 24             _configuration = configuration;
 25             _categoryName = categoryName;
 26         }
 27 
 28         /// <summary>
 29         ///  Starting range 
 30         /// </summary>
 31         /// <typeparam name="TState"> State type </typeparam>
 32         /// <param name="state"> state </param>
 33         /// <returns></returns>
 34         public IDisposable BeginScope<TState>(TState state)
 35         {
 36             return null;
 37         }
 38 
 39         /// <summary>
 40         ///  Whether to use 
 41         /// </summary>
 42         /// <param name="logLevel"> The level of logging </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         ///  journal 
 66         /// </summary>
 67         /// <typeparam name="TState"> State type </typeparam>
 68         /// <param name="logLevel"> The level of logging </param>
 69         /// <param name="eventId"> event ID</param>
 70         /// <param name="state"> state </param>
 71         /// <param name="exception"> abnormal </param>
 72         /// <param name="formatter"> Format delegate </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());// Splice subdirectories 
 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($" Log time :{logTime}   Category name :{_categoryName}[{eventId.Id}]   The level of logging :{logLevel}   news :{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($" Exception writing file log :{ex.Message}");
161                     Console.WriteLine(ex.StackTrace);
162                 }
163                 finally
164                 {
165                     Lock._fileLockSlim.ExitWriteLock();
166                 }
167             }
168         }
169     }

Four 、 Create a static class and add an extension method Registration service  

 1 /// <summary>
 2     ///  Log generator extension class 
 3     /// </summary>
 4     public static class ILoggingBuilderExtensions
 5     {
 6 
 7         /// <summary>
 8         ///  Add file log 
 9         /// </summary>
10         /// <param name="loggingBuilder"> Log construction </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     }

5、 ... and 、 Usage mode .NET6.0 For example

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddFileLog();// Add file log 

  6、 ... and 、json File configuration format Native format   As always, I like the native implementation of Microsoft

"Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
    },
    "FileLog": {
      "LogLevel": {
        "Default": "Information"
      },
      "BaseDirectory": "app_log",
      "FileName": "yyyy-MM-dd",
      "ExtensionName": ".log",
      "Template": "LogTime:{LogTime}  CatetoryName:{CatetoryName}  LogLevel:{LogLevel}\r\n{Message}\r\n{StackTrace}\r\n",
      "MaxFileCount": 10,
      "MaxFileSize": 2048,
      "DateTimeFormat": "yyyy-MM-dd HH:mm:ss.fff"
    }
  }

 

原网站

版权声明
本文为[China-Mr-zhong]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/179/202206281751550168.html