zhaolei
2020-11-20 921de2254ff5712a44ed8575ee8efe34252f6603
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#if !NET45
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
#endif
using System;
 
namespace Prow.Logging
{
    /// <summary>
    /// 日志文件操作类,内部使用单件模式,所以只能记录在一个文件中
    /// </summary>
#if !NET45
    [ProviderAlias("LgbFile")]
#endif
    public sealed class FileLoggerProvider : LoggerProvider
    {
#if !NET45
        private IDisposable? _optionsReloadToken;
        private readonly IConfiguration? _config;
#endif
        private FileLoggerOptions _options;
        private readonly FileLoggerWriter _logWriter;
        /// <summary>
        /// 默认构造函数
        /// </summary>
        /// <param name="options">IFileLoggerOptions 实例</param>
        /// <param name="filter">日志过滤回调函数</param>
        public FileLoggerProvider(FileLoggerOptions options, Func<string, LogLevel, bool>? filter = null) : base(null, filter)
        {
            _options = options;
            _logWriter = new FileLoggerWriter(_options);
            LogCallback = _logWriter.WriteMessage;
        }
 
#if !NET45
        /// <summary>
        /// 通过注入方式监听配置文件初始化 FileProvider,此构造函数被 IoC 调用
        /// </summary>
        /// <param name="options"></param>
        /// <param name="configuration"></param>
        public FileLoggerProvider(IOptionsMonitor<FileLoggerOptions> options, IConfiguration configuration) : this(options.CurrentValue)
        {
            _config = configuration;
            _optionsReloadToken = options.OnChange(ReloadLoggerOptions);
        }
 
        private void ReloadLoggerOptions(FileLoggerOptions op)
        {
            _options = op;
            _logWriter.Option = op;
        }
 
        private IExternalScopeProvider? scopeProvider;
 
        private IExternalScopeProvider? GetScopeProvider()
        {
            if (_options.IncludeScopes && scopeProvider == null)
            {
                scopeProvider = new LoggerExternalScopeProvider();
            }
            return scopeProvider;
        }
 
        /// <summary>
        ///创建 ILogger 实例方法
        /// </summary>
        /// <param name="categoryName">分类名称</param>
        /// <returns>ILogger 实例</returns>
        public override ILogger CreateLogger(string categoryName) => new Logger(categoryName, LogCallback, Filter, GetScopeProvider(), _config);
#else
        /// <summary>
        /// 创建 ILogger 实例方法
        /// </summary>
        /// <param name="categoryName">分类名称</param>
        /// <returns>ILogger 实例</returns>
        public override ILogger CreateLogger(string categoryName) => new Logger(categoryName, LogCallback, Filter, _options.IncludeScopes);
#endif
 
        /// <summary>
        /// 强制输出日志到文件中
        /// </summary>
        public void Flush() => _logWriter.Flush();
 
        private bool disposedValue; // To detect redundant calls
 
        /// <summary>
        /// Dispose 方法
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
#if !NET45
                    _optionsReloadToken?.Dispose();
#endif
                    _logWriter.Dispose();
                }
                disposedValue = true;
            }
        }
    }
}